19b94acceSBarry Smith 2af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/ 307475bc1SBarry Smith #include <petscdmshell.h> 4d96771aaSLisandro Dalcin #include <petscdraw.h> 5a01aa210SMatthew G. Knepley #include <petscds.h> 69b94acceSBarry Smith 7ace3abfcSBarry Smith PetscBool SNESRegisterAllCalled = PETSC_FALSE; 80298fd71SBarry Smith PetscFunctionList SNESList = NULL; 98ba1e511SMatthew Knepley 108ba1e511SMatthew Knepley /* Logging support */ 1122c6f798SBarry Smith PetscClassId SNES_CLASSID, DMSNES_CLASSID; 1294db00ebSBarry Smith PetscLogEvent SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_NGSEval, SNES_NGSFuncEval, SNES_NPCSolve, SNES_ObjectiveEval; 13a09944afSBarry Smith 14e113a28aSBarry Smith /*@ 15e113a28aSBarry Smith SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 16e113a28aSBarry Smith 173f9fe445SBarry Smith Logically Collective on SNES 18e113a28aSBarry Smith 19e113a28aSBarry Smith Input Parameters: 20e113a28aSBarry Smith + snes - iterative context obtained from SNESCreate() 21e113a28aSBarry Smith - flg - PETSC_TRUE indicates you want the error generated 22e113a28aSBarry Smith 23e113a28aSBarry Smith Options database keys: 24e113a28aSBarry Smith . -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false) 25e113a28aSBarry Smith 26e113a28aSBarry Smith Level: intermediate 27e113a28aSBarry Smith 28e113a28aSBarry Smith Notes: 29e113a28aSBarry Smith Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 30e113a28aSBarry Smith to determine if it has converged. 31e113a28aSBarry Smith 32e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 33e113a28aSBarry Smith 34e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 35e113a28aSBarry Smith @*/ 367087cfbeSBarry Smith PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 37e113a28aSBarry Smith { 38e113a28aSBarry Smith PetscFunctionBegin; 39e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 40acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flg,2); 41e113a28aSBarry Smith snes->errorifnotconverged = flg; 42e113a28aSBarry Smith PetscFunctionReturn(0); 43e113a28aSBarry Smith } 44e113a28aSBarry Smith 45e113a28aSBarry Smith /*@ 46e113a28aSBarry Smith SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 47e113a28aSBarry Smith 48e113a28aSBarry Smith Not Collective 49e113a28aSBarry Smith 50e113a28aSBarry Smith Input Parameter: 51e113a28aSBarry Smith . snes - iterative context obtained from SNESCreate() 52e113a28aSBarry Smith 53e113a28aSBarry Smith Output Parameter: 54e113a28aSBarry Smith . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 55e113a28aSBarry Smith 56e113a28aSBarry Smith Level: intermediate 57e113a28aSBarry Smith 58e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 59e113a28aSBarry Smith 60e113a28aSBarry Smith .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 61e113a28aSBarry Smith @*/ 627087cfbeSBarry Smith PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 63e113a28aSBarry Smith { 64e113a28aSBarry Smith PetscFunctionBegin; 65e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 66e113a28aSBarry Smith PetscValidPointer(flag,2); 67e113a28aSBarry Smith *flag = snes->errorifnotconverged; 68e113a28aSBarry Smith PetscFunctionReturn(0); 69e113a28aSBarry Smith } 70e113a28aSBarry Smith 714fc747eaSLawrence Mitchell /*@ 724fc747eaSLawrence Mitchell SNESSetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution? 734fc747eaSLawrence Mitchell 744fc747eaSLawrence Mitchell Logically Collective on SNES 754fc747eaSLawrence Mitchell 764fc747eaSLawrence Mitchell Input Parameters: 774fc747eaSLawrence Mitchell + snes - the shell SNES 784fc747eaSLawrence Mitchell - flg - is the residual computed? 794fc747eaSLawrence Mitchell 804fc747eaSLawrence Mitchell Level: advanced 814fc747eaSLawrence Mitchell 824fc747eaSLawrence Mitchell .seealso: SNESGetAlwaysComputesFinalResidual() 834fc747eaSLawrence Mitchell @*/ 844fc747eaSLawrence Mitchell PetscErrorCode SNESSetAlwaysComputesFinalResidual(SNES snes, PetscBool flg) 854fc747eaSLawrence Mitchell { 864fc747eaSLawrence Mitchell PetscFunctionBegin; 874fc747eaSLawrence Mitchell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 884fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = flg; 894fc747eaSLawrence Mitchell PetscFunctionReturn(0); 904fc747eaSLawrence Mitchell } 914fc747eaSLawrence Mitchell 924fc747eaSLawrence Mitchell /*@ 934fc747eaSLawrence Mitchell SNESGetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution? 944fc747eaSLawrence Mitchell 954fc747eaSLawrence Mitchell Logically Collective on SNES 964fc747eaSLawrence Mitchell 974fc747eaSLawrence Mitchell Input Parameter: 984fc747eaSLawrence Mitchell . snes - the shell SNES 994fc747eaSLawrence Mitchell 1004fc747eaSLawrence Mitchell Output Parameter: 1014fc747eaSLawrence Mitchell . flg - is the residual computed? 1024fc747eaSLawrence Mitchell 1034fc747eaSLawrence Mitchell Level: advanced 1044fc747eaSLawrence Mitchell 1054fc747eaSLawrence Mitchell .seealso: SNESSetAlwaysComputesFinalResidual() 1064fc747eaSLawrence Mitchell @*/ 1074fc747eaSLawrence Mitchell PetscErrorCode SNESGetAlwaysComputesFinalResidual(SNES snes, PetscBool *flg) 1084fc747eaSLawrence Mitchell { 1094fc747eaSLawrence Mitchell PetscFunctionBegin; 1104fc747eaSLawrence Mitchell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1114fc747eaSLawrence Mitchell *flg = snes->alwayscomputesfinalresidual; 1124fc747eaSLawrence Mitchell PetscFunctionReturn(0); 1134fc747eaSLawrence Mitchell } 1144fc747eaSLawrence Mitchell 115e725d27bSBarry Smith /*@ 116bf388a1fSBarry Smith SNESSetFunctionDomainError - tells SNES that the input vector to your SNESFunction is not 1174936397dSBarry Smith in the functions domain. For example, negative pressure. 1184936397dSBarry Smith 1193f9fe445SBarry Smith Logically Collective on SNES 1204936397dSBarry Smith 1214936397dSBarry Smith Input Parameters: 1226a388c36SPeter Brune . snes - the SNES context 1234936397dSBarry Smith 12428529972SSatish Balay Level: advanced 1254936397dSBarry Smith 1264936397dSBarry Smith .keywords: SNES, view 1274936397dSBarry Smith 128bf388a1fSBarry Smith .seealso: SNESCreate(), SNESSetFunction(), SNESFunction 1294936397dSBarry Smith @*/ 1307087cfbeSBarry Smith PetscErrorCode SNESSetFunctionDomainError(SNES snes) 1314936397dSBarry Smith { 1324936397dSBarry Smith PetscFunctionBegin; 1330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 134422a814eSBarry Smith if (snes->errorifnotconverged) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"User code indicates input vector is not in the function domain"); 1354936397dSBarry Smith snes->domainerror = PETSC_TRUE; 1364936397dSBarry Smith PetscFunctionReturn(0); 1374936397dSBarry Smith } 1384936397dSBarry Smith 1396a388c36SPeter Brune /*@ 140c77b2880SPeter Brune SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction; 1416a388c36SPeter Brune 1426a388c36SPeter Brune Logically Collective on SNES 1436a388c36SPeter Brune 1446a388c36SPeter Brune Input Parameters: 1456a388c36SPeter Brune . snes - the SNES context 1466a388c36SPeter Brune 1476a388c36SPeter Brune Output Parameters: 148bf388a1fSBarry Smith . domainerror - Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise. 1496a388c36SPeter Brune 1506a388c36SPeter Brune Level: advanced 1516a388c36SPeter Brune 1526a388c36SPeter Brune .keywords: SNES, view 1536a388c36SPeter Brune 154bf388a1fSBarry Smith .seealso: SNESSetFunctionDomainError(), SNESComputeFunction() 1556a388c36SPeter Brune @*/ 1566a388c36SPeter Brune PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 1576a388c36SPeter Brune { 1586a388c36SPeter Brune PetscFunctionBegin; 1596a388c36SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1606a388c36SPeter Brune PetscValidPointer(domainerror, 2); 1616a388c36SPeter Brune *domainerror = snes->domainerror; 1626a388c36SPeter Brune PetscFunctionReturn(0); 1636a388c36SPeter Brune } 1646a388c36SPeter Brune 16555849f57SBarry Smith /*@C 16655849f57SBarry Smith SNESLoad - Loads a SNES that has been stored in binary with SNESView(). 16755849f57SBarry Smith 16855849f57SBarry Smith Collective on PetscViewer 16955849f57SBarry Smith 17055849f57SBarry Smith Input Parameters: 17155849f57SBarry Smith + newdm - the newly loaded SNES, this needs to have been created with SNESCreate() or 17255849f57SBarry Smith some related function before a call to SNESLoad(). 17355849f57SBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() 17455849f57SBarry Smith 17555849f57SBarry Smith Level: intermediate 17655849f57SBarry Smith 17755849f57SBarry Smith Notes: 17855849f57SBarry Smith The type is determined by the data in the file, any type set into the SNES before this call is ignored. 17955849f57SBarry Smith 18055849f57SBarry Smith Notes for advanced users: 18155849f57SBarry Smith Most users should not need to know the details of the binary storage 18255849f57SBarry Smith format, since SNESLoad() and TSView() completely hide these details. 18355849f57SBarry Smith But for anyone who's interested, the standard binary matrix storage 18455849f57SBarry Smith format is 18555849f57SBarry Smith .vb 18655849f57SBarry Smith has not yet been determined 18755849f57SBarry Smith .ve 18855849f57SBarry Smith 18955849f57SBarry Smith .seealso: PetscViewerBinaryOpen(), SNESView(), MatLoad(), VecLoad() 19055849f57SBarry Smith @*/ 1912d53ad75SBarry Smith PetscErrorCode SNESLoad(SNES snes, PetscViewer viewer) 19255849f57SBarry Smith { 19355849f57SBarry Smith PetscErrorCode ierr; 19455849f57SBarry Smith PetscBool isbinary; 195060da220SMatthew G. Knepley PetscInt classid; 19655849f57SBarry Smith char type[256]; 19755849f57SBarry Smith KSP ksp; 1982d53ad75SBarry Smith DM dm; 1992d53ad75SBarry Smith DMSNES dmsnes; 20055849f57SBarry Smith 20155849f57SBarry Smith PetscFunctionBegin; 2022d53ad75SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20355849f57SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 20455849f57SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 20555849f57SBarry Smith if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 20655849f57SBarry Smith 207060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr); 208ce94432eSBarry Smith if (classid != SNES_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Not SNES next in file"); 209060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr); 2102d53ad75SBarry Smith ierr = SNESSetType(snes, type);CHKERRQ(ierr); 2112d53ad75SBarry Smith if (snes->ops->load) { 2122d53ad75SBarry Smith ierr = (*snes->ops->load)(snes,viewer);CHKERRQ(ierr); 213f2c2a1b9SBarry Smith } 2142d53ad75SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2152d53ad75SBarry Smith ierr = DMGetDMSNES(dm,&dmsnes);CHKERRQ(ierr); 2162d53ad75SBarry Smith ierr = DMSNESLoad(dmsnes,viewer);CHKERRQ(ierr); 2172d53ad75SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 21855849f57SBarry Smith ierr = KSPLoad(ksp,viewer);CHKERRQ(ierr); 21955849f57SBarry Smith PetscFunctionReturn(0); 22055849f57SBarry Smith } 2216a388c36SPeter Brune 2229804daf3SBarry Smith #include <petscdraw.h> 223e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 224e04113cfSBarry Smith #include <petscviewersaws.h> 225bfb97211SBarry Smith #endif 2267e2c5f70SBarry Smith /*@C 2279b94acceSBarry Smith SNESView - Prints the SNES data structure. 2289b94acceSBarry Smith 2294c49b128SBarry Smith Collective on SNES 230fee21e36SBarry Smith 231c7afd0dbSLois Curfman McInnes Input Parameters: 232c7afd0dbSLois Curfman McInnes + SNES - the SNES context 233c7afd0dbSLois Curfman McInnes - viewer - visualization context 234c7afd0dbSLois Curfman McInnes 2359b94acceSBarry Smith Options Database Key: 236c8a8ba5cSLois Curfman McInnes . -snes_view - Calls SNESView() at end of SNESSolve() 2379b94acceSBarry Smith 2389b94acceSBarry Smith Notes: 2399b94acceSBarry Smith The available visualization contexts include 240b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 241b0a32e0cSBarry Smith - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 242c8a8ba5cSLois Curfman McInnes output where only the first processor opens 243c8a8ba5cSLois Curfman McInnes the file. All other processors send their 244c8a8ba5cSLois Curfman McInnes data to the first processor to print. 2459b94acceSBarry Smith 2463e081fefSLois Curfman McInnes The user can open an alternative visualization context with 247b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 2489b94acceSBarry Smith 24936851e7fSLois Curfman McInnes Level: beginner 25036851e7fSLois Curfman McInnes 2519b94acceSBarry Smith .keywords: SNES, view 2529b94acceSBarry Smith 253b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen() 2549b94acceSBarry Smith @*/ 2557087cfbeSBarry Smith PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 2569b94acceSBarry Smith { 257fa9f3622SBarry Smith SNESKSPEW *kctx; 258dfbe8321SBarry Smith PetscErrorCode ierr; 25994b7f48cSBarry Smith KSP ksp; 2607f1410a3SPeter Brune SNESLineSearch linesearch; 26172a02f06SBarry Smith PetscBool iascii,isstring,isbinary,isdraw; 2622d53ad75SBarry Smith DMSNES dmsnes; 263e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 264536b137fSBarry Smith PetscBool issaws; 265bfb97211SBarry Smith #endif 2669b94acceSBarry Smith 2673a40ed3dSBarry Smith PetscFunctionBegin; 2680700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2693050cee2SBarry Smith if (!viewer) { 270ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer);CHKERRQ(ierr); 2713050cee2SBarry Smith } 2720700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 273c9780b6fSBarry Smith PetscCheckSameComm(snes,1,viewer,2); 27474679c65SBarry Smith 275251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 276251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 27755849f57SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 27872a02f06SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 279e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 280536b137fSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 281bfb97211SBarry Smith #endif 28232077d6dSBarry Smith if (iascii) { 283dc0571f2SMatthew G. Knepley SNESNormSchedule normschedule; 284dc0571f2SMatthew G. Knepley 285dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer);CHKERRQ(ierr); 286fce1e034SJed Brown if (!snes->setupcalled) { 287fce1e034SJed Brown ierr = PetscViewerASCIIPrintf(viewer," SNES has not been set up so information may be incomplete\n");CHKERRQ(ierr); 288fce1e034SJed Brown } 289e7788613SBarry Smith if (snes->ops->view) { 290b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 291e7788613SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 292b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2930ef38995SBarry Smith } 29477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 29557622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%g, absolute=%g, solution=%g\n",(double)snes->rtol,(double)snes->abstol,(double)snes->stol);CHKERRQ(ierr); 29677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 29777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 298dc0571f2SMatthew G. Knepley ierr = SNESGetNormSchedule(snes, &normschedule);CHKERRQ(ierr); 299dc0571f2SMatthew G. Knepley if (normschedule > 0) {ierr = PetscViewerASCIIPrintf(viewer," norm schedule %s\n",SNESNormSchedules[normschedule]);CHKERRQ(ierr);} 30017fe4bdfSPeter Brune if (snes->gridsequence) { 30117fe4bdfSPeter Brune ierr = PetscViewerASCIIPrintf(viewer," total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr); 30217fe4bdfSPeter Brune } 3039b94acceSBarry Smith if (snes->ksp_ewconv) { 304fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3059b94acceSBarry Smith if (kctx) { 30677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 30757622a8eSBarry 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); 30857622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," gamma=%g, alpha=%g, alpha2=%g\n",(double)kctx->gamma,(double)kctx->alpha,(double)kctx->alpha2);CHKERRQ(ierr); 3099b94acceSBarry Smith } 3109b94acceSBarry Smith } 311eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 312eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 313eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 314eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 315eb1f6c34SBarry Smith } 316eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 317eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 318eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 31942f4f86dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 320eb1f6c34SBarry Smith } 3210f5bd95cSBarry Smith } else if (isstring) { 322317d6ea6SBarry Smith const char *type; 323454a90a3SBarry Smith ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 324b0a32e0cSBarry Smith ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 32555849f57SBarry Smith } else if (isbinary) { 32655849f57SBarry Smith PetscInt classid = SNES_FILE_CLASSID; 32755849f57SBarry Smith MPI_Comm comm; 32855849f57SBarry Smith PetscMPIInt rank; 32955849f57SBarry Smith char type[256]; 33055849f57SBarry Smith 33155849f57SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 33255849f57SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 33355849f57SBarry Smith if (!rank) { 33455849f57SBarry Smith ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 33589d949e2SBarry Smith ierr = PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type));CHKERRQ(ierr); 33689d949e2SBarry Smith ierr = PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 33755849f57SBarry Smith } 33855849f57SBarry Smith if (snes->ops->view) { 33955849f57SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 34055849f57SBarry Smith } 34172a02f06SBarry Smith } else if (isdraw) { 34272a02f06SBarry Smith PetscDraw draw; 34372a02f06SBarry Smith char str[36]; 34489fd9fafSBarry Smith PetscReal x,y,bottom,h; 34572a02f06SBarry Smith 34672a02f06SBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 34772a02f06SBarry Smith ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr); 34872a02f06SBarry Smith ierr = PetscStrcpy(str,"SNES: ");CHKERRQ(ierr); 34972a02f06SBarry Smith ierr = PetscStrcat(str,((PetscObject)snes)->type_name);CHKERRQ(ierr); 35051fa3d41SBarry Smith ierr = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr); 35189fd9fafSBarry Smith bottom = y - h; 35272a02f06SBarry Smith ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr); 353c4646bacSPeter Brune if (snes->ops->view) { 354c4646bacSPeter Brune ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 355c4646bacSPeter Brune } 356e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 357536b137fSBarry Smith } else if (issaws) { 358d45a07a7SBarry Smith PetscMPIInt rank; 3592657e9d9SBarry Smith const char *name; 360d45a07a7SBarry Smith 3612657e9d9SBarry Smith ierr = PetscObjectGetName((PetscObject)snes,&name);CHKERRQ(ierr); 362d45a07a7SBarry Smith ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 363d45a07a7SBarry Smith if (!((PetscObject)snes)->amsmem && !rank) { 364d45a07a7SBarry Smith char dir[1024]; 365d45a07a7SBarry Smith 366e04113cfSBarry Smith ierr = PetscObjectViewSAWs((PetscObject)snes,viewer);CHKERRQ(ierr); 3672657e9d9SBarry Smith ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name);CHKERRQ(ierr); 3682657e9d9SBarry Smith PetscStackCallSAWs(SAWs_Register,(dir,&snes->iter,1,SAWs_READ,SAWs_INT)); 369bfb97211SBarry Smith if (!snes->conv_hist) { 370a0931e03SBarry Smith ierr = SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE);CHKERRQ(ierr); 371bfb97211SBarry Smith } 3722657e9d9SBarry Smith ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/conv_hist",name);CHKERRQ(ierr); 3732657e9d9SBarry Smith PetscStackCallSAWs(SAWs_Register,(dir,snes->conv_hist,10,SAWs_READ,SAWs_DOUBLE)); 374f05ece33SBarry Smith } 375bfb97211SBarry Smith #endif 37672a02f06SBarry Smith } 37772a02f06SBarry Smith if (snes->linesearch) { 37872a02f06SBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 3797601faf0SJed Brown ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr); 38072a02f06SBarry Smith ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr); 38172a02f06SBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 38219bcc07fSBarry Smith } 38342f4f86dSBarry Smith if (snes->pc && snes->usespc) { 3844a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 3854a0c5b0cSMatthew G Knepley ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr); 3864a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 3874a0c5b0cSMatthew G Knepley } 3882d53ad75SBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 3892d53ad75SBarry Smith ierr = DMGetDMSNES(snes->dm,&dmsnes);CHKERRQ(ierr); 3902d53ad75SBarry Smith ierr = DMSNESView(dmsnes, viewer);CHKERRQ(ierr); 3912d53ad75SBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 3922c155ee1SBarry Smith if (snes->usesksp) { 3932c155ee1SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 394b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 39594b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 396b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 3972c155ee1SBarry Smith } 39872a02f06SBarry Smith if (isdraw) { 39972a02f06SBarry Smith PetscDraw draw; 40072a02f06SBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 40172a02f06SBarry Smith ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr); 4027f1410a3SPeter Brune } 4033a40ed3dSBarry Smith PetscFunctionReturn(0); 4049b94acceSBarry Smith } 4059b94acceSBarry Smith 40676b2cf59SMatthew Knepley /* 40776b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 40876b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 40976b2cf59SMatthew Knepley */ 41076b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 411a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 4126849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 41376b2cf59SMatthew Knepley 414ac226902SBarry Smith /*@C 41576b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 41676b2cf59SMatthew Knepley 41776b2cf59SMatthew Knepley Not Collective 41876b2cf59SMatthew Knepley 41976b2cf59SMatthew Knepley Input Parameter: 42076b2cf59SMatthew Knepley . snescheck - function that checks for options 42176b2cf59SMatthew Knepley 42276b2cf59SMatthew Knepley Level: developer 42376b2cf59SMatthew Knepley 42476b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 42576b2cf59SMatthew Knepley @*/ 4267087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 42776b2cf59SMatthew Knepley { 42876b2cf59SMatthew Knepley PetscFunctionBegin; 429f23aa3ddSBarry Smith if (numberofsetfromoptions >= MAXSETFROMOPTIONS) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 43076b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 43176b2cf59SMatthew Knepley PetscFunctionReturn(0); 43276b2cf59SMatthew Knepley } 43376b2cf59SMatthew Knepley 4347087cfbeSBarry Smith extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 435aa3661deSLisandro Dalcin 436ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 437aa3661deSLisandro Dalcin { 438aa3661deSLisandro Dalcin Mat J; 439aa3661deSLisandro Dalcin KSP ksp; 440aa3661deSLisandro Dalcin PC pc; 441ace3abfcSBarry Smith PetscBool match; 442aa3661deSLisandro Dalcin PetscErrorCode ierr; 443895c21f2SBarry Smith MatNullSpace nullsp; 444aa3661deSLisandro Dalcin 445aa3661deSLisandro Dalcin PetscFunctionBegin; 4460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 447aa3661deSLisandro Dalcin 44898613b67SLisandro Dalcin if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 44998613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 4502a7a6963SBarry Smith ierr = MatCreateVecs(A ? A : B, NULL,&snes->vec_func);CHKERRQ(ierr); 45198613b67SLisandro Dalcin } 45298613b67SLisandro Dalcin 453aa3661deSLisandro Dalcin if (version == 1) { 454aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 45598613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4569c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 457aa3661deSLisandro Dalcin } else if (version == 2) { 458e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 459570b7f6dSBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16) 460aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 461aa3661deSLisandro Dalcin #else 462e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 463aa3661deSLisandro Dalcin #endif 464a8248277SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 465aa3661deSLisandro Dalcin 466895c21f2SBarry Smith /* attach any user provided null space that was on Amat to the newly created matrix free matrix */ 467895c21f2SBarry Smith if (snes->jacobian) { 468895c21f2SBarry Smith ierr = MatGetNullSpace(snes->jacobian,&nullsp);CHKERRQ(ierr); 469895c21f2SBarry Smith if (nullsp) { 470895c21f2SBarry Smith ierr = MatSetNullSpace(J,nullsp);CHKERRQ(ierr); 471895c21f2SBarry Smith } 472895c21f2SBarry Smith } 473895c21f2SBarry Smith 474aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 475d3462f78SMatthew Knepley if (hasOperator) { 4763232da50SPeter Brune 477aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 478aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 479aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 480aa3661deSLisandro Dalcin } else { 481aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 4823232da50SPeter Brune provided preconditioner Jacobian with the default matrix free version. */ 483172a4300SPeter Brune if ((snes->pcside == PC_LEFT) && snes->pc) { 484d728fb7dSPeter Brune if (!snes->jacobian){ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);} 485172a4300SPeter Brune } else { 48628a52e04SBarry Smith ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,0);CHKERRQ(ierr); 487172a4300SPeter Brune } 488aa3661deSLisandro Dalcin /* Force no preconditioner */ 489aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 490aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 491251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 492aa3661deSLisandro Dalcin if (!match) { 493aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 494aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 495aa3661deSLisandro Dalcin } 496aa3661deSLisandro Dalcin } 4976bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 498aa3661deSLisandro Dalcin PetscFunctionReturn(0); 499aa3661deSLisandro Dalcin } 500aa3661deSLisandro Dalcin 501dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx) 502dfe15315SJed Brown { 503dfe15315SJed Brown SNES snes = (SNES)ctx; 504dfe15315SJed Brown PetscErrorCode ierr; 5050298fd71SBarry Smith Vec Xfine,Xfine_named = NULL,Xcoarse; 506dfe15315SJed Brown 507dfe15315SJed Brown PetscFunctionBegin; 50816ebb321SJed Brown if (PetscLogPrintInfo) { 50916ebb321SJed Brown PetscInt finelevel,coarselevel,fineclevel,coarseclevel; 51016ebb321SJed Brown ierr = DMGetRefineLevel(dmfine,&finelevel);CHKERRQ(ierr); 51116ebb321SJed Brown ierr = DMGetCoarsenLevel(dmfine,&fineclevel);CHKERRQ(ierr); 51216ebb321SJed Brown ierr = DMGetRefineLevel(dmcoarse,&coarselevel);CHKERRQ(ierr); 51316ebb321SJed Brown ierr = DMGetCoarsenLevel(dmcoarse,&coarseclevel);CHKERRQ(ierr); 51416ebb321SJed Brown ierr = PetscInfo4(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel);CHKERRQ(ierr); 51516ebb321SJed Brown } 516dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 517dfe15315SJed Brown else { 518dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr); 519dfe15315SJed Brown Xfine = Xfine_named; 520dfe15315SJed Brown } 521dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 522907f5c5aSLawrence Mitchell if (Inject) { 523907f5c5aSLawrence Mitchell ierr = MatRestrict(Inject,Xfine,Xcoarse);CHKERRQ(ierr); 524907f5c5aSLawrence Mitchell } else { 525dfe15315SJed Brown ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr); 526dfe15315SJed Brown ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr); 527907f5c5aSLawrence Mitchell } 528dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 529dfe15315SJed Brown if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);} 530dfe15315SJed Brown PetscFunctionReturn(0); 531dfe15315SJed Brown } 532dfe15315SJed Brown 53316ebb321SJed Brown static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx) 53416ebb321SJed Brown { 53516ebb321SJed Brown PetscErrorCode ierr; 53616ebb321SJed Brown 53716ebb321SJed Brown PetscFunctionBegin; 53816ebb321SJed Brown ierr = DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);CHKERRQ(ierr); 53916ebb321SJed Brown PetscFunctionReturn(0); 54016ebb321SJed Brown } 54116ebb321SJed Brown 542a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 543a6950cb2SJed Brown * safely call SNESGetDM() in their residual evaluation routine. */ 54423ee1639SBarry Smith static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx) 545caa4e7f2SJed Brown { 546caa4e7f2SJed Brown SNES snes = (SNES)ctx; 547caa4e7f2SJed Brown PetscErrorCode ierr; 548caa4e7f2SJed Brown Mat Asave = A,Bsave = B; 5490298fd71SBarry Smith Vec X,Xnamed = NULL; 550dfe15315SJed Brown DM dmsave; 5514e269d77SPeter Brune void *ctxsave; 552d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 553caa4e7f2SJed Brown 554caa4e7f2SJed Brown PetscFunctionBegin; 555dfe15315SJed Brown dmsave = snes->dm; 556dfe15315SJed Brown ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr); 557dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 558dfe15315SJed Brown else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ 559dfe15315SJed Brown ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 560dfe15315SJed Brown X = Xnamed; 5610298fd71SBarry Smith ierr = SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave);CHKERRQ(ierr); 5624e269d77SPeter Brune /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */ 5638d359177SBarry Smith if (jac == SNESComputeJacobianDefaultColor) { 5648d359177SBarry Smith ierr = SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr); 565dfe15315SJed Brown } 5664e269d77SPeter Brune } 5674e269d77SPeter Brune /* put the previous context back */ 5684e269d77SPeter Brune 569d1e9a80fSBarry Smith ierr = SNESComputeJacobian(snes,X,A,B);CHKERRQ(ierr); 5708d359177SBarry Smith if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) { 5710298fd71SBarry Smith ierr = SNESSetJacobian(snes,NULL,NULL,jac,ctxsave);CHKERRQ(ierr); 5724e269d77SPeter Brune } 5734e269d77SPeter Brune 574ce94432eSBarry Smith if (A != Asave || B != Bsave) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"No support for changing matrices at this time"); 575dfe15315SJed Brown if (Xnamed) { 576dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 577dfe15315SJed Brown } 578dfe15315SJed Brown snes->dm = dmsave; 579caa4e7f2SJed Brown PetscFunctionReturn(0); 580caa4e7f2SJed Brown } 581caa4e7f2SJed Brown 5826cab3a1bSJed Brown /*@ 5836cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 5846cab3a1bSJed Brown 5856cab3a1bSJed Brown Collective 5866cab3a1bSJed Brown 5876cab3a1bSJed Brown Input Arguments: 5886cab3a1bSJed Brown . snes - snes to configure 5896cab3a1bSJed Brown 5906cab3a1bSJed Brown Level: developer 5916cab3a1bSJed Brown 5926cab3a1bSJed Brown .seealso: SNESSetUp() 5936cab3a1bSJed Brown @*/ 5946cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 5956cab3a1bSJed Brown { 5966cab3a1bSJed Brown PetscErrorCode ierr; 5976cab3a1bSJed Brown DM dm; 598942e3340SBarry Smith DMSNES sdm; 5996cab3a1bSJed Brown 6006cab3a1bSJed Brown PetscFunctionBegin; 6016cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 602942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 603ce94432eSBarry Smith if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"DMSNES not properly configured"); 604f5af7f23SKarl Rupp else if (!snes->jacobian && snes->mf) { 6056cab3a1bSJed Brown Mat J; 6066cab3a1bSJed Brown void *functx; 6076cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 6086cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 6096cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 6100298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 6113232da50SPeter Brune ierr = SNESSetJacobian(snes,J,J,0,0);CHKERRQ(ierr); 6126cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 613caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 6146cab3a1bSJed Brown Mat J,B; 6156cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 6166cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 6176cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 618b412c318SBarry Smith ierr = DMCreateMatrix(snes->dm,&B);CHKERRQ(ierr); 61906f20277SJed Brown /* sdm->computejacobian was already set to reach here */ 6200298fd71SBarry Smith ierr = SNESSetJacobian(snes,J,B,NULL,NULL);CHKERRQ(ierr); 6216cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 6226cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 623caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 6241ba9b98eSMatthew G. Knepley PetscDS prob; 6256cab3a1bSJed Brown Mat J, B; 6261ba9b98eSMatthew G. Knepley PetscBool hasPrec = PETSC_FALSE; 6271ba9b98eSMatthew G. Knepley 6286cab3a1bSJed Brown J = snes->jacobian; 6291ba9b98eSMatthew G. Knepley ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 6301ba9b98eSMatthew G. Knepley if (prob) {ierr = PetscDSHasJacobianPreconditioner(prob, &hasPrec);CHKERRQ(ierr);} 631ec9a985fSMatthew G. Knepley if (J) {ierr = PetscObjectReference((PetscObject) J);CHKERRQ(ierr);} 632ec9a985fSMatthew G. Knepley else if (hasPrec) {ierr = DMCreateMatrix(snes->dm, &J);CHKERRQ(ierr);} 633b412c318SBarry Smith ierr = DMCreateMatrix(snes->dm, &B);CHKERRQ(ierr); 6340298fd71SBarry Smith ierr = SNESSetJacobian(snes, J ? J : B, B, NULL, NULL);CHKERRQ(ierr); 6351ba9b98eSMatthew G. Knepley ierr = MatDestroy(&J);CHKERRQ(ierr); 6366cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 6376cab3a1bSJed Brown } 638caa4e7f2SJed Brown { 639caa4e7f2SJed Brown KSP ksp; 640caa4e7f2SJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 641caa4e7f2SJed Brown ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr); 64216ebb321SJed Brown ierr = DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 643caa4e7f2SJed Brown } 6446cab3a1bSJed Brown PetscFunctionReturn(0); 6456cab3a1bSJed Brown } 6466cab3a1bSJed Brown 647fde5950dSBarry Smith /*@C 648fde5950dSBarry Smith SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 649fde5950dSBarry Smith 650fde5950dSBarry Smith Collective on SNES 651fde5950dSBarry Smith 652fde5950dSBarry Smith Input Parameters: 653fde5950dSBarry Smith + snes - SNES object you wish to monitor 654fde5950dSBarry Smith . name - the monitor type one is seeking 655fde5950dSBarry Smith . help - message indicating what monitoring is done 656fde5950dSBarry Smith . manual - manual page for the monitor 657fde5950dSBarry Smith . monitor - the monitor function 658fde5950dSBarry Smith - monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the SNES or PetscViewer objects 659fde5950dSBarry Smith 660fde5950dSBarry Smith Level: developer 661fde5950dSBarry Smith 662fde5950dSBarry Smith .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 663fde5950dSBarry Smith PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 664fde5950dSBarry Smith PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 665fde5950dSBarry Smith PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 666fde5950dSBarry Smith PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 667fde5950dSBarry Smith PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 668fde5950dSBarry Smith PetscOptionsFList(), PetscOptionsEList() 669fde5950dSBarry Smith @*/ 670d43b4f6eSBarry Smith PetscErrorCode SNESMonitorSetFromOptions(SNES snes,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNES,PetscViewerAndFormat*)) 671fde5950dSBarry Smith { 672fde5950dSBarry Smith PetscErrorCode ierr; 673fde5950dSBarry Smith PetscViewer viewer; 674fde5950dSBarry Smith PetscViewerFormat format; 675fde5950dSBarry Smith PetscBool flg; 676fde5950dSBarry Smith 677fde5950dSBarry Smith PetscFunctionBegin; 678fde5950dSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr); 679fde5950dSBarry Smith if (flg) { 680d43b4f6eSBarry Smith PetscViewerAndFormat *vf; 681d43b4f6eSBarry Smith ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr); 682d43b4f6eSBarry Smith ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr); 683fde5950dSBarry Smith if (monitorsetup) { 684d43b4f6eSBarry Smith ierr = (*monitorsetup)(snes,vf);CHKERRQ(ierr); 685fde5950dSBarry Smith } 686d43b4f6eSBarry Smith ierr = SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr); 687fde5950dSBarry Smith } 688fde5950dSBarry Smith PetscFunctionReturn(0); 689fde5950dSBarry Smith } 690fde5950dSBarry Smith 6919b94acceSBarry Smith /*@ 69294b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 6939b94acceSBarry Smith 694c7afd0dbSLois Curfman McInnes Collective on SNES 695c7afd0dbSLois Curfman McInnes 6969b94acceSBarry Smith Input Parameter: 6979b94acceSBarry Smith . snes - the SNES context 6989b94acceSBarry Smith 69936851e7fSLois Curfman McInnes Options Database Keys: 700722329fbSBarry Smith + -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list 70182738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 70282738288SBarry Smith of the change in the solution between steps 70370441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 704b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 705e4d06f11SPatrick Farrell . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 706b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 707b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 7084839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 709ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 710a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 711e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 712b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 7132492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 71482738288SBarry Smith solver; hence iterations will continue until max_it 7151fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 71682738288SBarry Smith of convergence test 717fde5950dSBarry Smith . -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout 718fde5950dSBarry Smith . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 719fde5950dSBarry Smith . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 720fde5950dSBarry Smith . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 7214619e776SBarry Smith . -snes_monitor_lg_residualnorm - plots residual norm at each iteration 722459f5d12SBarry Smith . -snes_monitor_lg_range - plots residual norm at each iteration 723e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 724e2e60de9SPeter Brune . -snes_fd_color - use finite differences with coloring to compute Jacobian 7255968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 726fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 72782738288SBarry Smith 72882738288SBarry Smith Options Database for Eisenstat-Walker method: 729fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 7304b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 73136851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 73236851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 73336851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 73436851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 73536851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 73636851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 73782738288SBarry Smith 73811ca99fdSLois Curfman McInnes Notes: 73911ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 740a7f22e61SSatish Balay Users-Manual: ch_snes 74183e2fdc7SBarry Smith 74236851e7fSLois Curfman McInnes Level: beginner 74336851e7fSLois Curfman McInnes 7449b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 7459b94acceSBarry Smith 74669ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 7479b94acceSBarry Smith @*/ 7487087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 7499b94acceSBarry Smith { 7508afaa268SBarry Smith PetscBool flg,pcset,persist,set; 751d8f46077SPeter Brune PetscInt i,indx,lag,grids; 75204d7464bSBarry Smith const char *deft = SNESNEWTONLS; 75385385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 75485385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 755e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 75685385478SLisandro Dalcin PetscErrorCode ierr; 757c40d0f55SPeter Brune PCSide pcside; 758a64e098fSPeter Brune const char *optionsprefix; 7599b94acceSBarry Smith 7603a40ed3dSBarry Smith PetscFunctionBegin; 7610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7620f51fdf8SToby Isaac ierr = SNESRegisterAll();CHKERRQ(ierr); 7633194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 764639ff905SBarry Smith if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name; 765a264d7a6SBarry Smith ierr = PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 766d64ed03dSBarry Smith if (flg) { 767186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 7687adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 769186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 770d64ed03dSBarry Smith } 77194ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL);CHKERRQ(ierr); 77294ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL);CHKERRQ(ierr); 773186905e3SBarry Smith 77494ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL);CHKERRQ(ierr); 775e4d06f11SPatrick Farrell ierr = PetscOptionsReal("-snes_divergence_tolerance","Stop if residual norm increases by this factor","SNESSetDivergenceTolerance",snes->divtol,&snes->divtol,NULL);CHKERRQ(ierr); 7760298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL);CHKERRQ(ierr); 7770298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL);CHKERRQ(ierr); 7780298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL);CHKERRQ(ierr); 7790298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL);CHKERRQ(ierr); 7800298fd71SBarry Smith ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL);CHKERRQ(ierr); 78185385478SLisandro Dalcin 782a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 783a8054027SBarry Smith if (flg) { 784a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 785a8054027SBarry Smith } 78637ec4e1aSPeter Brune ierr = PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr); 78737ec4e1aSPeter Brune if (flg) { 78837ec4e1aSPeter Brune ierr = SNESSetLagPreconditionerPersists(snes,persist);CHKERRQ(ierr); 78937ec4e1aSPeter Brune } 790e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 791e35cf81dSBarry Smith if (flg) { 792e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 793e35cf81dSBarry Smith } 79437ec4e1aSPeter Brune ierr = PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr); 79537ec4e1aSPeter Brune if (flg) { 79637ec4e1aSPeter Brune ierr = SNESSetLagJacobianPersists(snes,persist);CHKERRQ(ierr); 79737ec4e1aSPeter Brune } 79837ec4e1aSPeter Brune 799efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 800efd51863SBarry Smith if (flg) { 801efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 802efd51863SBarry Smith } 803a8054027SBarry Smith 80485385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 80585385478SLisandro Dalcin if (flg) { 80685385478SLisandro Dalcin switch (indx) { 8078d359177SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL);CHKERRQ(ierr); break; 808e2a6519dSDmitry Karpeev case 1: ierr = SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL);CHKERRQ(ierr); break; 80985385478SLisandro Dalcin } 81085385478SLisandro Dalcin } 81185385478SLisandro Dalcin 812365a6726SPeter Brune ierr = PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg);CHKERRQ(ierr); 813365a6726SPeter Brune if (flg) { ierr = SNESSetNormSchedule(snes,(SNESNormSchedule)indx);CHKERRQ(ierr); } 814fdacfa88SPeter Brune 81547073ea2SPeter Brune ierr = PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg);CHKERRQ(ierr); 81647073ea2SPeter Brune if (flg) { ierr = SNESSetFunctionType(snes,(SNESFunctionType)indx);CHKERRQ(ierr); } 817186905e3SBarry Smith 81885385478SLisandro Dalcin kctx = (SNESKSPEW*)snes->kspconvctx; 81985385478SLisandro Dalcin 8200298fd71SBarry Smith ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL);CHKERRQ(ierr); 821186905e3SBarry Smith 82294ae4db5SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL);CHKERRQ(ierr); 82394ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL);CHKERRQ(ierr); 82494ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL);CHKERRQ(ierr); 82594ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL);CHKERRQ(ierr); 82694ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL);CHKERRQ(ierr); 82794ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL);CHKERRQ(ierr); 82894ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL);CHKERRQ(ierr); 829186905e3SBarry Smith 83090d69ab7SBarry Smith flg = PETSC_FALSE; 8318afaa268SBarry Smith ierr = PetscOptionsBool("-snes_check_jacobian","Check each Jacobian with a differenced one","SNESUpdateCheckJacobian",flg,&flg,&set);CHKERRQ(ierr); 8328afaa268SBarry Smith if (set && flg) { 8335341784dSBarry Smith ierr = SNESSetUpdate(snes,SNESUpdateCheckJacobian);CHKERRQ(ierr); 8345341784dSBarry Smith } 8355341784dSBarry Smith 8365341784dSBarry Smith flg = PETSC_FALSE; 8378afaa268SBarry Smith ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set);CHKERRQ(ierr); 8388afaa268SBarry Smith if (set && flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 839eabae89aSBarry Smith 840fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,NULL);CHKERRQ(ierr); 841fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_short","Monitor norm of function with fewer digits","SNESMonitorDefaultShort",SNESMonitorDefaultShort,NULL);CHKERRQ(ierr); 842fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_range","Monitor range of elements of function","SNESMonitorRange",SNESMonitorRange,NULL);CHKERRQ(ierr); 843eabae89aSBarry Smith 844fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_ratio","Monitor ratios of the norm of function for consecutive steps","SNESMonitorRatio",SNESMonitorRatio,SNESMonitorRatioSetUp);CHKERRQ(ierr); 845fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorDefaultField",SNESMonitorDefaultField,NULL);CHKERRQ(ierr); 846fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution","View solution at each iteration","SNESMonitorSolution",SNESMonitorSolution,NULL);CHKERRQ(ierr); 847fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution_update","View correction at each iteration","SNESMonitorSolutionUpdate",SNESMonitorSolutionUpdate,NULL);CHKERRQ(ierr); 848fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_residual","View residual at each iteration","SNESMonitorResidual",SNESMonitorResidual,NULL);CHKERRQ(ierr); 849fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",SNESMonitorJacUpdateSpectrum,NULL);CHKERRQ(ierr); 850fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet",SNESMonitorFields,NULL);CHKERRQ(ierr); 8512db13446SMatthew G. Knepley 8525180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 8535180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 8545180491cSLisandro Dalcin 855fde5950dSBarry Smith 85690d69ab7SBarry Smith flg = PETSC_FALSE; 8570298fd71SBarry Smith ierr = PetscOptionsBool("-snes_monitor_lg_residualnorm","Plot function norm at each iteration","SNESMonitorLGResidualNorm",flg,&flg,NULL);CHKERRQ(ierr); 858459f5d12SBarry Smith if (flg) { 859d96771aaSLisandro Dalcin PetscDrawLG ctx; 860459f5d12SBarry Smith 8616ba87a44SLisandro Dalcin ierr = SNESMonitorLGCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr); 862d96771aaSLisandro Dalcin ierr = SNESMonitorSet(snes,SNESMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);CHKERRQ(ierr); 863459f5d12SBarry Smith } 86490d69ab7SBarry Smith flg = PETSC_FALSE; 8650298fd71SBarry Smith ierr = PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL);CHKERRQ(ierr); 866459f5d12SBarry Smith if (flg) { 867459f5d12SBarry Smith PetscViewer ctx; 868e24b481bSBarry Smith 8696ba87a44SLisandro Dalcin ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr); 870459f5d12SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 871459f5d12SBarry Smith } 8722e7541e6SPeter Brune 8732e7541e6SPeter Brune 874cc0c4584SMatthew G. Knepley 87590d69ab7SBarry Smith flg = PETSC_FALSE; 8768d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL);CHKERRQ(ierr); 8774b27c08aSLois Curfman McInnes if (flg) { 8786cab3a1bSJed Brown void *functx; 8790298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 8808d359177SBarry Smith ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx);CHKERRQ(ierr); 881ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 8829b94acceSBarry Smith } 883639f9d9dSBarry Smith 88444848bc4SPeter Brune flg = PETSC_FALSE; 8858d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL);CHKERRQ(ierr); 88697584545SPeter Brune if (flg) { 8878d359177SBarry Smith ierr = SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL);CHKERRQ(ierr); 88897584545SPeter Brune } 88997584545SPeter Brune 89097584545SPeter Brune flg = PETSC_FALSE; 8918d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL);CHKERRQ(ierr); 89244848bc4SPeter Brune if (flg) { 893c52e227fSPeter Brune DM dm; 894c52e227fSPeter Brune DMSNES sdm; 895c52e227fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 896aace71b7SPeter Brune ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 897aace71b7SPeter Brune sdm->jacobianctx = NULL; 8988d359177SBarry Smith ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr); 89944848bc4SPeter Brune ierr = PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr); 90044848bc4SPeter Brune } 90144848bc4SPeter Brune 902aa3661deSLisandro Dalcin flg = PETSC_FALSE; 903d8f46077SPeter 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); 904d8f46077SPeter Brune if (flg && snes->mf_operator) { 905a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 906d8f46077SPeter Brune snes->mf = PETSC_TRUE; 907a8248277SBarry Smith } 908aa3661deSLisandro Dalcin flg = PETSC_FALSE; 909d8f46077SPeter Brune ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&snes->mf,&flg);CHKERRQ(ierr); 910d8f46077SPeter Brune if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 911d8f46077SPeter Brune ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,0);CHKERRQ(ierr); 912d28543b3SPeter Brune 913c40d0f55SPeter Brune flg = PETSC_FALSE; 914be95d8f1SBarry Smith ierr = SNESGetNPCSide(snes,&pcside);CHKERRQ(ierr); 915be95d8f1SBarry Smith ierr = PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr); 916be95d8f1SBarry Smith if (flg) {ierr = SNESSetNPCSide(snes,pcside);CHKERRQ(ierr);} 917c40d0f55SPeter Brune 918e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 9198a70d858SHong Zhang /* 9208a70d858SHong Zhang Publish convergence information using SAWs 9218a70d858SHong Zhang */ 9228a70d858SHong Zhang flg = PETSC_FALSE; 9238a70d858SHong Zhang ierr = PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); 9248a70d858SHong Zhang if (flg) { 9258a70d858SHong Zhang void *ctx; 9268a70d858SHong Zhang ierr = SNESMonitorSAWsCreate(snes,&ctx);CHKERRQ(ierr); 9278a70d858SHong Zhang ierr = SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy);CHKERRQ(ierr); 9288a70d858SHong Zhang } 9298a70d858SHong Zhang #endif 9308a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS) 931b90c6cbeSBarry Smith { 932b90c6cbeSBarry Smith PetscBool set; 933b90c6cbeSBarry Smith flg = PETSC_FALSE; 9348a70d858SHong Zhang ierr = PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set);CHKERRQ(ierr); 935b90c6cbeSBarry Smith if (set) { 936e04113cfSBarry Smith ierr = PetscObjectSAWsSetBlock((PetscObject)snes,flg);CHKERRQ(ierr); 937b90c6cbeSBarry Smith } 938b90c6cbeSBarry Smith } 939b90c6cbeSBarry Smith #endif 940b90c6cbeSBarry Smith 94176b2cf59SMatthew Knepley for (i = 0; i < numberofsetfromoptions; i++) { 94276b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 94376b2cf59SMatthew Knepley } 94476b2cf59SMatthew Knepley 945e7788613SBarry Smith if (snes->ops->setfromoptions) { 946e55864a3SBarry Smith ierr = (*snes->ops->setfromoptions)(PetscOptionsObject,snes);CHKERRQ(ierr); 947639f9d9dSBarry Smith } 9485d973c19SBarry Smith 9495d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 9500633abcbSJed Brown ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)snes);CHKERRQ(ierr); 951b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 9524bbc92c1SBarry Smith 9539e764e56SPeter Brune if (!snes->linesearch) { 9547601faf0SJed Brown ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 9559e764e56SPeter Brune } 956f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 9579e764e56SPeter Brune 9586991f827SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 9596991f827SBarry Smith ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr); 9606991f827SBarry Smith ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 9616991f827SBarry Smith 962be95d8f1SBarry Smith /* if someone has set the SNES NPC type, create it. */ 96351e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 964c5929fdfSBarry Smith ierr = PetscOptionsHasName(((PetscObject)snes)->options,optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 96551e86f29SPeter Brune if (pcset && (!snes->pc)) { 966be95d8f1SBarry Smith ierr = SNESGetNPC(snes, &snes->pc);CHKERRQ(ierr); 96751e86f29SPeter Brune } 9683a40ed3dSBarry Smith PetscFunctionReturn(0); 9699b94acceSBarry Smith } 9709b94acceSBarry Smith 971bb9467b5SJed Brown /*@C 972d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 973d25893d9SBarry Smith the nonlinear solvers. 974d25893d9SBarry Smith 975d25893d9SBarry Smith Logically Collective on SNES 976d25893d9SBarry Smith 977d25893d9SBarry Smith Input Parameters: 978d25893d9SBarry Smith + snes - the SNES context 979d25893d9SBarry Smith . compute - function to compute the context 980d25893d9SBarry Smith - destroy - function to destroy the context 981d25893d9SBarry Smith 982d25893d9SBarry Smith Level: intermediate 983d25893d9SBarry Smith 984bb9467b5SJed Brown Notes: 985bb9467b5SJed Brown This function is currently not available from Fortran. 986bb9467b5SJed Brown 987d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 988d25893d9SBarry Smith 989d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 990d25893d9SBarry Smith @*/ 991d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 992d25893d9SBarry Smith { 993d25893d9SBarry Smith PetscFunctionBegin; 994d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 995d25893d9SBarry Smith snes->ops->usercompute = compute; 996d25893d9SBarry Smith snes->ops->userdestroy = destroy; 997d25893d9SBarry Smith PetscFunctionReturn(0); 998d25893d9SBarry Smith } 999a847f771SSatish Balay 1000b07ff414SBarry Smith /*@ 10019b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 10029b94acceSBarry Smith the nonlinear solvers. 10039b94acceSBarry Smith 10043f9fe445SBarry Smith Logically Collective on SNES 1005fee21e36SBarry Smith 1006c7afd0dbSLois Curfman McInnes Input Parameters: 1007c7afd0dbSLois Curfman McInnes + snes - the SNES context 1008c7afd0dbSLois Curfman McInnes - usrP - optional user context 1009c7afd0dbSLois Curfman McInnes 101036851e7fSLois Curfman McInnes Level: intermediate 101136851e7fSLois Curfman McInnes 1012daf670e6SBarry Smith Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this 1013daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1014daf670e6SBarry Smith 10159b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 10169b94acceSBarry Smith 1017ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext() 10189b94acceSBarry Smith @*/ 10197087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 10209b94acceSBarry Smith { 10211b2093e4SBarry Smith PetscErrorCode ierr; 1022b07ff414SBarry Smith KSP ksp; 10231b2093e4SBarry Smith 10243a40ed3dSBarry Smith PetscFunctionBegin; 10250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1026b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 1027b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 10289b94acceSBarry Smith snes->user = usrP; 10293a40ed3dSBarry Smith PetscFunctionReturn(0); 10309b94acceSBarry Smith } 103174679c65SBarry Smith 1032b07ff414SBarry Smith /*@ 10339b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 10349b94acceSBarry Smith nonlinear solvers. 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 . usrP - user context 10439b94acceSBarry Smith 1044daf670e6SBarry Smith Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this 1045daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1046daf670e6SBarry Smith 104736851e7fSLois Curfman McInnes Level: intermediate 104836851e7fSLois Curfman McInnes 10499b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 10509b94acceSBarry Smith 10519b94acceSBarry Smith .seealso: SNESSetApplicationContext() 10529b94acceSBarry Smith @*/ 1053e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 10549b94acceSBarry Smith { 10553a40ed3dSBarry Smith PetscFunctionBegin; 10560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1057e71120c6SJed Brown *(void**)usrP = snes->user; 10583a40ed3dSBarry Smith PetscFunctionReturn(0); 10599b94acceSBarry Smith } 106074679c65SBarry Smith 10619b94acceSBarry Smith /*@ 1062*3565c898SBarry Smith SNESSetUseMatrixFree - indicates that SNES should use matrix free finite difference matrix vector products internally to apply 1063*3565c898SBarry Smith the Jacobian. 1064*3565c898SBarry Smith 1065*3565c898SBarry Smith Collective on SNES 1066*3565c898SBarry Smith 1067*3565c898SBarry Smith Input Parameters: 1068*3565c898SBarry Smith + snes - SNES context 1069*3565c898SBarry Smith . mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored 1070*3565c898SBarry Smith - mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 1071*3565c898SBarry Smith 1072*3565c898SBarry Smith Options Database: 1073*3565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator 1074*3565c898SBarry Smith - -snes_mf_operator - use matrix free only for the mat operator 1075*3565c898SBarry Smith 1076*3565c898SBarry Smith Level: intermediate 1077*3565c898SBarry Smith 1078*3565c898SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 1079*3565c898SBarry Smith 1080*3565c898SBarry Smith .seealso: SNESGetUseMatrixFree(), MatCreateSNESMF() 1081*3565c898SBarry Smith @*/ 1082*3565c898SBarry Smith PetscErrorCode SNESSetUseMatrixFree(SNES snes,PetscBool mf_operator,PetscBool mf) 1083*3565c898SBarry Smith { 1084*3565c898SBarry Smith PetscFunctionBegin; 1085*3565c898SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1086*3565c898SBarry Smith if (mf && !mf_operator) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"If using mf must also use mf_operator"); 1087*3565c898SBarry Smith snes->mf = mf; 1088*3565c898SBarry Smith snes->mf_operator = mf_operator; 1089*3565c898SBarry Smith PetscFunctionReturn(0); 1090*3565c898SBarry Smith } 1091*3565c898SBarry Smith 1092*3565c898SBarry Smith /*@ 1093*3565c898SBarry Smith SNESGetUseMatrixFree - indicates if the SNES uses matrix free finite difference matrix vector products to apply 1094*3565c898SBarry Smith the Jacobian. 1095*3565c898SBarry Smith 1096*3565c898SBarry Smith Collective on SNES 1097*3565c898SBarry Smith 1098*3565c898SBarry Smith Input Parameter: 1099*3565c898SBarry Smith . snes - SNES context 1100*3565c898SBarry Smith 1101*3565c898SBarry Smith Output Parameters: 1102*3565c898SBarry Smith + mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored 1103*3565c898SBarry Smith - mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 1104*3565c898SBarry Smith 1105*3565c898SBarry Smith Options Database: 1106*3565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator 1107*3565c898SBarry Smith - -snes_mf_operator - use matrix free only for the mat operator 1108*3565c898SBarry Smith 1109*3565c898SBarry Smith Level: intermediate 1110*3565c898SBarry Smith 1111*3565c898SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 1112*3565c898SBarry Smith 1113*3565c898SBarry Smith .seealso: SNESSetUseMatrixFree(), MatCreateSNESMF() 1114*3565c898SBarry Smith @*/ 1115*3565c898SBarry Smith PetscErrorCode SNESGetUseMatrixFree(SNES snes,PetscBool *mf_operator,PetscBool *mf) 1116*3565c898SBarry Smith { 1117*3565c898SBarry Smith PetscFunctionBegin; 1118*3565c898SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1119*3565c898SBarry Smith if (mf) *mf = snes->mf; 1120*3565c898SBarry Smith if (mf_operator) *mf_operator = snes->mf_operator; 1121*3565c898SBarry Smith PetscFunctionReturn(0); 1122*3565c898SBarry Smith } 1123*3565c898SBarry Smith 1124*3565c898SBarry Smith /*@ 1125c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 1126c8228a4eSBarry Smith at this time. 11279b94acceSBarry Smith 1128c7afd0dbSLois Curfman McInnes Not Collective 1129c7afd0dbSLois Curfman McInnes 11309b94acceSBarry Smith Input Parameter: 11319b94acceSBarry Smith . snes - SNES context 11329b94acceSBarry Smith 11339b94acceSBarry Smith Output Parameter: 11349b94acceSBarry Smith . iter - iteration number 11359b94acceSBarry Smith 1136c8228a4eSBarry Smith Notes: 1137c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 1138c8228a4eSBarry Smith 1139c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 114008405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 114108405cd6SLois Curfman McInnes .vb 114208405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 114308405cd6SLois Curfman McInnes if (!(it % 2)) { 114408405cd6SLois Curfman McInnes [compute Jacobian here] 114508405cd6SLois Curfman McInnes } 114608405cd6SLois Curfman McInnes .ve 1147c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 114808405cd6SLois Curfman McInnes recomputed every second SNES iteration. 1149c8228a4eSBarry Smith 115036851e7fSLois Curfman McInnes Level: intermediate 115136851e7fSLois Curfman McInnes 11522b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 11532b668275SBarry Smith 115471dbe336SPeter Brune .seealso: SNESGetLinearSolveIterations() 11559b94acceSBarry Smith @*/ 11567087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt *iter) 11579b94acceSBarry Smith { 11583a40ed3dSBarry Smith PetscFunctionBegin; 11590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11604482741eSBarry Smith PetscValidIntPointer(iter,2); 11619b94acceSBarry Smith *iter = snes->iter; 11623a40ed3dSBarry Smith PetscFunctionReturn(0); 11639b94acceSBarry Smith } 116474679c65SBarry Smith 1165360c497dSPeter Brune /*@ 1166360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 1167360c497dSPeter Brune 1168360c497dSPeter Brune Not Collective 1169360c497dSPeter Brune 1170360c497dSPeter Brune Input Parameter: 1171360c497dSPeter Brune . snes - SNES context 1172360c497dSPeter Brune . iter - iteration number 1173360c497dSPeter Brune 1174360c497dSPeter Brune Level: developer 1175360c497dSPeter Brune 1176360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 1177360c497dSPeter Brune 117871dbe336SPeter Brune .seealso: SNESGetLinearSolveIterations() 1179360c497dSPeter Brune @*/ 1180360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 1181360c497dSPeter Brune { 1182360c497dSPeter Brune PetscErrorCode ierr; 1183360c497dSPeter Brune 1184360c497dSPeter Brune PetscFunctionBegin; 1185360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1186e04113cfSBarry Smith ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr); 1187360c497dSPeter Brune snes->iter = iter; 1188e04113cfSBarry Smith ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr); 1189360c497dSPeter Brune PetscFunctionReturn(0); 1190360c497dSPeter Brune } 1191360c497dSPeter Brune 11929b94acceSBarry Smith /*@ 1193b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 11949b94acceSBarry Smith attempted by the nonlinear solver. 11959b94acceSBarry Smith 1196c7afd0dbSLois Curfman McInnes Not Collective 1197c7afd0dbSLois Curfman McInnes 11989b94acceSBarry Smith Input Parameter: 11999b94acceSBarry Smith . snes - SNES context 12009b94acceSBarry Smith 12019b94acceSBarry Smith Output Parameter: 12029b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 12039b94acceSBarry Smith 1204c96a6f78SLois Curfman McInnes Notes: 1205c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1206c96a6f78SLois Curfman McInnes 120736851e7fSLois Curfman McInnes Level: intermediate 120836851e7fSLois Curfman McInnes 12099b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 121058ebbce7SBarry Smith 1211e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 121258ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 12139b94acceSBarry Smith @*/ 12147087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails) 12159b94acceSBarry Smith { 12163a40ed3dSBarry Smith PetscFunctionBegin; 12170700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12184482741eSBarry Smith PetscValidIntPointer(nfails,2); 121950ffb88aSMatthew Knepley *nfails = snes->numFailures; 122050ffb88aSMatthew Knepley PetscFunctionReturn(0); 122150ffb88aSMatthew Knepley } 122250ffb88aSMatthew Knepley 122350ffb88aSMatthew Knepley /*@ 1224b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 122550ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 122650ffb88aSMatthew Knepley 122750ffb88aSMatthew Knepley Not Collective 122850ffb88aSMatthew Knepley 122950ffb88aSMatthew Knepley Input Parameters: 123050ffb88aSMatthew Knepley + snes - SNES context 123150ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 123250ffb88aSMatthew Knepley 123350ffb88aSMatthew Knepley Level: intermediate 123450ffb88aSMatthew Knepley 123550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 123658ebbce7SBarry Smith 1237e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 123858ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 123950ffb88aSMatthew Knepley @*/ 12407087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 124150ffb88aSMatthew Knepley { 124250ffb88aSMatthew Knepley PetscFunctionBegin; 12430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 124450ffb88aSMatthew Knepley snes->maxFailures = maxFails; 124550ffb88aSMatthew Knepley PetscFunctionReturn(0); 124650ffb88aSMatthew Knepley } 124750ffb88aSMatthew Knepley 124850ffb88aSMatthew Knepley /*@ 1249b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 125050ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 125150ffb88aSMatthew Knepley 125250ffb88aSMatthew Knepley Not Collective 125350ffb88aSMatthew Knepley 125450ffb88aSMatthew Knepley Input Parameter: 125550ffb88aSMatthew Knepley . snes - SNES context 125650ffb88aSMatthew Knepley 125750ffb88aSMatthew Knepley Output Parameter: 125850ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 125950ffb88aSMatthew Knepley 126050ffb88aSMatthew Knepley Level: intermediate 126150ffb88aSMatthew Knepley 126250ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 126358ebbce7SBarry Smith 1264e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 126558ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 126658ebbce7SBarry Smith 126750ffb88aSMatthew Knepley @*/ 12687087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 126950ffb88aSMatthew Knepley { 127050ffb88aSMatthew Knepley PetscFunctionBegin; 12710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12724482741eSBarry Smith PetscValidIntPointer(maxFails,2); 127350ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 12743a40ed3dSBarry Smith PetscFunctionReturn(0); 12759b94acceSBarry Smith } 1276a847f771SSatish Balay 12772541af92SBarry Smith /*@ 12782541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 12792541af92SBarry Smith done by SNES. 12802541af92SBarry Smith 12812541af92SBarry Smith Not Collective 12822541af92SBarry Smith 12832541af92SBarry Smith Input Parameter: 12842541af92SBarry Smith . snes - SNES context 12852541af92SBarry Smith 12862541af92SBarry Smith Output Parameter: 12872541af92SBarry Smith . nfuncs - number of evaluations 12882541af92SBarry Smith 12892541af92SBarry Smith Level: intermediate 12902541af92SBarry Smith 1291971e163fSPeter Brune Notes: Reset every time SNESSolve is called unless SNESSetCountersReset() is used. 1292971e163fSPeter Brune 12932541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 129458ebbce7SBarry Smith 1295971e163fSPeter Brune .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), SNESSetCountersReset() 12962541af92SBarry Smith @*/ 12977087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 12982541af92SBarry Smith { 12992541af92SBarry Smith PetscFunctionBegin; 13000700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13012541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 13022541af92SBarry Smith *nfuncs = snes->nfuncs; 13032541af92SBarry Smith PetscFunctionReturn(0); 13042541af92SBarry Smith } 13052541af92SBarry Smith 13063d4c4710SBarry Smith /*@ 13073d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 13083d4c4710SBarry Smith linear solvers. 13093d4c4710SBarry Smith 13103d4c4710SBarry Smith Not Collective 13113d4c4710SBarry Smith 13123d4c4710SBarry Smith Input Parameter: 13133d4c4710SBarry Smith . snes - SNES context 13143d4c4710SBarry Smith 13153d4c4710SBarry Smith Output Parameter: 13163d4c4710SBarry Smith . nfails - number of failed solves 13173d4c4710SBarry Smith 13189d85da0cSMatthew G. Knepley Level: intermediate 13199d85da0cSMatthew G. Knepley 13209d85da0cSMatthew G. Knepley Options Database Keys: 13219d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 13229d85da0cSMatthew G. Knepley 13233d4c4710SBarry Smith Notes: 13243d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 13253d4c4710SBarry Smith 13263d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 132758ebbce7SBarry Smith 1328e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 13293d4c4710SBarry Smith @*/ 13307087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails) 13313d4c4710SBarry Smith { 13323d4c4710SBarry Smith PetscFunctionBegin; 13330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13343d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 13353d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 13363d4c4710SBarry Smith PetscFunctionReturn(0); 13373d4c4710SBarry Smith } 13383d4c4710SBarry Smith 13393d4c4710SBarry Smith /*@ 13403d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 13413d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 13423d4c4710SBarry Smith 13433f9fe445SBarry Smith Logically Collective on SNES 13443d4c4710SBarry Smith 13453d4c4710SBarry Smith Input Parameters: 13463d4c4710SBarry Smith + snes - SNES context 13473d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 13483d4c4710SBarry Smith 13493d4c4710SBarry Smith Level: intermediate 13503d4c4710SBarry Smith 13519d85da0cSMatthew G. Knepley Options Database Keys: 13529d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 13539d85da0cSMatthew G. Knepley 1354a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 13553d4c4710SBarry Smith 13563d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 13573d4c4710SBarry Smith 135858ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 13593d4c4710SBarry Smith @*/ 13607087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 13613d4c4710SBarry Smith { 13623d4c4710SBarry Smith PetscFunctionBegin; 13630700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1364c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 13653d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 13663d4c4710SBarry Smith PetscFunctionReturn(0); 13673d4c4710SBarry Smith } 13683d4c4710SBarry Smith 13693d4c4710SBarry Smith /*@ 13703d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 13713d4c4710SBarry Smith are allowed before SNES terminates 13723d4c4710SBarry Smith 13733d4c4710SBarry Smith Not Collective 13743d4c4710SBarry Smith 13753d4c4710SBarry Smith Input Parameter: 13763d4c4710SBarry Smith . snes - SNES context 13773d4c4710SBarry Smith 13783d4c4710SBarry Smith Output Parameter: 13793d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 13803d4c4710SBarry Smith 13813d4c4710SBarry Smith Level: intermediate 13823d4c4710SBarry Smith 13833d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 13843d4c4710SBarry Smith 13853d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 13863d4c4710SBarry Smith 1387e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 13883d4c4710SBarry Smith @*/ 13897087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 13903d4c4710SBarry Smith { 13913d4c4710SBarry Smith PetscFunctionBegin; 13920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13933d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 13943d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 13953d4c4710SBarry Smith PetscFunctionReturn(0); 13963d4c4710SBarry Smith } 13973d4c4710SBarry Smith 1398c96a6f78SLois Curfman McInnes /*@ 1399b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1400c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1401c96a6f78SLois Curfman McInnes 1402c7afd0dbSLois Curfman McInnes Not Collective 1403c7afd0dbSLois Curfman McInnes 1404c96a6f78SLois Curfman McInnes Input Parameter: 1405c96a6f78SLois Curfman McInnes . snes - SNES context 1406c96a6f78SLois Curfman McInnes 1407c96a6f78SLois Curfman McInnes Output Parameter: 1408c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1409c96a6f78SLois Curfman McInnes 1410c96a6f78SLois Curfman McInnes Notes: 1411971e163fSPeter Brune This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used. 1412c96a6f78SLois Curfman McInnes 1413010be392SBarry Smith If the linear solver fails inside the SNESSolve() the iterations for that call to the linear solver are not included. If you wish to count them 1414010be392SBarry Smith then call KSPGetIterationNumber() after the failed solve. 1415010be392SBarry Smith 141636851e7fSLois Curfman McInnes Level: intermediate 141736851e7fSLois Curfman McInnes 1418c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 14192b668275SBarry Smith 142071dbe336SPeter Brune .seealso: SNESGetIterationNumber(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESSetCountersReset() 1421c96a6f78SLois Curfman McInnes @*/ 14227087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt *lits) 1423c96a6f78SLois Curfman McInnes { 14243a40ed3dSBarry Smith PetscFunctionBegin; 14250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14264482741eSBarry Smith PetscValidIntPointer(lits,2); 1427c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 14283a40ed3dSBarry Smith PetscFunctionReturn(0); 1429c96a6f78SLois Curfman McInnes } 1430c96a6f78SLois Curfman McInnes 1431971e163fSPeter Brune /*@ 1432971e163fSPeter Brune SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations 1433971e163fSPeter Brune are reset every time SNESSolve() is called. 1434971e163fSPeter Brune 1435971e163fSPeter Brune Logically Collective on SNES 1436971e163fSPeter Brune 1437971e163fSPeter Brune Input Parameter: 1438971e163fSPeter Brune + snes - SNES context 1439971e163fSPeter Brune - reset - whether to reset the counters or not 1440971e163fSPeter Brune 1441971e163fSPeter Brune Notes: 1442fa19ca70SBarry Smith This defaults to PETSC_TRUE 1443971e163fSPeter Brune 1444971e163fSPeter Brune Level: developer 1445971e163fSPeter Brune 1446971e163fSPeter Brune .keywords: SNES, nonlinear, set, reset, number, linear, iterations 1447971e163fSPeter Brune 1448734794cfSBarry Smith .seealso: SNESGetNumberFunctionEvals(), SNESGetLinearSolveIterations(), SNESGetNPC() 1449971e163fSPeter Brune @*/ 1450971e163fSPeter Brune PetscErrorCode SNESSetCountersReset(SNES snes,PetscBool reset) 1451971e163fSPeter Brune { 1452971e163fSPeter Brune PetscFunctionBegin; 1453971e163fSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1454971e163fSPeter Brune PetscValidLogicalCollectiveBool(snes,reset,2); 1455971e163fSPeter Brune snes->counters_reset = reset; 1456971e163fSPeter Brune PetscFunctionReturn(0); 1457971e163fSPeter Brune } 1458971e163fSPeter Brune 145982bf6240SBarry Smith 14602999313aSBarry Smith /*@ 14612999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 14622999313aSBarry Smith 14632999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 14642999313aSBarry Smith 14652999313aSBarry Smith Input Parameters: 14662999313aSBarry Smith + snes - the SNES context 14672999313aSBarry Smith - ksp - the KSP context 14682999313aSBarry Smith 14692999313aSBarry Smith Notes: 14702999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 14712999313aSBarry Smith so this routine is rarely needed. 14722999313aSBarry Smith 14732999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 14742999313aSBarry Smith decreased by one. 14752999313aSBarry Smith 14762999313aSBarry Smith Level: developer 14772999313aSBarry Smith 14782999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 14792999313aSBarry Smith 14802999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 14812999313aSBarry Smith @*/ 14827087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 14832999313aSBarry Smith { 14842999313aSBarry Smith PetscErrorCode ierr; 14852999313aSBarry Smith 14862999313aSBarry Smith PetscFunctionBegin; 14870700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14880700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 14892999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 14907dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1491906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 14922999313aSBarry Smith snes->ksp = ksp; 14932999313aSBarry Smith PetscFunctionReturn(0); 14942999313aSBarry Smith } 14952999313aSBarry Smith 14969b94acceSBarry Smith /* -----------------------------------------------------------*/ 149752baeb72SSatish Balay /*@ 14989b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 14999b94acceSBarry Smith 1500c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1501c7afd0dbSLois Curfman McInnes 1502c7afd0dbSLois Curfman McInnes Input Parameters: 1503906ed7ccSBarry Smith . comm - MPI communicator 15049b94acceSBarry Smith 15059b94acceSBarry Smith Output Parameter: 15069b94acceSBarry Smith . outsnes - the new SNES context 15079b94acceSBarry Smith 1508c7afd0dbSLois Curfman McInnes Options Database Keys: 1509c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1510c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1511c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1512c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1513c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1514c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1515c1f60f51SBarry Smith 151636851e7fSLois Curfman McInnes Level: beginner 151736851e7fSLois Curfman McInnes 15189b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 15199b94acceSBarry Smith 1520a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1521a8054027SBarry Smith 15229b94acceSBarry Smith @*/ 15237087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 15249b94acceSBarry Smith { 1525dfbe8321SBarry Smith PetscErrorCode ierr; 15269b94acceSBarry Smith SNES snes; 1527fa9f3622SBarry Smith SNESKSPEW *kctx; 152837fcc0dbSBarry Smith 15293a40ed3dSBarry Smith PetscFunctionBegin; 1530ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 15310298fd71SBarry Smith *outsnes = NULL; 1532607a6623SBarry Smith ierr = SNESInitializePackage();CHKERRQ(ierr); 15338ba1e511SMatthew Knepley 153473107ff1SLisandro Dalcin ierr = PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 15357adad957SLisandro Dalcin 15368d359177SBarry Smith snes->ops->converged = SNESConvergedDefault; 15372c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 153888976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 15399b94acceSBarry Smith snes->max_its = 50; 15409750a799SBarry Smith snes->max_funcs = 10000; 15419b94acceSBarry Smith snes->norm = 0.0; 1542365a6726SPeter Brune snes->normschedule = SNES_NORM_ALWAYS; 15436c67d002SPeter Brune snes->functype = SNES_FUNCTION_DEFAULT; 15443a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 15453a2046daSBarry Smith snes->rtol = 1.e-5; 15463a2046daSBarry Smith #else 1547b4874afaSBarry Smith snes->rtol = 1.e-8; 15483a2046daSBarry Smith #endif 1549b4874afaSBarry Smith snes->ttol = 0.0; 15503a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 15513a2046daSBarry Smith snes->abstol = 1.e-25; 15523a2046daSBarry Smith #else 155370441072SBarry Smith snes->abstol = 1.e-50; 15543a2046daSBarry Smith #endif 15557cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE) 15567cd0ae37SLisandro Dalcin snes->stol = 1.e-5; 15577cd0ae37SLisandro Dalcin #else 1558c60f73f4SPeter Brune snes->stol = 1.e-8; 15597cd0ae37SLisandro Dalcin #endif 15603a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 15613a2046daSBarry Smith snes->deltatol = 1.e-6; 15623a2046daSBarry Smith #else 15634b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 15643a2046daSBarry Smith #endif 1565e37c518bSBarry Smith snes->divtol = 1.e4; 1566e37c518bSBarry Smith snes->rnorm0 = 0; 15679b94acceSBarry Smith snes->nfuncs = 0; 156850ffb88aSMatthew Knepley snes->numFailures = 0; 156950ffb88aSMatthew Knepley snes->maxFailures = 1; 15707a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1571e35cf81dSBarry Smith snes->lagjacobian = 1; 157237ec4e1aSPeter Brune snes->jac_iter = 0; 157337ec4e1aSPeter Brune snes->lagjac_persist = PETSC_FALSE; 1574a8054027SBarry Smith snes->lagpreconditioner = 1; 157537ec4e1aSPeter Brune snes->pre_iter = 0; 157637ec4e1aSPeter Brune snes->lagpre_persist = PETSC_FALSE; 1577639f9d9dSBarry Smith snes->numbermonitors = 0; 15789b94acceSBarry Smith snes->data = 0; 15794dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1580186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 15816f24a144SLois Curfman McInnes snes->nwork = 0; 158258c9b817SLisandro Dalcin snes->work = 0; 158358c9b817SLisandro Dalcin snes->nvwork = 0; 158458c9b817SLisandro Dalcin snes->vwork = 0; 1585758f92a0SBarry Smith snes->conv_hist_len = 0; 1586758f92a0SBarry Smith snes->conv_hist_max = 0; 15870298fd71SBarry Smith snes->conv_hist = NULL; 15880298fd71SBarry Smith snes->conv_hist_its = NULL; 1589758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1590971e163fSPeter Brune snes->counters_reset = PETSC_TRUE; 1591e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1592184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 1593c40d0f55SPeter Brune snes->pcside = PC_RIGHT; 1594c40d0f55SPeter Brune 1595d8f46077SPeter Brune snes->mf = PETSC_FALSE; 1596d8f46077SPeter Brune snes->mf_operator = PETSC_FALSE; 1597d8f46077SPeter Brune snes->mf_version = 1; 1598d8f46077SPeter Brune 15993d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 16003d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 16013d4c4710SBarry Smith 1602349187a7SBarry Smith snes->vizerotolerance = 1.e-8; 1603349187a7SBarry Smith 16044fc747eaSLawrence Mitchell /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */ 16054fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 16064fc747eaSLawrence Mitchell 16079b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 1608b00a9115SJed Brown ierr = PetscNewLog(snes,&kctx);CHKERRQ(ierr); 1609f5af7f23SKarl Rupp 16109b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 16119b94acceSBarry Smith kctx->version = 2; 16129b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 16139b94acceSBarry Smith this was too large for some test cases */ 161475567043SBarry Smith kctx->rtol_last = 0.0; 16159b94acceSBarry Smith kctx->rtol_max = .9; 16169b94acceSBarry Smith kctx->gamma = 1.0; 161762d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 161871f87433Sdalcinl kctx->alpha2 = kctx->alpha; 16199b94acceSBarry Smith kctx->threshold = .1; 162075567043SBarry Smith kctx->lresid_last = 0.0; 162175567043SBarry Smith kctx->norm_last = 0.0; 16229b94acceSBarry Smith 16239b94acceSBarry Smith *outsnes = snes; 16243a40ed3dSBarry Smith PetscFunctionReturn(0); 16259b94acceSBarry Smith } 16269b94acceSBarry Smith 162788f0584fSBarry Smith /*MC 1628411c0326SBarry Smith SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES 162988f0584fSBarry Smith 163088f0584fSBarry Smith Synopsis: 1631411c0326SBarry Smith #include "petscsnes.h" 1632411c0326SBarry Smith PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx); 163388f0584fSBarry Smith 163488f0584fSBarry Smith Input Parameters: 163588f0584fSBarry Smith + snes - the SNES context 163688f0584fSBarry Smith . x - state at which to evaluate residual 163788f0584fSBarry Smith - ctx - optional user-defined function context, passed in with SNESSetFunction() 163888f0584fSBarry Smith 163988f0584fSBarry Smith Output Parameter: 164088f0584fSBarry Smith . f - vector to put residual (function value) 164188f0584fSBarry Smith 1642878cb397SSatish Balay Level: intermediate 1643878cb397SSatish Balay 164488f0584fSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 164588f0584fSBarry Smith M*/ 164688f0584fSBarry Smith 16479b94acceSBarry Smith /*@C 16489b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 16499b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 16509b94acceSBarry Smith equations. 16519b94acceSBarry Smith 16523f9fe445SBarry Smith Logically Collective on SNES 1653fee21e36SBarry Smith 1654c7afd0dbSLois Curfman McInnes Input Parameters: 1655c7afd0dbSLois Curfman McInnes + snes - the SNES context 1656c7afd0dbSLois Curfman McInnes . r - vector to store function value 1657f8b49ee9SBarry Smith . f - function evaluation routine; see SNESFunction for calling sequence details 1658c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 16590298fd71SBarry Smith function evaluation routine (may be NULL) 16609b94acceSBarry Smith 16619b94acceSBarry Smith Notes: 16629b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 16639b94acceSBarry Smith $ f'(x) x = -f(x), 1664c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 16659b94acceSBarry Smith 166636851e7fSLois Curfman McInnes Level: beginner 166736851e7fSLois Curfman McInnes 16689b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 16699b94acceSBarry Smith 1670bf388a1fSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction 16719b94acceSBarry Smith @*/ 1672f8b49ee9SBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 16739b94acceSBarry Smith { 167485385478SLisandro Dalcin PetscErrorCode ierr; 16756cab3a1bSJed Brown DM dm; 16766cab3a1bSJed Brown 16773a40ed3dSBarry Smith PetscFunctionBegin; 16780700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1679d2a683ecSLisandro Dalcin if (r) { 1680d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1681d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 168285385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 16836bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 1684f5af7f23SKarl Rupp 168585385478SLisandro Dalcin snes->vec_func = r; 1686d2a683ecSLisandro Dalcin } 16876cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1688f8b49ee9SBarry Smith ierr = DMSNESSetFunction(dm,f,ctx);CHKERRQ(ierr); 16893a40ed3dSBarry Smith PetscFunctionReturn(0); 16909b94acceSBarry Smith } 16919b94acceSBarry Smith 1692646217ecSPeter Brune 1693e4ed7901SPeter Brune /*@C 1694e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1695e4ed7901SPeter Brune function norm at the initialization of the method. In some 1696e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1697e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1698e4ed7901SPeter Brune to SNESComputeFunction in that case. 1699e4ed7901SPeter Brune 1700e4ed7901SPeter Brune Logically Collective on SNES 1701e4ed7901SPeter Brune 1702e4ed7901SPeter Brune Input Parameters: 1703e4ed7901SPeter Brune + snes - the SNES context 1704e4ed7901SPeter Brune - f - vector to store function value 1705e4ed7901SPeter Brune 1706e4ed7901SPeter Brune Notes: 1707e4ed7901SPeter Brune This should not be modified during the solution procedure. 1708e4ed7901SPeter Brune 1709e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1710e4ed7901SPeter Brune 1711e4ed7901SPeter Brune Level: developer 1712e4ed7901SPeter Brune 1713e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function 1714e4ed7901SPeter Brune 1715e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1716e4ed7901SPeter Brune @*/ 1717e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1718e4ed7901SPeter Brune { 1719e4ed7901SPeter Brune PetscErrorCode ierr; 1720e4ed7901SPeter Brune Vec vec_func; 1721e4ed7901SPeter Brune 1722e4ed7901SPeter Brune PetscFunctionBegin; 1723e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1724e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1725e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 17265c9e203fSPeter Brune if (snes->pcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) { 1727902f982fSPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1728902f982fSPeter Brune PetscFunctionReturn(0); 1729902f982fSPeter Brune } 17300298fd71SBarry Smith ierr = SNESGetFunction(snes,&vec_func,NULL,NULL);CHKERRQ(ierr); 1731e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1732f5af7f23SKarl Rupp 1733217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1734e4ed7901SPeter Brune PetscFunctionReturn(0); 1735e4ed7901SPeter Brune } 1736e4ed7901SPeter Brune 1737534ebe21SPeter Brune /*@ 1738365a6726SPeter Brune SNESSetNormSchedule - Sets the SNESNormSchedule used in covergence and monitoring 1739534ebe21SPeter Brune of the SNES method. 1740534ebe21SPeter Brune 1741534ebe21SPeter Brune Logically Collective on SNES 1742534ebe21SPeter Brune 1743534ebe21SPeter Brune Input Parameters: 1744534ebe21SPeter Brune + snes - the SNES context 1745365a6726SPeter Brune - normschedule - the frequency of norm computation 1746534ebe21SPeter Brune 1747517f1916SMatthew G. Knepley Options Database Key: 1748517f1916SMatthew G. Knepley . -snes_norm_schedule <none, always, initialonly, finalonly, initalfinalonly> 1749517f1916SMatthew G. Knepley 1750534ebe21SPeter Brune Notes: 1751365a6726SPeter Brune Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 1752534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1753534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1754be95d8f1SBarry Smith (SNESNGS) and the like do not require the norm of the function to be computed, and therfore 1755534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1756534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1757534ebe21SPeter Brune their solution. 1758534ebe21SPeter Brune 1759534ebe21SPeter Brune Level: developer 1760534ebe21SPeter Brune 1761534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1762534ebe21SPeter Brune 1763365a6726SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1764534ebe21SPeter Brune @*/ 1765365a6726SPeter Brune PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule) 1766534ebe21SPeter Brune { 1767534ebe21SPeter Brune PetscFunctionBegin; 1768534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1769365a6726SPeter Brune snes->normschedule = normschedule; 1770534ebe21SPeter Brune PetscFunctionReturn(0); 1771534ebe21SPeter Brune } 1772534ebe21SPeter Brune 1773534ebe21SPeter Brune 1774534ebe21SPeter Brune /*@ 1775365a6726SPeter Brune SNESGetNormSchedule - Gets the SNESNormSchedule used in covergence and monitoring 1776534ebe21SPeter Brune of the SNES method. 1777534ebe21SPeter Brune 1778534ebe21SPeter Brune Logically Collective on SNES 1779534ebe21SPeter Brune 1780534ebe21SPeter Brune Input Parameters: 1781534ebe21SPeter Brune + snes - the SNES context 1782365a6726SPeter Brune - normschedule - the type of the norm used 1783534ebe21SPeter Brune 1784534ebe21SPeter Brune Level: advanced 1785534ebe21SPeter Brune 1786534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1787534ebe21SPeter Brune 1788365a6726SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1789534ebe21SPeter Brune @*/ 1790365a6726SPeter Brune PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule) 1791534ebe21SPeter Brune { 1792534ebe21SPeter Brune PetscFunctionBegin; 1793534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1794365a6726SPeter Brune *normschedule = snes->normschedule; 1795534ebe21SPeter Brune PetscFunctionReturn(0); 1796534ebe21SPeter Brune } 1797534ebe21SPeter Brune 179847073ea2SPeter Brune 1799c5ce4427SMatthew G. Knepley /*@ 1800c5ce4427SMatthew G. Knepley SNESSetFunctionNorm - Sets the last computed residual norm. 1801c5ce4427SMatthew G. Knepley 1802c5ce4427SMatthew G. Knepley Logically Collective on SNES 1803c5ce4427SMatthew G. Knepley 1804c5ce4427SMatthew G. Knepley Input Parameters: 1805c5ce4427SMatthew G. Knepley + snes - the SNES context 1806c5ce4427SMatthew G. Knepley 1807c5ce4427SMatthew G. Knepley - normschedule - the frequency of norm computation 1808c5ce4427SMatthew G. Knepley 1809c5ce4427SMatthew G. Knepley Level: developer 1810c5ce4427SMatthew G. Knepley 1811c5ce4427SMatthew G. Knepley .keywords: SNES, nonlinear, set, function, norm, type 1812c5ce4427SMatthew G. Knepley .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1813c5ce4427SMatthew G. Knepley @*/ 1814c5ce4427SMatthew G. Knepley PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm) 1815c5ce4427SMatthew G. Knepley { 1816c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1817c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1818c5ce4427SMatthew G. Knepley snes->norm = norm; 1819c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 1820c5ce4427SMatthew G. Knepley } 1821c5ce4427SMatthew G. Knepley 1822c5ce4427SMatthew G. Knepley /*@ 1823c5ce4427SMatthew G. Knepley SNESGetFunctionNorm - Gets the last computed norm of the residual 1824c5ce4427SMatthew G. Knepley 1825c5ce4427SMatthew G. Knepley Not Collective 1826c5ce4427SMatthew G. Knepley 1827c5ce4427SMatthew G. Knepley Input Parameter: 1828c5ce4427SMatthew G. Knepley . snes - the SNES context 1829c5ce4427SMatthew G. Knepley 1830c5ce4427SMatthew G. Knepley Output Parameter: 1831c5ce4427SMatthew G. Knepley . norm - the last computed residual norm 1832c5ce4427SMatthew G. Knepley 1833c5ce4427SMatthew G. Knepley Level: developer 1834c5ce4427SMatthew G. Knepley 1835c5ce4427SMatthew G. Knepley .keywords: SNES, nonlinear, set, function, norm, type 1836c5ce4427SMatthew G. Knepley .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1837c5ce4427SMatthew G. Knepley @*/ 1838c5ce4427SMatthew G. Knepley PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm) 1839c5ce4427SMatthew G. Knepley { 1840c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1841c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1842c5ce4427SMatthew G. Knepley PetscValidPointer(norm, 2); 1843c5ce4427SMatthew G. Knepley *norm = snes->norm; 1844c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 1845c5ce4427SMatthew G. Knepley } 1846c5ce4427SMatthew G. Knepley 184747073ea2SPeter Brune /*@C 184847073ea2SPeter Brune SNESSetFunctionType - Sets the SNESNormSchedule used in covergence and monitoring 184947073ea2SPeter Brune of the SNES method. 185047073ea2SPeter Brune 185147073ea2SPeter Brune Logically Collective on SNES 185247073ea2SPeter Brune 185347073ea2SPeter Brune Input Parameters: 185447073ea2SPeter Brune + snes - the SNES context 185547073ea2SPeter Brune - normschedule - the frequency of norm computation 185647073ea2SPeter Brune 185747073ea2SPeter Brune Notes: 185847073ea2SPeter Brune Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 185947073ea2SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 186047073ea2SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1861be95d8f1SBarry Smith (SNESNGS) and the like do not require the norm of the function to be computed, and therfore 186247073ea2SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 186347073ea2SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 186447073ea2SPeter Brune their solution. 186547073ea2SPeter Brune 186647073ea2SPeter Brune Level: developer 186747073ea2SPeter Brune 186847073ea2SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 186947073ea2SPeter Brune 187047073ea2SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 187147073ea2SPeter Brune @*/ 187247073ea2SPeter Brune PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type) 187347073ea2SPeter Brune { 187447073ea2SPeter Brune PetscFunctionBegin; 187547073ea2SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 187647073ea2SPeter Brune snes->functype = type; 187747073ea2SPeter Brune PetscFunctionReturn(0); 187847073ea2SPeter Brune } 187947073ea2SPeter Brune 188047073ea2SPeter Brune 188147073ea2SPeter Brune /*@C 188247073ea2SPeter Brune SNESGetFunctionType - Gets the SNESNormSchedule used in covergence and monitoring 188347073ea2SPeter Brune of the SNES method. 188447073ea2SPeter Brune 188547073ea2SPeter Brune Logically Collective on SNES 188647073ea2SPeter Brune 188747073ea2SPeter Brune Input Parameters: 188847073ea2SPeter Brune + snes - the SNES context 188947073ea2SPeter Brune - normschedule - the type of the norm used 189047073ea2SPeter Brune 189147073ea2SPeter Brune Level: advanced 189247073ea2SPeter Brune 189347073ea2SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 189447073ea2SPeter Brune 189547073ea2SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 189647073ea2SPeter Brune @*/ 189747073ea2SPeter Brune PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type) 189847073ea2SPeter Brune { 189947073ea2SPeter Brune PetscFunctionBegin; 190047073ea2SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 190147073ea2SPeter Brune *type = snes->functype; 1902534ebe21SPeter Brune PetscFunctionReturn(0); 1903534ebe21SPeter Brune } 1904534ebe21SPeter Brune 1905bf388a1fSBarry Smith /*MC 1906be95d8f1SBarry Smith SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function 1907bf388a1fSBarry Smith 1908bf388a1fSBarry Smith Synopsis: 1909aaa7dc30SBarry Smith #include <petscsnes.h> 1910be95d8f1SBarry Smith $ SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx); 1911bf388a1fSBarry Smith 1912bf388a1fSBarry Smith + X - solution vector 1913bf388a1fSBarry Smith . B - RHS vector 1914bf388a1fSBarry Smith - ctx - optional user-defined Gauss-Seidel context 1915bf388a1fSBarry Smith 1916878cb397SSatish Balay Level: intermediate 1917878cb397SSatish Balay 1918be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetNGS() 1919bf388a1fSBarry Smith M*/ 1920bf388a1fSBarry Smith 1921c79ef259SPeter Brune /*@C 1922be95d8f1SBarry Smith SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for 1923c79ef259SPeter Brune use with composed nonlinear solvers. 1924c79ef259SPeter Brune 1925c79ef259SPeter Brune Input Parameters: 1926c79ef259SPeter Brune + snes - the SNES context 1927be95d8f1SBarry Smith . f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction 1928c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 19290298fd71SBarry Smith smoother evaluation routine (may be NULL) 1930c79ef259SPeter Brune 1931c79ef259SPeter Brune Notes: 1932be95d8f1SBarry Smith The NGS routines are used by the composed nonlinear solver to generate 1933c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1934c79ef259SPeter Brune 1935d28543b3SPeter Brune Level: intermediate 1936c79ef259SPeter Brune 1937d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1938c79ef259SPeter Brune 1939be95d8f1SBarry Smith .seealso: SNESGetFunction(), SNESComputeNGS() 1940c79ef259SPeter Brune @*/ 1941be95d8f1SBarry Smith PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 19426cab3a1bSJed Brown { 19436cab3a1bSJed Brown PetscErrorCode ierr; 19446cab3a1bSJed Brown DM dm; 19456cab3a1bSJed Brown 1946646217ecSPeter Brune PetscFunctionBegin; 19476cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 19486cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1949be95d8f1SBarry Smith ierr = DMSNESSetNGS(dm,f,ctx);CHKERRQ(ierr); 1950646217ecSPeter Brune PetscFunctionReturn(0); 1951646217ecSPeter Brune } 1952646217ecSPeter Brune 195382b59a81SJed Brown PETSC_EXTERN PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 19548b0a5094SBarry Smith { 19558b0a5094SBarry Smith PetscErrorCode ierr; 1956e03ab78fSPeter Brune DM dm; 1957942e3340SBarry Smith DMSNES sdm; 19586cab3a1bSJed Brown 19598b0a5094SBarry Smith PetscFunctionBegin; 1960e03ab78fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1961942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 19628b0a5094SBarry Smith /* A(x)*x - b(x) */ 196322c6f798SBarry Smith if (sdm->ops->computepfunction) { 196422c6f798SBarry Smith ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr); 196522c6f798SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard function."); 1966e03ab78fSPeter Brune 196722c6f798SBarry Smith if (sdm->ops->computepjacobian) { 1968d1e9a80fSBarry Smith ierr = (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);CHKERRQ(ierr); 196974e1e8c1SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard matrix."); 19708b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 197195eabcedSBarry Smith ierr = MatMultAdd(snes->jacobian,x,f,f);CHKERRQ(ierr); 19728b0a5094SBarry Smith PetscFunctionReturn(0); 19738b0a5094SBarry Smith } 19748b0a5094SBarry Smith 1975d1e9a80fSBarry Smith PETSC_EXTERN PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx) 19768b0a5094SBarry Smith { 19778b0a5094SBarry Smith PetscFunctionBegin; 1978e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 19798b0a5094SBarry Smith PetscFunctionReturn(0); 19808b0a5094SBarry Smith } 19818b0a5094SBarry Smith 19828b0a5094SBarry Smith /*@C 19830d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 19848b0a5094SBarry Smith 19858b0a5094SBarry Smith Logically Collective on SNES 19868b0a5094SBarry Smith 19878b0a5094SBarry Smith Input Parameters: 19888b0a5094SBarry Smith + snes - the SNES context 19898b0a5094SBarry Smith . r - vector to store function value 1990f8b49ee9SBarry Smith . b - function evaluation routine 1991e5d3d808SBarry Smith . Amat - matrix with which A(x) x - b(x) is to be computed 1992e5d3d808SBarry Smith . Pmat - matrix from which preconditioner is computed (usually the same as Amat) 1993411c0326SBarry Smith . J - function to compute matrix value, see SNESJacobianFunction for details on its calling sequence 19948b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 19950298fd71SBarry Smith function evaluation routine (may be NULL) 19968b0a5094SBarry Smith 19978b0a5094SBarry Smith Notes: 1998f450aa47SBarry 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 1999f450aa47SBarry 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. 2000f450aa47SBarry Smith 20018b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 20028b0a5094SBarry Smith 20038b0a5094SBarry 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} 20048b0a5094SBarry 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. 20058b0a5094SBarry Smith 20068b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 20078b0a5094SBarry Smith 20080d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 20090d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 20108b0a5094SBarry Smith 20118b0a5094SBarry 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 20128b0a5094SBarry 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 20138b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 20148b0a5094SBarry Smith 2015f450aa47SBarry Smith Level: intermediate 20168b0a5094SBarry Smith 20178b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 20188b0a5094SBarry Smith 2019411c0326SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard(), SNESJacobianFunction 20208b0a5094SBarry Smith @*/ 2021d1e9a80fSBarry 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) 20228b0a5094SBarry Smith { 20238b0a5094SBarry Smith PetscErrorCode ierr; 2024e03ab78fSPeter Brune DM dm; 2025e03ab78fSPeter Brune 20268b0a5094SBarry Smith PetscFunctionBegin; 20278b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2028e03ab78fSPeter Brune ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 2029f8b49ee9SBarry Smith ierr = DMSNESSetPicard(dm,b,J,ctx);CHKERRQ(ierr); 20308b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 2031e5d3d808SBarry Smith ierr = SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 20328b0a5094SBarry Smith PetscFunctionReturn(0); 20338b0a5094SBarry Smith } 20348b0a5094SBarry Smith 20357971a8bfSPeter Brune /*@C 20367971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 20377971a8bfSPeter Brune 20387971a8bfSPeter Brune Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 20397971a8bfSPeter Brune 20407971a8bfSPeter Brune Input Parameter: 20417971a8bfSPeter Brune . snes - the SNES context 20427971a8bfSPeter Brune 20437971a8bfSPeter Brune Output Parameter: 20440298fd71SBarry Smith + r - the function (or NULL) 2045f8b49ee9SBarry Smith . f - the function (or NULL); see SNESFunction for calling sequence details 2046e4357dc4SBarry Smith . Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL) 2047e4357dc4SBarry Smith . Pmat - the matrix from which the preconditioner will be constructed (or NULL) 2048f8b49ee9SBarry Smith . J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details 20490298fd71SBarry Smith - ctx - the function context (or NULL) 20507971a8bfSPeter Brune 20517971a8bfSPeter Brune Level: advanced 20527971a8bfSPeter Brune 20537971a8bfSPeter Brune .keywords: SNES, nonlinear, get, function 20547971a8bfSPeter Brune 2055e4357dc4SBarry Smith .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction 20567971a8bfSPeter Brune @*/ 2057d1e9a80fSBarry 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) 20587971a8bfSPeter Brune { 20597971a8bfSPeter Brune PetscErrorCode ierr; 20607971a8bfSPeter Brune DM dm; 20617971a8bfSPeter Brune 20627971a8bfSPeter Brune PetscFunctionBegin; 20637971a8bfSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20640298fd71SBarry Smith ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 2065e4357dc4SBarry Smith ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 20667971a8bfSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2067f8b49ee9SBarry Smith ierr = DMSNESGetPicard(dm,f,J,ctx);CHKERRQ(ierr); 20687971a8bfSPeter Brune PetscFunctionReturn(0); 20697971a8bfSPeter Brune } 20707971a8bfSPeter Brune 2071d25893d9SBarry Smith /*@C 2072d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 2073d25893d9SBarry Smith 2074d25893d9SBarry Smith Logically Collective on SNES 2075d25893d9SBarry Smith 2076d25893d9SBarry Smith Input Parameters: 2077d25893d9SBarry Smith + snes - the SNES context 2078d25893d9SBarry Smith . func - function evaluation routine 2079d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 20800298fd71SBarry Smith function evaluation routine (may be NULL) 2081d25893d9SBarry Smith 2082d25893d9SBarry Smith Calling sequence of func: 2083d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 2084d25893d9SBarry Smith 2085d25893d9SBarry Smith . f - function vector 2086d25893d9SBarry Smith - ctx - optional user-defined function context 2087d25893d9SBarry Smith 2088d25893d9SBarry Smith Level: intermediate 2089d25893d9SBarry Smith 2090d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 2091d25893d9SBarry Smith 2092d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 2093d25893d9SBarry Smith @*/ 2094d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 2095d25893d9SBarry Smith { 2096d25893d9SBarry Smith PetscFunctionBegin; 2097d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2098d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 2099d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 2100d25893d9SBarry Smith PetscFunctionReturn(0); 2101d25893d9SBarry Smith } 2102d25893d9SBarry Smith 21033ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 21041096aae1SMatthew Knepley /*@C 21051096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 21061096aae1SMatthew Knepley it assumes a zero right hand side. 21071096aae1SMatthew Knepley 21083f9fe445SBarry Smith Logically Collective on SNES 21091096aae1SMatthew Knepley 21101096aae1SMatthew Knepley Input Parameter: 21111096aae1SMatthew Knepley . snes - the SNES context 21121096aae1SMatthew Knepley 21131096aae1SMatthew Knepley Output Parameter: 21140298fd71SBarry Smith . rhs - the right hand side vector or NULL if the right hand side vector is null 21151096aae1SMatthew Knepley 21161096aae1SMatthew Knepley Level: intermediate 21171096aae1SMatthew Knepley 21181096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 21191096aae1SMatthew Knepley 212085385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 21211096aae1SMatthew Knepley @*/ 21227087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 21231096aae1SMatthew Knepley { 21241096aae1SMatthew Knepley PetscFunctionBegin; 21250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21261096aae1SMatthew Knepley PetscValidPointer(rhs,2); 212785385478SLisandro Dalcin *rhs = snes->vec_rhs; 21281096aae1SMatthew Knepley PetscFunctionReturn(0); 21291096aae1SMatthew Knepley } 21301096aae1SMatthew Knepley 21319b94acceSBarry Smith /*@ 2132bf388a1fSBarry Smith SNESComputeFunction - Calls the function that has been set with SNESSetFunction(). 21339b94acceSBarry Smith 2134c7afd0dbSLois Curfman McInnes Collective on SNES 2135c7afd0dbSLois Curfman McInnes 21369b94acceSBarry Smith Input Parameters: 2137c7afd0dbSLois Curfman McInnes + snes - the SNES context 2138c7afd0dbSLois Curfman McInnes - x - input vector 21399b94acceSBarry Smith 21409b94acceSBarry Smith Output Parameter: 21413638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 21429b94acceSBarry Smith 21431bffabb2SLois Curfman McInnes Notes: 214436851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 214536851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 214636851e7fSLois Curfman McInnes themselves. 214736851e7fSLois Curfman McInnes 214836851e7fSLois Curfman McInnes Level: developer 214936851e7fSLois Curfman McInnes 21509b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 21519b94acceSBarry Smith 2152a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 21539b94acceSBarry Smith @*/ 21547087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 21559b94acceSBarry Smith { 2156dfbe8321SBarry Smith PetscErrorCode ierr; 21576cab3a1bSJed Brown DM dm; 2158942e3340SBarry Smith DMSNES sdm; 21599b94acceSBarry Smith 21603a40ed3dSBarry Smith PetscFunctionBegin; 21610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21620700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 21630700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2164c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 2165c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 216662796dfbSBarry Smith ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr); 2167184914b5SBarry Smith 21686cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2169942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 217032f3f7c2SPeter Brune if (sdm->ops->computefunction) { 217194db00ebSBarry Smith if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2172ccf3c845SPeter Brune ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 217394db00ebSBarry Smith } 21745edff71fSBarry Smith ierr = VecLockPush(x);CHKERRQ(ierr); 2175d64ed03dSBarry Smith PetscStackPush("SNES user function"); 217622c6f798SBarry Smith ierr = (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 2177d64ed03dSBarry Smith PetscStackPop; 21785edff71fSBarry Smith ierr = VecLockPop(x);CHKERRQ(ierr); 217994db00ebSBarry Smith if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2180ccf3c845SPeter Brune ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 218194db00ebSBarry Smith } 2182c90fad12SPeter Brune } else if (snes->vec_rhs) { 2183c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 2184644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 218585385478SLisandro Dalcin if (snes->vec_rhs) { 218685385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 21873ab0aad5SBarry Smith } 2188ae3c334cSLois Curfman McInnes snes->nfuncs++; 2189422a814eSBarry Smith /* 2190422a814eSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2191422a814eSBarry Smith propagate the value to all processes 2192422a814eSBarry Smith */ 2193422a814eSBarry Smith if (snes->domainerror) { 2194422a814eSBarry Smith ierr = VecSetInf(y);CHKERRQ(ierr); 2195422a814eSBarry Smith } 21963a40ed3dSBarry Smith PetscFunctionReturn(0); 21979b94acceSBarry Smith } 21989b94acceSBarry Smith 2199c79ef259SPeter Brune /*@ 2200be95d8f1SBarry Smith SNESComputeNGS - Calls the Gauss-Seidel function that has been set with SNESSetNGS(). 2201c79ef259SPeter Brune 2202c79ef259SPeter Brune Collective on SNES 2203c79ef259SPeter Brune 2204c79ef259SPeter Brune Input Parameters: 2205c79ef259SPeter Brune + snes - the SNES context 2206c79ef259SPeter Brune . x - input vector 2207c79ef259SPeter Brune - b - rhs vector 2208c79ef259SPeter Brune 2209c79ef259SPeter Brune Output Parameter: 2210c79ef259SPeter Brune . x - new solution vector 2211c79ef259SPeter Brune 2212c79ef259SPeter Brune Notes: 2213be95d8f1SBarry Smith SNESComputeNGS() is typically used within composed nonlinear solver 2214c79ef259SPeter Brune implementations, so most users would not generally call this routine 2215c79ef259SPeter Brune themselves. 2216c79ef259SPeter Brune 2217c79ef259SPeter Brune Level: developer 2218c79ef259SPeter Brune 2219c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 2220c79ef259SPeter Brune 2221be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESComputeFunction() 2222c79ef259SPeter Brune @*/ 2223be95d8f1SBarry Smith PetscErrorCode SNESComputeNGS(SNES snes,Vec b,Vec x) 2224646217ecSPeter Brune { 2225646217ecSPeter Brune PetscErrorCode ierr; 22266cab3a1bSJed Brown DM dm; 2227942e3340SBarry Smith DMSNES sdm; 2228646217ecSPeter Brune 2229646217ecSPeter Brune PetscFunctionBegin; 2230646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2231646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2232646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 2233646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 2234646217ecSPeter Brune if (b) PetscCheckSameComm(snes,1,b,3); 223562796dfbSBarry Smith if (b) {ierr = VecValidValues(b,2,PETSC_TRUE);CHKERRQ(ierr);} 2236be95d8f1SBarry Smith ierr = PetscLogEventBegin(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr); 22376cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2238942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 223922c6f798SBarry Smith if (sdm->ops->computegs) { 22405edff71fSBarry Smith if (b) {ierr = VecLockPush(b);CHKERRQ(ierr);} 2241be95d8f1SBarry Smith PetscStackPush("SNES user NGS"); 224222c6f798SBarry Smith ierr = (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 2243646217ecSPeter Brune PetscStackPop; 22445edff71fSBarry Smith if (b) {ierr = VecLockPop(b);CHKERRQ(ierr);} 2245be95d8f1SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 2246be95d8f1SBarry Smith ierr = PetscLogEventEnd(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr); 2247646217ecSPeter Brune PetscFunctionReturn(0); 2248646217ecSPeter Brune } 2249646217ecSPeter Brune 225062fef451SLois Curfman McInnes /*@ 2251bf388a1fSBarry Smith SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian(). 225262fef451SLois Curfman McInnes 2253c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 2254c7afd0dbSLois Curfman McInnes 225562fef451SLois Curfman McInnes Input Parameters: 2256c7afd0dbSLois Curfman McInnes + snes - the SNES context 2257c7afd0dbSLois Curfman McInnes - x - input vector 225862fef451SLois Curfman McInnes 225962fef451SLois Curfman McInnes Output Parameters: 2260c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 2261d1e9a80fSBarry Smith - B - optional preconditioning matrix 2262fee21e36SBarry Smith 2263e35cf81dSBarry Smith Options Database Keys: 2264e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 2265693365a8SJed Brown . -snes_lag_jacobian <lag> 2266693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2267693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2268693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 22694c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 227094d6a431SBarry Smith . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2271c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 2272c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2273c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2274c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 22754c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 2276c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 2277c01495d3SJed Brown 2278e35cf81dSBarry Smith 227962fef451SLois Curfman McInnes Notes: 228062fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 228162fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 228262fef451SLois Curfman McInnes 228336851e7fSLois Curfman McInnes Level: developer 228436851e7fSLois Curfman McInnes 228562fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 228662fef451SLois Curfman McInnes 2287e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 228862fef451SLois Curfman McInnes @*/ 2289d1e9a80fSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B) 22909b94acceSBarry Smith { 2291dfbe8321SBarry Smith PetscErrorCode ierr; 2292ace3abfcSBarry Smith PetscBool flag; 22936cab3a1bSJed Brown DM dm; 2294942e3340SBarry Smith DMSNES sdm; 2295e0e3a89bSBarry Smith KSP ksp; 22963a40ed3dSBarry Smith 22973a40ed3dSBarry Smith PetscFunctionBegin; 22980700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 22990700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2300c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 230162796dfbSBarry Smith ierr = VecValidValues(X,2,PETSC_TRUE);CHKERRQ(ierr); 23026cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2303942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 23043232da50SPeter Brune 2305ce94432eSBarry Smith if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 2306ebd3b9afSBarry Smith 2307ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2308ebd3b9afSBarry Smith 2309fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2310fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2311f5af7f23SKarl Rupp 2312fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 2313fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 2314e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 231594ab13aaSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2316ebd3b9afSBarry Smith if (flag) { 231794ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 231894ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2319ebd3b9afSBarry Smith } 2320e35cf81dSBarry Smith PetscFunctionReturn(0); 232137ec4e1aSPeter Brune } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 2322e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 232394ab13aaSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2324ebd3b9afSBarry Smith if (flag) { 232594ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 232694ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2327ebd3b9afSBarry Smith } 2328e35cf81dSBarry Smith PetscFunctionReturn(0); 2329e35cf81dSBarry Smith } 2330d728fb7dSPeter Brune if (snes->pc && snes->pcside == PC_LEFT) { 233194ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 233294ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2333d728fb7dSPeter Brune PetscFunctionReturn(0); 2334d728fb7dSPeter Brune } 2335e35cf81dSBarry Smith 233694ab13aaSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 23375edff71fSBarry Smith ierr = VecLockPush(X);CHKERRQ(ierr); 2338d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 2339d1e9a80fSBarry Smith ierr = (*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx);CHKERRQ(ierr); 2340d64ed03dSBarry Smith PetscStackPop; 23415edff71fSBarry Smith ierr = VecLockPop(X);CHKERRQ(ierr); 234294ab13aaSBarry Smith ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 2343a8054027SBarry Smith 2344e0e3a89bSBarry Smith /* the next line ensures that snes->ksp exists */ 2345e0e3a89bSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 23463b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 23473b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 2348d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 23493b4f5425SBarry Smith snes->lagpreconditioner = -1; 23503b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 2351a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2352d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 235337ec4e1aSPeter Brune } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 2354a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2355d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 2356d1e9a80fSBarry Smith } else { 2357d1e9a80fSBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner\n");CHKERRQ(ierr); 2358d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 2359a8054027SBarry Smith } 2360a8054027SBarry Smith 23616d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 236294ab13aaSBarry Smith /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 236394ab13aaSBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2364693365a8SJed Brown { 2365693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 236627b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag);CHKERRQ(ierr); 236727b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr); 236827b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr); 236927b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator);CHKERRQ(ierr); 2370693365a8SJed Brown if (flag || flag_draw || flag_contour) { 23710298fd71SBarry Smith Mat Bexp_mine = NULL,Bexp,FDexp; 2372693365a8SJed Brown PetscViewer vdraw,vstdout; 23736b3a5b13SJed Brown PetscBool flg; 2374693365a8SJed Brown if (flag_operator) { 237594ab13aaSBarry Smith ierr = MatComputeExplicitOperator(A,&Bexp_mine);CHKERRQ(ierr); 2376693365a8SJed Brown Bexp = Bexp_mine; 2377693365a8SJed Brown } else { 2378693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 237994ab13aaSBarry Smith ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 238094ab13aaSBarry Smith if (flg) Bexp = B; 2381693365a8SJed Brown else { 2382693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 238394ab13aaSBarry Smith ierr = MatComputeExplicitOperator(B,&Bexp_mine);CHKERRQ(ierr); 2384693365a8SJed Brown Bexp = Bexp_mine; 2385693365a8SJed Brown } 2386693365a8SJed Brown } 2387693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2388d1e9a80fSBarry Smith ierr = SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL);CHKERRQ(ierr); 2389ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 2390693365a8SJed Brown if (flag_draw || flag_contour) { 2391ce94432eSBarry Smith ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2392693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 23930298fd71SBarry Smith } else vdraw = NULL; 2394693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");CHKERRQ(ierr); 2395693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2396693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2397693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2398693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2399693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2400693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2401693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2402693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2403693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2404693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2405693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2406693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2407693365a8SJed Brown } 2408693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2409693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2410693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2411693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2412693365a8SJed Brown } 2413693365a8SJed Brown } 24144c30e9fbSJed Brown { 24156719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 24166719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 241727b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag);CHKERRQ(ierr); 241827b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display);CHKERRQ(ierr); 241927b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr); 242027b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr); 242127b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold);CHKERRQ(ierr); 242227b0f280SBarry Smith if (flag_threshold) { 2423c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);CHKERRQ(ierr); 2424c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);CHKERRQ(ierr); 242527b0f280SBarry Smith } 24266719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 24274c30e9fbSJed Brown Mat Bfd; 24284c30e9fbSJed Brown PetscViewer vdraw,vstdout; 2429335efc43SPeter Brune MatColoring coloring; 24304c30e9fbSJed Brown ISColoring iscoloring; 24314c30e9fbSJed Brown MatFDColoring matfdcoloring; 24324c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 24334c30e9fbSJed Brown void *funcctx; 24346719d8e4SJed Brown PetscReal norm1,norm2,normmax; 24354c30e9fbSJed Brown 243694ab13aaSBarry Smith ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 2437335efc43SPeter Brune ierr = MatColoringCreate(Bfd,&coloring);CHKERRQ(ierr); 2438335efc43SPeter Brune ierr = MatColoringSetType(coloring,MATCOLORINGSL);CHKERRQ(ierr); 2439335efc43SPeter Brune ierr = MatColoringSetFromOptions(coloring);CHKERRQ(ierr); 2440335efc43SPeter Brune ierr = MatColoringApply(coloring,&iscoloring);CHKERRQ(ierr); 2441335efc43SPeter Brune ierr = MatColoringDestroy(&coloring);CHKERRQ(ierr); 24424c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 2443f86b9fbaSHong Zhang ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2444f86b9fbaSHong Zhang ierr = MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring);CHKERRQ(ierr); 24454c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 24464c30e9fbSJed Brown 24474c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 24480298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,&func,&funcctx);CHKERRQ(ierr); 24494c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr); 24504c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 24514c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 24524c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2453d1e9a80fSBarry Smith ierr = MatFDColoringApply(Bfd,matfdcoloring,X,snes);CHKERRQ(ierr); 24544c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 24554c30e9fbSJed Brown 2456ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 24574c30e9fbSJed Brown if (flag_draw || flag_contour) { 2458ce94432eSBarry Smith ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 24594c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 24600298fd71SBarry Smith } else vdraw = NULL; 24614c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 246294ab13aaSBarry Smith if (flag_display) {ierr = MatView(B,vstdout);CHKERRQ(ierr);} 246394ab13aaSBarry Smith if (vdraw) {ierr = MatView(B,vdraw);CHKERRQ(ierr);} 24644c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 24656719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 24664c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 246794ab13aaSBarry Smith ierr = MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 24684c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 24696719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 24704c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 247157622a8eSBarry 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); 24726719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 24734c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 24744c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 24754c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 24764c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 24774c30e9fbSJed Brown } 24784c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 24796719d8e4SJed Brown 24806719d8e4SJed Brown if (flag_threshold) { 24816719d8e4SJed Brown PetscInt bs,rstart,rend,i; 248294ab13aaSBarry Smith ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr); 248394ab13aaSBarry Smith ierr = MatGetOwnershipRange(B,&rstart,&rend);CHKERRQ(ierr); 24846719d8e4SJed Brown for (i=rstart; i<rend; i++) { 24856719d8e4SJed Brown const PetscScalar *ba,*ca; 24866719d8e4SJed Brown const PetscInt *bj,*cj; 24876719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 24886719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 248994ab13aaSBarry Smith ierr = MatGetRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 24906719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 249194ab13aaSBarry Smith if (bn != cn) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 24926719d8e4SJed Brown for (j=0; j<bn; j++) { 24936719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 24946719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 24956719d8e4SJed Brown maxentrycol = bj[j]; 24966719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 24976719d8e4SJed Brown } 24986719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 24996719d8e4SJed Brown maxdiffcol = bj[j]; 25006719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 25016719d8e4SJed Brown } 25026719d8e4SJed Brown if (rdiff > maxrdiff) { 25036719d8e4SJed Brown maxrdiffcol = bj[j]; 25046719d8e4SJed Brown maxrdiff = rdiff; 25056719d8e4SJed Brown } 25066719d8e4SJed Brown } 25076719d8e4SJed Brown if (maxrdiff > 1) { 250857622a8eSBarry 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); 25096719d8e4SJed Brown for (j=0; j<bn; j++) { 25106719d8e4SJed Brown PetscReal rdiff; 25116719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 25126719d8e4SJed Brown if (rdiff > 1) { 251357622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]));CHKERRQ(ierr); 25146719d8e4SJed Brown } 25156719d8e4SJed Brown } 25166719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 25176719d8e4SJed Brown } 251894ab13aaSBarry Smith ierr = MatRestoreRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 25196719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 25206719d8e4SJed Brown } 25216719d8e4SJed Brown } 25224c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 25234c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 25244c30e9fbSJed Brown } 25254c30e9fbSJed Brown } 25263a40ed3dSBarry Smith PetscFunctionReturn(0); 25279b94acceSBarry Smith } 25289b94acceSBarry Smith 2529bf388a1fSBarry Smith /*MC 2530411c0326SBarry Smith SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES 2531bf388a1fSBarry Smith 2532bf388a1fSBarry Smith Synopsis: 2533411c0326SBarry Smith #include "petscsnes.h" 2534411c0326SBarry Smith PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 2535bf388a1fSBarry Smith 2536bf388a1fSBarry Smith + x - input vector 2537e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 2538e5d3d808SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 2539bf388a1fSBarry Smith - ctx - [optional] user-defined Jacobian context 2540bf388a1fSBarry Smith 2541878cb397SSatish Balay Level: intermediate 2542878cb397SSatish Balay 2543bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian() 2544bf388a1fSBarry Smith M*/ 2545bf388a1fSBarry Smith 25469b94acceSBarry Smith /*@C 25479b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2548044dda88SLois Curfman McInnes location to store the matrix. 25499b94acceSBarry Smith 25503f9fe445SBarry Smith Logically Collective on SNES and Mat 2551c7afd0dbSLois Curfman McInnes 25529b94acceSBarry Smith Input Parameters: 2553c7afd0dbSLois Curfman McInnes + snes - the SNES context 2554e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 2555e5d3d808SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 2556411c0326SBarry Smith . J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details 2557c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 25580298fd71SBarry Smith Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value) 25599b94acceSBarry Smith 25609b94acceSBarry Smith Notes: 2561e5d3d808SBarry Smith If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on 256216913363SBarry Smith each matrix. 256316913363SBarry Smith 2564895c21f2SBarry Smith If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null 2565895c21f2SBarry Smith space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 2566895c21f2SBarry Smith 25678d359177SBarry Smith If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument 2568a8a26c1eSJed Brown must be a MatFDColoring. 2569a8a26c1eSJed Brown 2570c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2571c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2572c3cc8fd1SJed Brown 257336851e7fSLois Curfman McInnes Level: beginner 257436851e7fSLois Curfman McInnes 25759b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 25769b94acceSBarry Smith 2577411c0326SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J, 2578411c0326SBarry Smith SNESSetPicard(), SNESJacobianFunction 25799b94acceSBarry Smith @*/ 2580d1e9a80fSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 25819b94acceSBarry Smith { 2582dfbe8321SBarry Smith PetscErrorCode ierr; 25836cab3a1bSJed Brown DM dm; 25843a7fca6bSBarry Smith 25853a40ed3dSBarry Smith PetscFunctionBegin; 25860700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2587e5d3d808SBarry Smith if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 2588e5d3d808SBarry Smith if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 2589e5d3d808SBarry Smith if (Amat) PetscCheckSameComm(snes,1,Amat,2); 2590e5d3d808SBarry Smith if (Pmat) PetscCheckSameComm(snes,1,Pmat,3); 25916cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2592f8b49ee9SBarry Smith ierr = DMSNESSetJacobian(dm,J,ctx);CHKERRQ(ierr); 2593e5d3d808SBarry Smith if (Amat) { 2594e5d3d808SBarry Smith ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 25956bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 2596f5af7f23SKarl Rupp 2597e5d3d808SBarry Smith snes->jacobian = Amat; 25983a7fca6bSBarry Smith } 2599e5d3d808SBarry Smith if (Pmat) { 2600e5d3d808SBarry Smith ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr); 26016bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2602f5af7f23SKarl Rupp 2603e5d3d808SBarry Smith snes->jacobian_pre = Pmat; 26043a7fca6bSBarry Smith } 26053a40ed3dSBarry Smith PetscFunctionReturn(0); 26069b94acceSBarry Smith } 260762fef451SLois Curfman McInnes 2608c2aafc4cSSatish Balay /*@C 2609b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2610b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2611b4fd4287SBarry Smith 2612c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2613c7afd0dbSLois Curfman McInnes 2614b4fd4287SBarry Smith Input Parameter: 2615b4fd4287SBarry Smith . snes - the nonlinear solver context 2616b4fd4287SBarry Smith 2617b4fd4287SBarry Smith Output Parameters: 2618e5d3d808SBarry Smith + Amat - location to stash (approximate) Jacobian matrix (or NULL) 2619e5d3d808SBarry Smith . Pmat - location to stash matrix used to compute the preconditioner (or NULL) 2620411c0326SBarry Smith . J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence 26210298fd71SBarry Smith - ctx - location to stash Jacobian ctx (or NULL) 2622fee21e36SBarry Smith 262336851e7fSLois Curfman McInnes Level: advanced 262436851e7fSLois Curfman McInnes 2625411c0326SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction() 2626b4fd4287SBarry Smith @*/ 2627d1e9a80fSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 2628b4fd4287SBarry Smith { 26296cab3a1bSJed Brown PetscErrorCode ierr; 26306cab3a1bSJed Brown DM dm; 2631942e3340SBarry Smith DMSNES sdm; 26326cab3a1bSJed Brown 26333a40ed3dSBarry Smith PetscFunctionBegin; 26340700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2635e5d3d808SBarry Smith if (Amat) *Amat = snes->jacobian; 2636e5d3d808SBarry Smith if (Pmat) *Pmat = snes->jacobian_pre; 26376cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2638942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2639f8b49ee9SBarry Smith if (J) *J = sdm->ops->computejacobian; 26406cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 26413a40ed3dSBarry Smith PetscFunctionReturn(0); 2642b4fd4287SBarry Smith } 2643b4fd4287SBarry Smith 26449b94acceSBarry Smith /*@ 26459b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2646272ac6f2SLois Curfman McInnes of a nonlinear solver. 26479b94acceSBarry Smith 2648fee21e36SBarry Smith Collective on SNES 2649fee21e36SBarry Smith 2650c7afd0dbSLois Curfman McInnes Input Parameters: 265170e92668SMatthew Knepley . snes - the SNES context 2652c7afd0dbSLois Curfman McInnes 2653272ac6f2SLois Curfman McInnes Notes: 2654272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2655272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2656272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2657272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2658272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2659272ac6f2SLois Curfman McInnes 266036851e7fSLois Curfman McInnes Level: advanced 266136851e7fSLois Curfman McInnes 26629b94acceSBarry Smith .keywords: SNES, nonlinear, setup 26639b94acceSBarry Smith 26649b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 26659b94acceSBarry Smith @*/ 26667087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 26679b94acceSBarry Smith { 2668dfbe8321SBarry Smith PetscErrorCode ierr; 26696cab3a1bSJed Brown DM dm; 2670942e3340SBarry Smith DMSNES sdm; 2671c35f09e5SBarry Smith SNESLineSearch linesearch, pclinesearch; 26726e2a1849SPeter Brune void *lsprectx,*lspostctx; 26736b2b7091SBarry Smith PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*); 26746b2b7091SBarry Smith PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*); 26756e2a1849SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 26766e2a1849SPeter Brune Vec f,fpc; 26776e2a1849SPeter Brune void *funcctx; 2678d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 26791eb13d49SPeter Brune void *jacctx,*appctx; 268032b97717SPeter Brune Mat j,jpre; 26813a40ed3dSBarry Smith 26823a40ed3dSBarry Smith PetscFunctionBegin; 26830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 26844dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 26859b94acceSBarry Smith 26867adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 268704d7464bSBarry Smith ierr = SNESSetType(snes,SNESNEWTONLS);CHKERRQ(ierr); 268885385478SLisandro Dalcin } 268985385478SLisandro Dalcin 26900298fd71SBarry Smith ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr); 269158c9b817SLisandro Dalcin 26926cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2693942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2694ce94432eSBarry Smith if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object"); 269522c6f798SBarry Smith if (!sdm->ops->computejacobian) { 26968d359177SBarry Smith ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr); 269719f7a02aSBarry Smith } 26986cab3a1bSJed Brown if (!snes->vec_func) { 26996cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2700214df951SJed Brown } 2701efd51863SBarry Smith 270222d28d08SBarry Smith if (!snes->ksp) { 270322d28d08SBarry Smith ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr); 270422d28d08SBarry Smith } 2705b710008aSBarry Smith 270622d28d08SBarry Smith if (!snes->linesearch) { 27077601faf0SJed Brown ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 270822d28d08SBarry Smith } 2709ed07d7d7SPeter Brune ierr = SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction);CHKERRQ(ierr); 27109e764e56SPeter Brune 2711172a4300SPeter Brune if (snes->pc && (snes->pcside == PC_LEFT)) { 2712172a4300SPeter Brune snes->mf = PETSC_TRUE; 2713172a4300SPeter Brune snes->mf_operator = PETSC_FALSE; 2714172a4300SPeter Brune } 2715d8f46077SPeter Brune 27166e2a1849SPeter Brune if (snes->pc) { 27176e2a1849SPeter Brune /* copy the DM over */ 27186e2a1849SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 27196e2a1849SPeter Brune ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr); 27206e2a1849SPeter Brune 27216e2a1849SPeter Brune ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr); 27226e2a1849SPeter Brune ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr); 27236e2a1849SPeter Brune ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr); 272432b97717SPeter Brune ierr = SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx);CHKERRQ(ierr); 272532b97717SPeter Brune ierr = SNESSetJacobian(snes->pc,j,jpre,jac,jacctx);CHKERRQ(ierr); 27261eb13d49SPeter Brune ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr); 27271eb13d49SPeter Brune ierr = SNESSetApplicationContext(snes->pc,appctx);CHKERRQ(ierr); 27286e2a1849SPeter Brune ierr = VecDestroy(&fpc);CHKERRQ(ierr); 27296e2a1849SPeter Brune 27306e2a1849SPeter Brune /* copy the function pointers over */ 27316e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr); 27326e2a1849SPeter Brune 27336e2a1849SPeter Brune /* default to 1 iteration */ 2734140836e4SPeter Brune ierr = SNESSetTolerances(snes->pc,0.0,0.0,0.0,1,snes->pc->max_funcs);CHKERRQ(ierr); 2735a9936a0cSPeter Brune if (snes->pcside==PC_RIGHT) { 2736365a6726SPeter Brune ierr = SNESSetNormSchedule(snes->pc,SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 2737a9936a0cSPeter Brune } else { 2738365a6726SPeter Brune ierr = SNESSetNormSchedule(snes->pc,SNES_NORM_NONE);CHKERRQ(ierr); 2739a9936a0cSPeter Brune } 27406e2a1849SPeter Brune ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 27416e2a1849SPeter Brune 27426e2a1849SPeter Brune /* copy the line search context over */ 27437601faf0SJed Brown ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 27447601faf0SJed Brown ierr = SNESGetLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr); 27456b2b7091SBarry Smith ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr); 27466b2b7091SBarry Smith ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr); 27476b2b7091SBarry Smith ierr = SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);CHKERRQ(ierr); 27486b2b7091SBarry Smith ierr = SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);CHKERRQ(ierr); 27496e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 27506e2a1849SPeter Brune } 275132b97717SPeter Brune if (snes->mf) { 275232b97717SPeter Brune ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr); 275332b97717SPeter Brune } 275432b97717SPeter Brune if (snes->ops->usercompute && !snes->user) { 275532b97717SPeter Brune ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 275632b97717SPeter Brune } 27576e2a1849SPeter Brune 275837ec4e1aSPeter Brune snes->jac_iter = 0; 275937ec4e1aSPeter Brune snes->pre_iter = 0; 276037ec4e1aSPeter Brune 2761410397dcSLisandro Dalcin if (snes->ops->setup) { 2762410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2763410397dcSLisandro Dalcin } 276458c9b817SLisandro Dalcin 27656c67d002SPeter Brune if (snes->pc && (snes->pcside == PC_LEFT)) { 27666c67d002SPeter Brune if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 276755d4788fSPeter Brune ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 2768be95d8f1SBarry Smith ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC);CHKERRQ(ierr); 27696c67d002SPeter Brune } 27706c67d002SPeter Brune } 27716c67d002SPeter Brune 27727aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 27733a40ed3dSBarry Smith PetscFunctionReturn(0); 27749b94acceSBarry Smith } 27759b94acceSBarry Smith 277637596af1SLisandro Dalcin /*@ 277737596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 277837596af1SLisandro Dalcin 277937596af1SLisandro Dalcin Collective on SNES 278037596af1SLisandro Dalcin 278137596af1SLisandro Dalcin Input Parameter: 278237596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 278337596af1SLisandro Dalcin 2784d25893d9SBarry Smith Level: intermediate 2785d25893d9SBarry Smith 2786d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 278737596af1SLisandro Dalcin 278837596af1SLisandro Dalcin .keywords: SNES, destroy 278937596af1SLisandro Dalcin 279037596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 279137596af1SLisandro Dalcin @*/ 279237596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 279337596af1SLisandro Dalcin { 279437596af1SLisandro Dalcin PetscErrorCode ierr; 279537596af1SLisandro Dalcin 279637596af1SLisandro Dalcin PetscFunctionBegin; 279737596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2798d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2799d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 28000298fd71SBarry Smith snes->user = NULL; 2801d25893d9SBarry Smith } 28028a23116dSBarry Smith if (snes->pc) { 28038a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 28048a23116dSBarry Smith } 28058a23116dSBarry Smith 280637596af1SLisandro Dalcin if (snes->ops->reset) { 280737596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 280837596af1SLisandro Dalcin } 28099e764e56SPeter Brune if (snes->ksp) { 28109e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 28119e764e56SPeter Brune } 28129e764e56SPeter Brune 28139e764e56SPeter Brune if (snes->linesearch) { 2814f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 28159e764e56SPeter Brune } 28169e764e56SPeter Brune 28176bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 28186bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 28196bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 28206bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 28216bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 28226bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2823c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2824c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 2825f5af7f23SKarl Rupp 282640fdac6aSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 282740fdac6aSLawrence Mitchell 282837596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 282937596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 283037596af1SLisandro Dalcin PetscFunctionReturn(0); 283137596af1SLisandro Dalcin } 283237596af1SLisandro Dalcin 283352baeb72SSatish Balay /*@ 28349b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 28359b94acceSBarry Smith with SNESCreate(). 28369b94acceSBarry Smith 2837c7afd0dbSLois Curfman McInnes Collective on SNES 2838c7afd0dbSLois Curfman McInnes 28399b94acceSBarry Smith Input Parameter: 28409b94acceSBarry Smith . snes - the SNES context 28419b94acceSBarry Smith 284236851e7fSLois Curfman McInnes Level: beginner 284336851e7fSLois Curfman McInnes 28449b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 28459b94acceSBarry Smith 284663a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 28479b94acceSBarry Smith @*/ 28486bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 28499b94acceSBarry Smith { 28506849ba73SBarry Smith PetscErrorCode ierr; 28513a40ed3dSBarry Smith 28523a40ed3dSBarry Smith PetscFunctionBegin; 28536bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 28546bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 28556bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2856d4bb536fSBarry Smith 28576bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 28588a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 28596b8b9a38SLisandro Dalcin 2860e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 2861e04113cfSBarry Smith ierr = PetscObjectSAWsViewOff((PetscObject)*snes);CHKERRQ(ierr); 28626bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 28636d4c513bSLisandro Dalcin 28646bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 28656bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2866f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 28676b8b9a38SLisandro Dalcin 28686bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 28696bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 28706bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 28716b8b9a38SLisandro Dalcin } 28726bf464f9SBarry Smith if ((*snes)->conv_malloc) { 28736bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 28746bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 287558c9b817SLisandro Dalcin } 28766bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2877a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 28783a40ed3dSBarry Smith PetscFunctionReturn(0); 28799b94acceSBarry Smith } 28809b94acceSBarry Smith 28819b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 28829b94acceSBarry Smith 2883a8054027SBarry Smith /*@ 2884a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2885a8054027SBarry Smith 28863f9fe445SBarry Smith Logically Collective on SNES 2887a8054027SBarry Smith 2888a8054027SBarry Smith Input Parameters: 2889a8054027SBarry Smith + snes - the SNES context 2890a8054027SBarry 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 28913b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2892a8054027SBarry Smith 2893a8054027SBarry Smith Options Database Keys: 2894a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2895a8054027SBarry Smith 2896a8054027SBarry Smith Notes: 2897a8054027SBarry Smith The default is 1 2898a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2899a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2900a8054027SBarry Smith 2901a8054027SBarry Smith Level: intermediate 2902a8054027SBarry Smith 2903a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2904a8054027SBarry Smith 2905e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2906a8054027SBarry Smith 2907a8054027SBarry Smith @*/ 29087087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2909a8054027SBarry Smith { 2910a8054027SBarry Smith PetscFunctionBegin; 29110700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2912e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2913e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2914c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2915a8054027SBarry Smith snes->lagpreconditioner = lag; 2916a8054027SBarry Smith PetscFunctionReturn(0); 2917a8054027SBarry Smith } 2918a8054027SBarry Smith 2919efd51863SBarry Smith /*@ 2920efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2921efd51863SBarry Smith 2922efd51863SBarry Smith Logically Collective on SNES 2923efd51863SBarry Smith 2924efd51863SBarry Smith Input Parameters: 2925efd51863SBarry Smith + snes - the SNES context 2926efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2927efd51863SBarry Smith 2928efd51863SBarry Smith Options Database Keys: 2929efd51863SBarry Smith . -snes_grid_sequence <steps> 2930efd51863SBarry Smith 2931efd51863SBarry Smith Level: intermediate 2932efd51863SBarry Smith 2933c0df2a02SJed Brown Notes: 2934c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2935c0df2a02SJed Brown 2936efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2937efd51863SBarry Smith 2938fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetGridSequence() 2939efd51863SBarry Smith 2940efd51863SBarry Smith @*/ 2941efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2942efd51863SBarry Smith { 2943efd51863SBarry Smith PetscFunctionBegin; 2944efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2945efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2946efd51863SBarry Smith snes->gridsequence = steps; 2947efd51863SBarry Smith PetscFunctionReturn(0); 2948efd51863SBarry Smith } 2949efd51863SBarry Smith 2950fa19ca70SBarry Smith /*@ 2951fa19ca70SBarry Smith SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does 2952fa19ca70SBarry Smith 2953fa19ca70SBarry Smith Logically Collective on SNES 2954fa19ca70SBarry Smith 2955fa19ca70SBarry Smith Input Parameter: 2956fa19ca70SBarry Smith . snes - the SNES context 2957fa19ca70SBarry Smith 2958fa19ca70SBarry Smith Output Parameter: 2959fa19ca70SBarry Smith . steps - the number of refinements to do, defaults to 0 2960fa19ca70SBarry Smith 2961fa19ca70SBarry Smith Options Database Keys: 2962fa19ca70SBarry Smith . -snes_grid_sequence <steps> 2963fa19ca70SBarry Smith 2964fa19ca70SBarry Smith Level: intermediate 2965fa19ca70SBarry Smith 2966fa19ca70SBarry Smith Notes: 2967fa19ca70SBarry Smith Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2968fa19ca70SBarry Smith 2969fa19ca70SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2970fa19ca70SBarry Smith 2971fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetGridSequence() 2972fa19ca70SBarry Smith 2973fa19ca70SBarry Smith @*/ 2974fa19ca70SBarry Smith PetscErrorCode SNESGetGridSequence(SNES snes,PetscInt *steps) 2975fa19ca70SBarry Smith { 2976fa19ca70SBarry Smith PetscFunctionBegin; 2977fa19ca70SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2978fa19ca70SBarry Smith *steps = snes->gridsequence; 2979fa19ca70SBarry Smith PetscFunctionReturn(0); 2980fa19ca70SBarry Smith } 2981fa19ca70SBarry Smith 2982a8054027SBarry Smith /*@ 2983a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2984a8054027SBarry Smith 29853f9fe445SBarry Smith Not Collective 2986a8054027SBarry Smith 2987a8054027SBarry Smith Input Parameter: 2988a8054027SBarry Smith . snes - the SNES context 2989a8054027SBarry Smith 2990a8054027SBarry Smith Output Parameter: 2991a8054027SBarry 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 29923b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2993a8054027SBarry Smith 2994a8054027SBarry Smith Options Database Keys: 2995a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2996a8054027SBarry Smith 2997a8054027SBarry Smith Notes: 2998a8054027SBarry Smith The default is 1 2999a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3000a8054027SBarry Smith 3001a8054027SBarry Smith Level: intermediate 3002a8054027SBarry Smith 3003a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 3004a8054027SBarry Smith 3005a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 3006a8054027SBarry Smith 3007a8054027SBarry Smith @*/ 30087087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 3009a8054027SBarry Smith { 3010a8054027SBarry Smith PetscFunctionBegin; 30110700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3012a8054027SBarry Smith *lag = snes->lagpreconditioner; 3013a8054027SBarry Smith PetscFunctionReturn(0); 3014a8054027SBarry Smith } 3015a8054027SBarry Smith 3016e35cf81dSBarry Smith /*@ 3017e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 3018e35cf81dSBarry Smith often the preconditioner is rebuilt. 3019e35cf81dSBarry Smith 30203f9fe445SBarry Smith Logically Collective on SNES 3021e35cf81dSBarry Smith 3022e35cf81dSBarry Smith Input Parameters: 3023e35cf81dSBarry Smith + snes - the SNES context 3024e35cf81dSBarry 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 3025fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 3026e35cf81dSBarry Smith 3027e35cf81dSBarry Smith Options Database Keys: 3028e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 3029e35cf81dSBarry Smith 3030e35cf81dSBarry Smith Notes: 3031e35cf81dSBarry Smith The default is 1 3032e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3033fe3ffe1eSBarry 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 3034fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 3035e35cf81dSBarry Smith 3036e35cf81dSBarry Smith Level: intermediate 3037e35cf81dSBarry Smith 3038e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 3039e35cf81dSBarry Smith 3040e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 3041e35cf81dSBarry Smith 3042e35cf81dSBarry Smith @*/ 30437087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 3044e35cf81dSBarry Smith { 3045e35cf81dSBarry Smith PetscFunctionBegin; 30460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3047e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3048e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3049c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 3050e35cf81dSBarry Smith snes->lagjacobian = lag; 3051e35cf81dSBarry Smith PetscFunctionReturn(0); 3052e35cf81dSBarry Smith } 3053e35cf81dSBarry Smith 3054e35cf81dSBarry Smith /*@ 3055e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 3056e35cf81dSBarry Smith 30573f9fe445SBarry Smith Not Collective 3058e35cf81dSBarry Smith 3059e35cf81dSBarry Smith Input Parameter: 3060e35cf81dSBarry Smith . snes - the SNES context 3061e35cf81dSBarry Smith 3062e35cf81dSBarry Smith Output Parameter: 3063e35cf81dSBarry 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 3064e35cf81dSBarry Smith the Jacobian is built etc. 3065e35cf81dSBarry Smith 3066e35cf81dSBarry Smith Options Database Keys: 3067e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 3068e35cf81dSBarry Smith 3069e35cf81dSBarry Smith Notes: 3070e35cf81dSBarry Smith The default is 1 3071e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3072e35cf81dSBarry Smith 3073e35cf81dSBarry Smith Level: intermediate 3074e35cf81dSBarry Smith 3075e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 3076e35cf81dSBarry Smith 3077e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 3078e35cf81dSBarry Smith 3079e35cf81dSBarry Smith @*/ 30807087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 3081e35cf81dSBarry Smith { 3082e35cf81dSBarry Smith PetscFunctionBegin; 30830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3084e35cf81dSBarry Smith *lag = snes->lagjacobian; 3085e35cf81dSBarry Smith PetscFunctionReturn(0); 3086e35cf81dSBarry Smith } 3087e35cf81dSBarry Smith 308837ec4e1aSPeter Brune /*@ 308937ec4e1aSPeter Brune SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves 309037ec4e1aSPeter Brune 309137ec4e1aSPeter Brune Logically collective on SNES 309237ec4e1aSPeter Brune 309337ec4e1aSPeter Brune Input Parameter: 309437ec4e1aSPeter Brune + snes - the SNES context 30959d7e2deaSPeter Brune - flg - jacobian lagging persists if true 309637ec4e1aSPeter Brune 309737ec4e1aSPeter Brune Options Database Keys: 309837ec4e1aSPeter Brune . -snes_lag_jacobian_persists <flg> 309937ec4e1aSPeter Brune 310037ec4e1aSPeter Brune Notes: This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 310137ec4e1aSPeter Brune several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 310237ec4e1aSPeter Brune timesteps may present huge efficiency gains. 310337ec4e1aSPeter Brune 310437ec4e1aSPeter Brune Level: developer 310537ec4e1aSPeter Brune 3106be95d8f1SBarry Smith .keywords: SNES, nonlinear, lag 310737ec4e1aSPeter Brune 3108be95d8f1SBarry Smith .seealso: SNESSetLagPreconditionerPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC() 310937ec4e1aSPeter Brune 311037ec4e1aSPeter Brune @*/ 311137ec4e1aSPeter Brune PetscErrorCode SNESSetLagJacobianPersists(SNES snes,PetscBool flg) 311237ec4e1aSPeter Brune { 311337ec4e1aSPeter Brune PetscFunctionBegin; 311437ec4e1aSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 311537ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes,flg,2); 311637ec4e1aSPeter Brune snes->lagjac_persist = flg; 311737ec4e1aSPeter Brune PetscFunctionReturn(0); 311837ec4e1aSPeter Brune } 311937ec4e1aSPeter Brune 312037ec4e1aSPeter Brune /*@ 312137ec4e1aSPeter Brune SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple solves 312237ec4e1aSPeter Brune 312337ec4e1aSPeter Brune Logically Collective on SNES 312437ec4e1aSPeter Brune 312537ec4e1aSPeter Brune Input Parameter: 312637ec4e1aSPeter Brune + snes - the SNES context 31279d7e2deaSPeter Brune - flg - preconditioner lagging persists if true 312837ec4e1aSPeter Brune 312937ec4e1aSPeter Brune Options Database Keys: 313037ec4e1aSPeter Brune . -snes_lag_jacobian_persists <flg> 313137ec4e1aSPeter Brune 313237ec4e1aSPeter Brune Notes: This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 313337ec4e1aSPeter Brune by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 313437ec4e1aSPeter Brune several timesteps may present huge efficiency gains. 313537ec4e1aSPeter Brune 313637ec4e1aSPeter Brune Level: developer 313737ec4e1aSPeter Brune 3138be95d8f1SBarry Smith .keywords: SNES, nonlinear, lag 313937ec4e1aSPeter Brune 3140be95d8f1SBarry Smith .seealso: SNESSetLagJacobianPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC() 314137ec4e1aSPeter Brune 314237ec4e1aSPeter Brune @*/ 314337ec4e1aSPeter Brune PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg) 314437ec4e1aSPeter Brune { 314537ec4e1aSPeter Brune PetscFunctionBegin; 314637ec4e1aSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 314737ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes,flg,2); 314837ec4e1aSPeter Brune snes->lagpre_persist = flg; 314937ec4e1aSPeter Brune PetscFunctionReturn(0); 315037ec4e1aSPeter Brune } 315137ec4e1aSPeter Brune 31529b94acceSBarry Smith /*@ 3153d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 31549b94acceSBarry Smith 31553f9fe445SBarry Smith Logically Collective on SNES 3156c7afd0dbSLois Curfman McInnes 31579b94acceSBarry Smith Input Parameters: 3158c7afd0dbSLois Curfman McInnes + snes - the SNES context 315970441072SBarry Smith . abstol - absolute convergence tolerance 316033174efeSLois Curfman McInnes . rtol - relative convergence tolerance 31615358d0d4SBarry Smith . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 316233174efeSLois Curfman McInnes . maxit - maximum number of iterations 3163c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 3164fee21e36SBarry Smith 316533174efeSLois Curfman McInnes Options Database Keys: 316670441072SBarry Smith + -snes_atol <abstol> - Sets abstol 3167c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 3168c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 3169c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 3170c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 31719b94acceSBarry Smith 3172d7a720efSLois Curfman McInnes Notes: 31739b94acceSBarry Smith The default maximum number of iterations is 50. 31749b94acceSBarry Smith The default maximum number of function evaluations is 1000. 31759b94acceSBarry Smith 317636851e7fSLois Curfman McInnes Level: intermediate 317736851e7fSLois Curfman McInnes 317833174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 31799b94acceSBarry Smith 3180e4d06f11SPatrick Farrell .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance() 31819b94acceSBarry Smith @*/ 31827087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 31839b94acceSBarry Smith { 31843a40ed3dSBarry Smith PetscFunctionBegin; 31850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3186c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 3187c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 3188c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 3189c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 3190c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 3191c5eb9154SBarry Smith 3192ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 319357622a8eSBarry Smith if (abstol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol); 3194ab54825eSJed Brown snes->abstol = abstol; 3195ab54825eSJed Brown } 3196ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 319757622a8eSBarry 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); 3198ab54825eSJed Brown snes->rtol = rtol; 3199ab54825eSJed Brown } 3200ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 320157622a8eSBarry Smith if (stol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol); 3202c60f73f4SPeter Brune snes->stol = stol; 3203ab54825eSJed Brown } 3204ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 3205ce94432eSBarry Smith if (maxit < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 3206ab54825eSJed Brown snes->max_its = maxit; 3207ab54825eSJed Brown } 3208ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 3209ce94432eSBarry Smith if (maxf < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 3210ab54825eSJed Brown snes->max_funcs = maxf; 3211ab54825eSJed Brown } 321288976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 32133a40ed3dSBarry Smith PetscFunctionReturn(0); 32149b94acceSBarry Smith } 32159b94acceSBarry Smith 3216e4d06f11SPatrick Farrell /*@ 3217e4d06f11SPatrick Farrell SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test. 3218e4d06f11SPatrick Farrell 3219e4d06f11SPatrick Farrell Logically Collective on SNES 3220e4d06f11SPatrick Farrell 3221e4d06f11SPatrick Farrell Input Parameters: 3222e4d06f11SPatrick Farrell + snes - the SNES context 3223e4d06f11SPatrick Farrell - divtol - the divergence tolerance. Use -1 to deactivate the test. 3224e4d06f11SPatrick Farrell 3225e4d06f11SPatrick Farrell Options Database Keys: 3226e4d06f11SPatrick Farrell + -snes_divergence_tolerance <divtol> - Sets divtol 3227e4d06f11SPatrick Farrell 3228e4d06f11SPatrick Farrell Notes: 3229e4d06f11SPatrick Farrell The default divergence tolerance is 1e4. 3230e4d06f11SPatrick Farrell 3231e4d06f11SPatrick Farrell Level: intermediate 3232e4d06f11SPatrick Farrell 3233e4d06f11SPatrick Farrell .keywords: SNES, nonlinear, set, divergence, tolerance 3234e4d06f11SPatrick Farrell 3235e4d06f11SPatrick Farrell .seealso: SNESSetTolerances(), SNESGetDivergenceTolerance 3236e4d06f11SPatrick Farrell @*/ 3237e4d06f11SPatrick Farrell PetscErrorCode SNESSetDivergenceTolerance(SNES snes,PetscReal divtol) 3238e4d06f11SPatrick Farrell { 3239e4d06f11SPatrick Farrell PetscFunctionBegin; 3240e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3241e4d06f11SPatrick Farrell PetscValidLogicalCollectiveReal(snes,divtol,2); 3242e4d06f11SPatrick Farrell 3243e4d06f11SPatrick Farrell if (divtol != PETSC_DEFAULT) { 3244e4d06f11SPatrick Farrell snes->divtol = divtol; 3245e4d06f11SPatrick Farrell } 3246e4d06f11SPatrick Farrell else { 3247e4d06f11SPatrick Farrell snes->divtol = 1.0e4; 3248e4d06f11SPatrick Farrell } 3249e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3250e4d06f11SPatrick Farrell } 3251e4d06f11SPatrick Farrell 32529b94acceSBarry Smith /*@ 325333174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 325433174efeSLois Curfman McInnes 3255c7afd0dbSLois Curfman McInnes Not Collective 3256c7afd0dbSLois Curfman McInnes 325733174efeSLois Curfman McInnes Input Parameters: 3258c7afd0dbSLois Curfman McInnes + snes - the SNES context 325985385478SLisandro Dalcin . atol - absolute convergence tolerance 326033174efeSLois Curfman McInnes . rtol - relative convergence tolerance 326133174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 326233174efeSLois Curfman McInnes of the change in the solution between steps 326333174efeSLois Curfman McInnes . maxit - maximum number of iterations 3264c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 3265fee21e36SBarry Smith 326633174efeSLois Curfman McInnes Notes: 32670298fd71SBarry Smith The user can specify NULL for any parameter that is not needed. 326833174efeSLois Curfman McInnes 326936851e7fSLois Curfman McInnes Level: intermediate 327036851e7fSLois Curfman McInnes 327133174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 327233174efeSLois Curfman McInnes 327333174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 327433174efeSLois Curfman McInnes @*/ 32757087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 327633174efeSLois Curfman McInnes { 32773a40ed3dSBarry Smith PetscFunctionBegin; 32780700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 327985385478SLisandro Dalcin if (atol) *atol = snes->abstol; 328033174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 3281c60f73f4SPeter Brune if (stol) *stol = snes->stol; 328233174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 328333174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 32843a40ed3dSBarry Smith PetscFunctionReturn(0); 328533174efeSLois Curfman McInnes } 328633174efeSLois Curfman McInnes 3287e4d06f11SPatrick Farrell /*@ 3288e4d06f11SPatrick Farrell SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test. 3289e4d06f11SPatrick Farrell 3290e4d06f11SPatrick Farrell Not Collective 3291e4d06f11SPatrick Farrell 3292e4d06f11SPatrick Farrell Input Parameters: 3293e4d06f11SPatrick Farrell + snes - the SNES context 3294e4d06f11SPatrick Farrell - divtol - divergence tolerance 3295e4d06f11SPatrick Farrell 3296e4d06f11SPatrick Farrell Level: intermediate 3297e4d06f11SPatrick Farrell 3298e4d06f11SPatrick Farrell .keywords: SNES, nonlinear, get, divergence, tolerance 3299e4d06f11SPatrick Farrell 3300e4d06f11SPatrick Farrell .seealso: SNESSetDivergenceTolerance() 3301e4d06f11SPatrick Farrell @*/ 3302e4d06f11SPatrick Farrell PetscErrorCode SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol) 3303e4d06f11SPatrick Farrell { 3304e4d06f11SPatrick Farrell PetscFunctionBegin; 3305e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3306e4d06f11SPatrick Farrell if (divtol) *divtol = snes->divtol; 3307e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3308e4d06f11SPatrick Farrell } 3309e4d06f11SPatrick Farrell 331033174efeSLois Curfman McInnes /*@ 33119b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 33129b94acceSBarry Smith 33133f9fe445SBarry Smith Logically Collective on SNES 3314fee21e36SBarry Smith 3315c7afd0dbSLois Curfman McInnes Input Parameters: 3316c7afd0dbSLois Curfman McInnes + snes - the SNES context 3317c7afd0dbSLois Curfman McInnes - tol - tolerance 3318c7afd0dbSLois Curfman McInnes 33199b94acceSBarry Smith Options Database Key: 3320c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 33219b94acceSBarry Smith 332236851e7fSLois Curfman McInnes Level: intermediate 332336851e7fSLois Curfman McInnes 33249b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 33259b94acceSBarry Smith 33262492ecdbSBarry Smith .seealso: SNESSetTolerances() 33279b94acceSBarry Smith @*/ 33287087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 33299b94acceSBarry Smith { 33303a40ed3dSBarry Smith PetscFunctionBegin; 33310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3332c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 33339b94acceSBarry Smith snes->deltatol = tol; 33343a40ed3dSBarry Smith PetscFunctionReturn(0); 33359b94acceSBarry Smith } 33369b94acceSBarry Smith 3337df9fa365SBarry Smith /* 3338df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 3339df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 3340df9fa365SBarry Smith macros instead of functions 3341df9fa365SBarry Smith */ 3342d96771aaSLisandro Dalcin PetscErrorCode SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx) 3343ce1608b8SBarry Smith { 3344dfbe8321SBarry Smith PetscErrorCode ierr; 3345ce1608b8SBarry Smith 3346ce1608b8SBarry Smith PetscFunctionBegin; 33470700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3348d96771aaSLisandro Dalcin ierr = KSPMonitorLGResidualNorm((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 3349ce1608b8SBarry Smith PetscFunctionReturn(0); 3350ce1608b8SBarry Smith } 3351ce1608b8SBarry Smith 3352d96771aaSLisandro Dalcin PetscErrorCode SNESMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *lgctx) 3353df9fa365SBarry Smith { 3354dfbe8321SBarry Smith PetscErrorCode ierr; 3355df9fa365SBarry Smith 3356df9fa365SBarry Smith PetscFunctionBegin; 3357d96771aaSLisandro Dalcin ierr = KSPMonitorLGResidualNormCreate(comm,host,label,x,y,m,n,lgctx);CHKERRQ(ierr); 3358df9fa365SBarry Smith PetscFunctionReturn(0); 3359df9fa365SBarry Smith } 3360df9fa365SBarry Smith 33616ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 33626ba87a44SLisandro Dalcin 33637087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 3364b271bb04SBarry Smith { 3365b271bb04SBarry Smith PetscDrawLG lg; 3366b271bb04SBarry Smith PetscErrorCode ierr; 3367b271bb04SBarry Smith PetscReal x,y,per; 3368b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 3369b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 3370b271bb04SBarry Smith PetscDraw draw; 3371b271bb04SBarry Smith 3372459f5d12SBarry Smith PetscFunctionBegin; 33734d4332d5SBarry Smith PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4); 3374b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 3375b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3376b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3377b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 3378b271bb04SBarry Smith x = (PetscReal)n; 337977b4d14cSPeter Brune if (rnorm > 0.0) y = PetscLog10Real(rnorm); 338094c9c6d3SKarl Rupp else y = -15.0; 3381b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 33826934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3383b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 33846934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3385b271bb04SBarry Smith } 3386b271bb04SBarry Smith 3387b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 3388b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3389b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3390b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 3391b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 3392b271bb04SBarry Smith x = (PetscReal)n; 3393b271bb04SBarry Smith y = 100.0*per; 3394b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 33956934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3396b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 33976934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3398b271bb04SBarry Smith } 3399b271bb04SBarry Smith 3400b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 3401b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3402b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3403b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 3404b271bb04SBarry Smith x = (PetscReal)n; 3405b271bb04SBarry Smith y = (prev - rnorm)/prev; 3406b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 34076934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3408b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 34096934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3410b271bb04SBarry Smith } 3411b271bb04SBarry Smith 3412b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 3413b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3414b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3415b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 3416b271bb04SBarry Smith x = (PetscReal)n; 3417b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 3418b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 3419b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3420b271bb04SBarry Smith } 34216934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3422b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 34236934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3424b271bb04SBarry Smith } 3425b271bb04SBarry Smith prev = rnorm; 3426b271bb04SBarry Smith PetscFunctionReturn(0); 3427b271bb04SBarry Smith } 3428b271bb04SBarry Smith 3429228d79bcSJed Brown /*@ 3430228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 3431228d79bcSJed Brown 3432228d79bcSJed Brown Collective on SNES 3433228d79bcSJed Brown 3434228d79bcSJed Brown Input Parameters: 3435228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 3436228d79bcSJed Brown . iter - iteration number 3437228d79bcSJed Brown - rnorm - relative norm of the residual 3438228d79bcSJed Brown 3439228d79bcSJed Brown Notes: 3440228d79bcSJed Brown This routine is called by the SNES implementations. 3441228d79bcSJed Brown It does not typically need to be called by the user. 3442228d79bcSJed Brown 3443228d79bcSJed Brown Level: developer 3444228d79bcSJed Brown 3445228d79bcSJed Brown .seealso: SNESMonitorSet() 3446228d79bcSJed Brown @*/ 34477a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 34487a03ce2fSLisandro Dalcin { 34497a03ce2fSLisandro Dalcin PetscErrorCode ierr; 34507a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 34517a03ce2fSLisandro Dalcin 34527a03ce2fSLisandro Dalcin PetscFunctionBegin; 34535edff71fSBarry Smith ierr = VecLockPush(snes->vec_sol);CHKERRQ(ierr); 34547a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 34557a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 34567a03ce2fSLisandro Dalcin } 34575edff71fSBarry Smith ierr = VecLockPop(snes->vec_sol);CHKERRQ(ierr); 34587a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 34597a03ce2fSLisandro Dalcin } 34607a03ce2fSLisandro Dalcin 34619b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 34629b94acceSBarry Smith 3463bf388a1fSBarry Smith /*MC 3464bf388a1fSBarry Smith SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver 3465bf388a1fSBarry Smith 3466bf388a1fSBarry Smith Synopsis: 3467aaa7dc30SBarry Smith #include <petscsnes.h> 3468bf388a1fSBarry Smith $ PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3469bf388a1fSBarry Smith 3470bf388a1fSBarry Smith + snes - the SNES context 3471bf388a1fSBarry Smith . its - iteration number 3472bf388a1fSBarry Smith . norm - 2-norm function value (may be estimated) 3473bf388a1fSBarry Smith - mctx - [optional] monitoring context 3474bf388a1fSBarry Smith 3475878cb397SSatish Balay Level: advanced 3476878cb397SSatish Balay 3477bf388a1fSBarry Smith .seealso: SNESMonitorSet(), SNESMonitorGet() 3478bf388a1fSBarry Smith M*/ 3479bf388a1fSBarry Smith 34809b94acceSBarry Smith /*@C 3481a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 34829b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 34839b94acceSBarry Smith progress. 34849b94acceSBarry Smith 34853f9fe445SBarry Smith Logically Collective on SNES 3486fee21e36SBarry Smith 3487c7afd0dbSLois Curfman McInnes Input Parameters: 3488c7afd0dbSLois Curfman McInnes + snes - the SNES context 34896e4dcb14SBarry Smith . f - the monitor function, see SNESMonitorFunction for the calling sequence 3490b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 34910298fd71SBarry Smith monitor routine (use NULL if no context is desired) 3492b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 34930298fd71SBarry Smith (may be NULL) 34949b94acceSBarry Smith 34959665c990SLois Curfman McInnes Options Database Keys: 3496a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 34974619e776SBarry Smith . -snes_monitor_lg_residualnorm - sets line graph monitor, 3498a6570f20SBarry Smith uses SNESMonitorLGCreate() 3499cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 3500c7afd0dbSLois Curfman McInnes been hardwired into a code by 3501a6570f20SBarry Smith calls to SNESMonitorSet(), but 3502c7afd0dbSLois Curfman McInnes does not cancel those set via 3503c7afd0dbSLois Curfman McInnes the options database. 35049665c990SLois Curfman McInnes 3505639f9d9dSBarry Smith Notes: 35066bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3507a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 35086bc08f3fSLois Curfman McInnes order in which they were set. 3509639f9d9dSBarry Smith 3510025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 3511025f1a04SBarry Smith 351236851e7fSLois Curfman McInnes Level: intermediate 351336851e7fSLois Curfman McInnes 35149b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 35159b94acceSBarry Smith 3516bf388a1fSBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction 35179b94acceSBarry Smith @*/ 35186e4dcb14SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 35199b94acceSBarry Smith { 3520b90d0a6eSBarry Smith PetscInt i; 3521649052a6SBarry Smith PetscErrorCode ierr; 352278064530SBarry Smith PetscBool identical; 3523b90d0a6eSBarry Smith 35243a40ed3dSBarry Smith PetscFunctionBegin; 35250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3526b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 352778064530SBarry Smith ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical);CHKERRQ(ierr); 352878064530SBarry Smith if (identical) PetscFunctionReturn(0); 3529649052a6SBarry Smith } 353078064530SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 35316e4dcb14SBarry Smith snes->monitor[snes->numbermonitors] = f; 3532b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3533639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 35343a40ed3dSBarry Smith PetscFunctionReturn(0); 35359b94acceSBarry Smith } 35369b94acceSBarry Smith 3537a278d85bSSatish Balay /*@ 3538a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 35395cd90555SBarry Smith 35403f9fe445SBarry Smith Logically Collective on SNES 3541c7afd0dbSLois Curfman McInnes 35425cd90555SBarry Smith Input Parameters: 35435cd90555SBarry Smith . snes - the SNES context 35445cd90555SBarry Smith 35451a480d89SAdministrator Options Database Key: 3546a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3547a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3548c7afd0dbSLois Curfman McInnes set via the options database 35495cd90555SBarry Smith 35505cd90555SBarry Smith Notes: 35515cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 35525cd90555SBarry Smith 355336851e7fSLois Curfman McInnes Level: intermediate 355436851e7fSLois Curfman McInnes 35555cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 35565cd90555SBarry Smith 3557a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 35585cd90555SBarry Smith @*/ 35597087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 35605cd90555SBarry Smith { 3561d952e501SBarry Smith PetscErrorCode ierr; 3562d952e501SBarry Smith PetscInt i; 3563d952e501SBarry Smith 35645cd90555SBarry Smith PetscFunctionBegin; 35650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3566d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 3567d952e501SBarry Smith if (snes->monitordestroy[i]) { 35683c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3569d952e501SBarry Smith } 3570d952e501SBarry Smith } 35715cd90555SBarry Smith snes->numbermonitors = 0; 35725cd90555SBarry Smith PetscFunctionReturn(0); 35735cd90555SBarry Smith } 35745cd90555SBarry Smith 3575bf388a1fSBarry Smith /*MC 3576bf388a1fSBarry Smith SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 3577bf388a1fSBarry Smith 3578bf388a1fSBarry Smith Synopsis: 3579aaa7dc30SBarry Smith #include <petscsnes.h> 3580bf388a1fSBarry Smith $ PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3581bf388a1fSBarry Smith 3582bf388a1fSBarry Smith + snes - the SNES context 3583bf388a1fSBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3584bf388a1fSBarry Smith . cctx - [optional] convergence context 3585bf388a1fSBarry Smith . reason - reason for convergence/divergence 3586bf388a1fSBarry Smith . xnorm - 2-norm of current iterate 3587bf388a1fSBarry Smith . gnorm - 2-norm of current step 3588bf388a1fSBarry Smith - f - 2-norm of function 3589bf388a1fSBarry Smith 3590878cb397SSatish Balay Level: intermediate 3591bf388a1fSBarry Smith 3592bf388a1fSBarry Smith .seealso: SNESSetConvergenceTest(), SNESGetConvergenceTest() 3593bf388a1fSBarry Smith M*/ 3594bf388a1fSBarry Smith 35959b94acceSBarry Smith /*@C 35969b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 35979b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 35989b94acceSBarry Smith 35993f9fe445SBarry Smith Logically Collective on SNES 3600fee21e36SBarry Smith 3601c7afd0dbSLois Curfman McInnes Input Parameters: 3602c7afd0dbSLois Curfman McInnes + snes - the SNES context 3603bf388a1fSBarry Smith . SNESConvergenceTestFunction - routine to test for convergence 36040298fd71SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be NULL) 36050298fd71SBarry Smith - destroy - [optional] destructor for the context (may be NULL; NULL_FUNCTION in Fortran) 36069b94acceSBarry Smith 360736851e7fSLois Curfman McInnes Level: advanced 360836851e7fSLois Curfman McInnes 36099b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 36109b94acceSBarry Smith 3611e2a6519dSDmitry Karpeev .seealso: SNESConvergedDefault(), SNESConvergedSkip(), SNESConvergenceTestFunction 36129b94acceSBarry Smith @*/ 3613bf388a1fSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 36149b94acceSBarry Smith { 36157f7931b9SBarry Smith PetscErrorCode ierr; 36167f7931b9SBarry Smith 36173a40ed3dSBarry Smith PetscFunctionBegin; 36180700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3619e2a6519dSDmitry Karpeev if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 36207f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 36217f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 36227f7931b9SBarry Smith } 3623bf388a1fSBarry Smith snes->ops->converged = SNESConvergenceTestFunction; 36247f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 362585385478SLisandro Dalcin snes->cnvP = cctx; 36263a40ed3dSBarry Smith PetscFunctionReturn(0); 36279b94acceSBarry Smith } 36289b94acceSBarry Smith 362952baeb72SSatish Balay /*@ 3630184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3631184914b5SBarry Smith 3632184914b5SBarry Smith Not Collective 3633184914b5SBarry Smith 3634184914b5SBarry Smith Input Parameter: 3635184914b5SBarry Smith . snes - the SNES context 3636184914b5SBarry Smith 3637184914b5SBarry Smith Output Parameter: 36384d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3639184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 3640184914b5SBarry Smith 36416a4d7782SBarry Smith Options Database: 36426a4d7782SBarry Smith . -snes_converged_reason - prints the reason to standard out 36436a4d7782SBarry Smith 3644184914b5SBarry Smith Level: intermediate 3645184914b5SBarry Smith 36466a4d7782SBarry Smith Notes: Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING. 3647184914b5SBarry Smith 3648184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 3649184914b5SBarry Smith 365033866048SMatthew G. Knepley .seealso: SNESSetConvergenceTest(), SNESSetConvergedReason(), SNESConvergedReason 3651184914b5SBarry Smith @*/ 36527087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3653184914b5SBarry Smith { 3654184914b5SBarry Smith PetscFunctionBegin; 36550700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36564482741eSBarry Smith PetscValidPointer(reason,2); 3657184914b5SBarry Smith *reason = snes->reason; 3658184914b5SBarry Smith PetscFunctionReturn(0); 3659184914b5SBarry Smith } 3660184914b5SBarry Smith 366133866048SMatthew G. Knepley /*@ 366233866048SMatthew G. Knepley SNESSetConvergedReason - Sets the reason the SNES iteration was stopped. 366333866048SMatthew G. Knepley 366433866048SMatthew G. Knepley Not Collective 366533866048SMatthew G. Knepley 366633866048SMatthew G. Knepley Input Parameters: 366733866048SMatthew G. Knepley + snes - the SNES context 366833866048SMatthew G. Knepley - reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 366933866048SMatthew G. Knepley manual pages for the individual convergence tests for complete lists 367033866048SMatthew G. Knepley 367133866048SMatthew G. Knepley Level: intermediate 367233866048SMatthew G. Knepley 367333866048SMatthew G. Knepley .keywords: SNES, nonlinear, set, convergence, test 367433866048SMatthew G. Knepley .seealso: SNESGetConvergedReason(), SNESSetConvergenceTest(), SNESConvergedReason 367533866048SMatthew G. Knepley @*/ 367633866048SMatthew G. Knepley PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason) 367733866048SMatthew G. Knepley { 367833866048SMatthew G. Knepley PetscFunctionBegin; 367933866048SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 368033866048SMatthew G. Knepley snes->reason = reason; 368133866048SMatthew G. Knepley PetscFunctionReturn(0); 368233866048SMatthew G. Knepley } 368333866048SMatthew G. Knepley 3684c9005455SLois Curfman McInnes /*@ 3685c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3686c9005455SLois Curfman McInnes 36873f9fe445SBarry Smith Logically Collective on SNES 3688fee21e36SBarry Smith 3689c7afd0dbSLois Curfman McInnes Input Parameters: 3690c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 36918c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3692cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3693758f92a0SBarry Smith . na - size of a and its 369464731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3695758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3696c7afd0dbSLois Curfman McInnes 3697308dcc3eSBarry Smith Notes: 36980298fd71SBarry Smith If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3699308dcc3eSBarry Smith default array of length 10000 is allocated. 3700308dcc3eSBarry Smith 3701c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3702c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3703c9005455SLois Curfman McInnes during the section of code that is being timed. 3704c9005455SLois Curfman McInnes 370536851e7fSLois Curfman McInnes Level: intermediate 370636851e7fSLois Curfman McInnes 3707c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3708758f92a0SBarry Smith 370908405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3710758f92a0SBarry Smith 3711c9005455SLois Curfman McInnes @*/ 37127087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3713c9005455SLois Curfman McInnes { 3714308dcc3eSBarry Smith PetscErrorCode ierr; 3715308dcc3eSBarry Smith 37163a40ed3dSBarry Smith PetscFunctionBegin; 37170700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37187a1ec6d4SBarry Smith if (a) PetscValidScalarPointer(a,2); 3719a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 37207a1ec6d4SBarry Smith if (!a) { 3721308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 37227fdeb8b9SBarry Smith ierr = PetscCalloc1(na,&a);CHKERRQ(ierr); 37237fdeb8b9SBarry Smith ierr = PetscCalloc1(na,&its);CHKERRQ(ierr); 3724f5af7f23SKarl Rupp 3725308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3726308dcc3eSBarry Smith } 3727c9005455SLois Curfman McInnes snes->conv_hist = a; 3728758f92a0SBarry Smith snes->conv_hist_its = its; 3729758f92a0SBarry Smith snes->conv_hist_max = na; 3730a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3731758f92a0SBarry Smith snes->conv_hist_reset = reset; 3732758f92a0SBarry Smith PetscFunctionReturn(0); 3733758f92a0SBarry Smith } 3734758f92a0SBarry Smith 3735308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3736c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3737c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 373899e0435eSBarry Smith 37398cc058d9SJed Brown PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3740308dcc3eSBarry Smith { 3741308dcc3eSBarry Smith mxArray *mat; 3742308dcc3eSBarry Smith PetscInt i; 3743308dcc3eSBarry Smith PetscReal *ar; 3744308dcc3eSBarry Smith 3745308dcc3eSBarry Smith PetscFunctionBegin; 3746308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3747308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3748f5af7f23SKarl Rupp for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 3749308dcc3eSBarry Smith PetscFunctionReturn(mat); 3750308dcc3eSBarry Smith } 3751308dcc3eSBarry Smith #endif 3752308dcc3eSBarry Smith 37530c4c9dddSBarry Smith /*@C 3754758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3755758f92a0SBarry Smith 37563f9fe445SBarry Smith Not Collective 3757758f92a0SBarry Smith 3758758f92a0SBarry Smith Input Parameter: 3759758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3760758f92a0SBarry Smith 3761758f92a0SBarry Smith Output Parameters: 3762758f92a0SBarry Smith . a - array to hold history 3763758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3764758f92a0SBarry Smith negative if not converged) for each solve. 3765758f92a0SBarry Smith - na - size of a and its 3766758f92a0SBarry Smith 3767758f92a0SBarry Smith Notes: 3768758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3769758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3770758f92a0SBarry Smith 3771758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3772758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3773758f92a0SBarry Smith during the section of code that is being timed. 3774758f92a0SBarry Smith 3775758f92a0SBarry Smith Level: intermediate 3776758f92a0SBarry Smith 3777758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3778758f92a0SBarry Smith 3779758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3780758f92a0SBarry Smith 3781758f92a0SBarry Smith @*/ 37827087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3783758f92a0SBarry Smith { 3784758f92a0SBarry Smith PetscFunctionBegin; 37850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3786758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3787758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3788758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 37893a40ed3dSBarry Smith PetscFunctionReturn(0); 3790c9005455SLois Curfman McInnes } 3791c9005455SLois Curfman McInnes 3792ac226902SBarry Smith /*@C 379376b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3794eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 37957e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 379676b2cf59SMatthew Knepley 37973f9fe445SBarry Smith Logically Collective on SNES 379876b2cf59SMatthew Knepley 379976b2cf59SMatthew Knepley Input Parameters: 380076b2cf59SMatthew Knepley . snes - The nonlinear solver context 380176b2cf59SMatthew Knepley . func - The function 380276b2cf59SMatthew Knepley 380376b2cf59SMatthew Knepley Calling sequence of func: 3804b5d30489SBarry Smith . func (SNES snes, PetscInt step); 380576b2cf59SMatthew Knepley 380676b2cf59SMatthew Knepley . step - The current step of the iteration 380776b2cf59SMatthew Knepley 3808fe97e370SBarry Smith Level: advanced 3809fe97e370SBarry Smith 3810fe97e370SBarry 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() 3811fe97e370SBarry Smith This is not used by most users. 381276b2cf59SMatthew Knepley 381376b2cf59SMatthew Knepley .keywords: SNES, update 3814b5d30489SBarry Smith 38158d359177SBarry Smith .seealso SNESSetJacobian(), SNESSolve() 381676b2cf59SMatthew Knepley @*/ 38177087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 381876b2cf59SMatthew Knepley { 381976b2cf59SMatthew Knepley PetscFunctionBegin; 38200700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3821e7788613SBarry Smith snes->ops->update = func; 382276b2cf59SMatthew Knepley PetscFunctionReturn(0); 382376b2cf59SMatthew Knepley } 382476b2cf59SMatthew Knepley 38259b94acceSBarry Smith /* 38269b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 38279b94acceSBarry Smith positive parameter delta. 38289b94acceSBarry Smith 38299b94acceSBarry Smith Input Parameters: 3830c7afd0dbSLois Curfman McInnes + snes - the SNES context 38319b94acceSBarry Smith . y - approximate solution of linear system 38329b94acceSBarry Smith . fnorm - 2-norm of current function 3833c7afd0dbSLois Curfman McInnes - delta - trust region size 38349b94acceSBarry Smith 38359b94acceSBarry Smith Output Parameters: 3836c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 38379b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 38389b94acceSBarry Smith region, and exceeds zero otherwise. 3839c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 38409b94acceSBarry Smith 38419b94acceSBarry Smith Note: 384204d7464bSBarry Smith For non-trust region methods such as SNESNEWTONLS, the parameter delta 38439b94acceSBarry Smith is set to be the maximum allowable step size. 38449b94acceSBarry Smith 38459b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 38469b94acceSBarry Smith */ 3847dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 38489b94acceSBarry Smith { 3849064f8208SBarry Smith PetscReal nrm; 3850ea709b57SSatish Balay PetscScalar cnorm; 3851dfbe8321SBarry Smith PetscErrorCode ierr; 38523a40ed3dSBarry Smith 38533a40ed3dSBarry Smith PetscFunctionBegin; 38540700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 38550700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3856c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3857184914b5SBarry Smith 3858064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3859064f8208SBarry Smith if (nrm > *delta) { 3860064f8208SBarry Smith nrm = *delta/nrm; 3861064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3862064f8208SBarry Smith cnorm = nrm; 38632dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 38649b94acceSBarry Smith *ynorm = *delta; 38659b94acceSBarry Smith } else { 38669b94acceSBarry Smith *gpnorm = 0.0; 3867064f8208SBarry Smith *ynorm = nrm; 38689b94acceSBarry Smith } 38693a40ed3dSBarry Smith PetscFunctionReturn(0); 38709b94acceSBarry Smith } 38719b94acceSBarry Smith 38722a359c20SBarry Smith /*@ 38732a359c20SBarry Smith SNESReasonView - Displays the reason a SNES solve converged or diverged to a viewer 38742a359c20SBarry Smith 38752a359c20SBarry Smith Collective on SNES 38762a359c20SBarry Smith 38772a359c20SBarry Smith Parameter: 38782a359c20SBarry Smith + snes - iterative context obtained from SNESCreate() 38792a359c20SBarry Smith - viewer - the viewer to display the reason 38802a359c20SBarry Smith 38812a359c20SBarry Smith 38822a359c20SBarry Smith Options Database Keys: 38832a359c20SBarry Smith . -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 38842a359c20SBarry Smith 38852a359c20SBarry Smith Level: beginner 38862a359c20SBarry Smith 38872a359c20SBarry Smith .keywords: SNES, solve, linear system 38882a359c20SBarry Smith 38892a359c20SBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault() 38902a359c20SBarry Smith 38912a359c20SBarry Smith @*/ 38922a359c20SBarry Smith PetscErrorCode SNESReasonView(SNES snes,PetscViewer viewer) 38932a359c20SBarry Smith { 38942a359c20SBarry Smith PetscErrorCode ierr; 38952a359c20SBarry Smith PetscBool isAscii; 38962a359c20SBarry Smith 38972a359c20SBarry Smith PetscFunctionBegin; 38982a359c20SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);CHKERRQ(ierr); 38992a359c20SBarry Smith if (isAscii) { 39002a359c20SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 39012a359c20SBarry Smith if (snes->reason > 0) { 39022a359c20SBarry Smith if (((PetscObject) snes)->prefix) { 39032a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 39042a359c20SBarry Smith } else { 39052a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 39062a359c20SBarry Smith } 39072a359c20SBarry Smith } else { 39082a359c20SBarry Smith if (((PetscObject) snes)->prefix) { 39092a359c20SBarry 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); 39102a359c20SBarry Smith } else { 39112a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 39122a359c20SBarry Smith } 39132a359c20SBarry Smith } 39142a359c20SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 39152a359c20SBarry Smith } 39162a359c20SBarry Smith PetscFunctionReturn(0); 39172a359c20SBarry Smith } 39182a359c20SBarry Smith 39192a359c20SBarry Smith /*@C 39202a359c20SBarry Smith SNESReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed. 39212a359c20SBarry Smith 39222a359c20SBarry Smith Collective on SNES 39232a359c20SBarry Smith 39242a359c20SBarry Smith Input Parameters: 39252a359c20SBarry Smith . snes - the SNES object 39262a359c20SBarry Smith 39272a359c20SBarry Smith Level: intermediate 39282a359c20SBarry Smith 39292a359c20SBarry Smith @*/ 39302a359c20SBarry Smith PetscErrorCode SNESReasonViewFromOptions(SNES snes) 39312a359c20SBarry Smith { 39322a359c20SBarry Smith PetscErrorCode ierr; 39332a359c20SBarry Smith PetscViewer viewer; 39342a359c20SBarry Smith PetscBool flg; 39352a359c20SBarry Smith static PetscBool incall = PETSC_FALSE; 39362a359c20SBarry Smith PetscViewerFormat format; 39372a359c20SBarry Smith 39382a359c20SBarry Smith PetscFunctionBegin; 39392a359c20SBarry Smith if (incall) PetscFunctionReturn(0); 39402a359c20SBarry Smith incall = PETSC_TRUE; 39412a359c20SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg);CHKERRQ(ierr); 39422a359c20SBarry Smith if (flg) { 39432a359c20SBarry Smith ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 39442a359c20SBarry Smith ierr = SNESReasonView(snes,viewer);CHKERRQ(ierr); 39452a359c20SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 39462a359c20SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 39472a359c20SBarry Smith } 39482a359c20SBarry Smith incall = PETSC_FALSE; 39492a359c20SBarry Smith PetscFunctionReturn(0); 39502a359c20SBarry Smith } 39512a359c20SBarry Smith 39526ce558aeSBarry Smith /*@C 3953f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3954f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 39559b94acceSBarry Smith 3956c7afd0dbSLois Curfman McInnes Collective on SNES 3957c7afd0dbSLois Curfman McInnes 3958b2002411SLois Curfman McInnes Input Parameters: 3959c7afd0dbSLois Curfman McInnes + snes - the SNES context 39600298fd71SBarry Smith . b - the constant part of the equation F(x) = b, or NULL to use zero. 396185385478SLisandro Dalcin - x - the solution vector. 39629b94acceSBarry Smith 3963b2002411SLois Curfman McInnes Notes: 39648ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 39658ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 39668ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 39678ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 39688ddd3da0SLois Curfman McInnes 396936851e7fSLois Curfman McInnes Level: beginner 397036851e7fSLois Curfman McInnes 39719b94acceSBarry Smith .keywords: SNES, nonlinear, solve 39729b94acceSBarry Smith 3973c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 39749b94acceSBarry Smith @*/ 39757087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 39769b94acceSBarry Smith { 3977dfbe8321SBarry Smith PetscErrorCode ierr; 3978ace3abfcSBarry Smith PetscBool flg; 3979efd51863SBarry Smith PetscInt grid; 39800298fd71SBarry Smith Vec xcreated = NULL; 3981caa4e7f2SJed Brown DM dm; 3982052efed2SBarry Smith 39833a40ed3dSBarry Smith PetscFunctionBegin; 39840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3985a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3986a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 39870700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 398885385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 398985385478SLisandro Dalcin 3990caa4e7f2SJed Brown if (!x) { 3991caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3992caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 3993a69afd8bSBarry Smith x = xcreated; 3994a69afd8bSBarry Smith } 3995ce1779c8SBarry Smith ierr = SNESViewFromOptions(snes,NULL,"-snes_view_pre");CHKERRQ(ierr); 3996f05ece33SBarry Smith 3997ce94432eSBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);} 3998efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3999efd51863SBarry Smith 400085385478SLisandro Dalcin /* set solution vector */ 4001efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 40026bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 400385385478SLisandro Dalcin snes->vec_sol = x; 4004caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4005caa4e7f2SJed Brown 4006caa4e7f2SJed Brown /* set affine vector if provided */ 400785385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 40086bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 400985385478SLisandro Dalcin snes->vec_rhs = b; 401085385478SLisandro Dalcin 4011154060b5SMatthew G. Knepley if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 4012154060b5SMatthew 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"); 4013154060b5SMatthew G. Knepley if (!snes->vec_sol_update /* && snes->vec_sol */) { 4014154060b5SMatthew G. Knepley ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 4015154060b5SMatthew G. Knepley ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);CHKERRQ(ierr); 4016154060b5SMatthew G. Knepley } 4017154060b5SMatthew G. Knepley ierr = DMShellSetGlobalVector(dm,snes->vec_sol);CHKERRQ(ierr); 401870e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 40193f149594SLisandro Dalcin 40207eee914bSBarry Smith if (!grid) { 40217eee914bSBarry Smith if (snes->ops->computeinitialguess) { 4022d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 4023d25893d9SBarry Smith } 4024dd568438SSatish Balay } 4025d25893d9SBarry Smith 4026abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 4027971e163fSPeter Brune if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;} 4028d5e45103SBarry Smith 40293f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 40304936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 403185385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 403217186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 4033422a814eSBarry Smith snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 40343f149594SLisandro Dalcin 403537ec4e1aSPeter Brune if (snes->lagjac_persist) snes->jac_iter += snes->iter; 403637ec4e1aSPeter Brune if (snes->lagpre_persist) snes->pre_iter += snes->iter; 403737ec4e1aSPeter Brune 403827b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg);CHKERRQ(ierr); 4039da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 40402a359c20SBarry Smith ierr = SNESReasonViewFromOptions(snes);CHKERRQ(ierr); 40415968eb51SBarry Smith 4042ce94432eSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 40439c8e83a9SBarry Smith if (snes->reason < 0) break; 4044efd51863SBarry Smith if (grid < snes->gridsequence) { 4045efd51863SBarry Smith DM fine; 4046efd51863SBarry Smith Vec xnew; 4047efd51863SBarry Smith Mat interp; 4048efd51863SBarry Smith 4049ce94432eSBarry Smith ierr = DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);CHKERRQ(ierr); 4050ce94432eSBarry Smith if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 40510298fd71SBarry Smith ierr = DMCreateInterpolation(snes->dm,fine,&interp,NULL);CHKERRQ(ierr); 4052efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 4053efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 4054c833c3b5SJed Brown ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 4055efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 4056efd51863SBarry Smith x = xnew; 4057efd51863SBarry Smith 4058efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 4059efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 4060efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 4061ce94432eSBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr); 4062efd51863SBarry Smith } 4063efd51863SBarry Smith } 4064ce1779c8SBarry Smith ierr = SNESViewFromOptions(snes,NULL,"-snes_view");CHKERRQ(ierr); 4065685405a1SBarry Smith ierr = VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution");CHKERRQ(ierr); 40663f7e2da0SPeter Brune 4067a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 4068e04113cfSBarry Smith ierr = PetscObjectSAWsBlock((PetscObject)snes);CHKERRQ(ierr); 40693a40ed3dSBarry Smith PetscFunctionReturn(0); 40709b94acceSBarry Smith } 40719b94acceSBarry Smith 40729b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 40739b94acceSBarry Smith 407482bf6240SBarry Smith /*@C 40754b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 40769b94acceSBarry Smith 4077fee21e36SBarry Smith Collective on SNES 4078fee21e36SBarry Smith 4079c7afd0dbSLois Curfman McInnes Input Parameters: 4080c7afd0dbSLois Curfman McInnes + snes - the SNES context 4081454a90a3SBarry Smith - type - a known method 4082c7afd0dbSLois Curfman McInnes 4083c7afd0dbSLois Curfman McInnes Options Database Key: 4084454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 408504d7464bSBarry Smith of available methods (for instance, newtonls or newtontr) 4086ae12b187SLois Curfman McInnes 40879b94acceSBarry Smith Notes: 4088e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 408904d7464bSBarry Smith + SNESNEWTONLS - Newton's method with line search 4090c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 409104d7464bSBarry Smith . SNESNEWTONTR - Newton's method with trust region 4092c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 40939b94acceSBarry Smith 4094ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 4095ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 4096ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 4097ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 4098ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 4099ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 4100ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 4101ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 4102ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 4103b0a32e0cSBarry Smith appropriate method. 410436851e7fSLois Curfman McInnes 41058f6c3df8SBarry Smith Developer Notes: SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates 41068f6c3df8SBarry Smith the constructor in that list and calls it to create the spexific object. 41078f6c3df8SBarry Smith 410836851e7fSLois Curfman McInnes Level: intermediate 4109a703fe33SLois Curfman McInnes 4110454a90a3SBarry Smith .keywords: SNES, set, type 4111435da068SBarry Smith 41128f6c3df8SBarry Smith .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions() 4113435da068SBarry Smith 41149b94acceSBarry Smith @*/ 411519fd82e9SBarry Smith PetscErrorCode SNESSetType(SNES snes,SNESType type) 41169b94acceSBarry Smith { 4117dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 4118ace3abfcSBarry Smith PetscBool match; 41193a40ed3dSBarry Smith 41203a40ed3dSBarry Smith PetscFunctionBegin; 41210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41224482741eSBarry Smith PetscValidCharPointer(type,2); 412382bf6240SBarry Smith 4124251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 41250f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 412692ff6ae8SBarry Smith 41271c9cd337SJed Brown ierr = PetscFunctionListFind(SNESList,type,&r);CHKERRQ(ierr); 4128e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 412975396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 4130b5c23020SJed Brown if (snes->ops->destroy) { 4131b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 41320298fd71SBarry Smith snes->ops->destroy = NULL; 4133b5c23020SJed Brown } 413475396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 413575396ef9SLisandro Dalcin snes->ops->setup = 0; 413675396ef9SLisandro Dalcin snes->ops->solve = 0; 413775396ef9SLisandro Dalcin snes->ops->view = 0; 413875396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 413975396ef9SLisandro Dalcin snes->ops->destroy = 0; 414075396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 414175396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 4142f5af7f23SKarl Rupp 4143454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 414403bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 41453a40ed3dSBarry Smith PetscFunctionReturn(0); 41469b94acceSBarry Smith } 41479b94acceSBarry Smith 41489b94acceSBarry Smith /*@C 41499a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 41509b94acceSBarry Smith 4151c7afd0dbSLois Curfman McInnes Not Collective 4152c7afd0dbSLois Curfman McInnes 41539b94acceSBarry Smith Input Parameter: 41544b0e389bSBarry Smith . snes - nonlinear solver context 41559b94acceSBarry Smith 41569b94acceSBarry Smith Output Parameter: 41573a7fca6bSBarry Smith . type - SNES method (a character string) 41589b94acceSBarry Smith 415936851e7fSLois Curfman McInnes Level: intermediate 416036851e7fSLois Curfman McInnes 4161454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 41629b94acceSBarry Smith @*/ 416319fd82e9SBarry Smith PetscErrorCode SNESGetType(SNES snes,SNESType *type) 41649b94acceSBarry Smith { 41653a40ed3dSBarry Smith PetscFunctionBegin; 41660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41674482741eSBarry Smith PetscValidPointer(type,2); 41687adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 41693a40ed3dSBarry Smith PetscFunctionReturn(0); 41709b94acceSBarry Smith } 41719b94acceSBarry Smith 41723cd8a7caSMatthew G. Knepley /*@ 41733cd8a7caSMatthew G. Knepley SNESSetSolution - Sets the solution vector for use by the SNES routines. 41743cd8a7caSMatthew G. Knepley 41753cd8a7caSMatthew G. Knepley Logically Collective on SNES and Vec 41763cd8a7caSMatthew G. Knepley 41773cd8a7caSMatthew G. Knepley Input Parameters: 41783cd8a7caSMatthew G. Knepley + snes - the SNES context obtained from SNESCreate() 41793cd8a7caSMatthew G. Knepley - u - the solution vector 41803cd8a7caSMatthew G. Knepley 41813cd8a7caSMatthew G. Knepley Level: beginner 41823cd8a7caSMatthew G. Knepley 41833cd8a7caSMatthew G. Knepley .keywords: SNES, set, solution 41843cd8a7caSMatthew G. Knepley @*/ 41853cd8a7caSMatthew G. Knepley PetscErrorCode SNESSetSolution(SNES snes, Vec u) 41863cd8a7caSMatthew G. Knepley { 41873cd8a7caSMatthew G. Knepley DM dm; 41883cd8a7caSMatthew G. Knepley PetscErrorCode ierr; 41893cd8a7caSMatthew G. Knepley 41903cd8a7caSMatthew G. Knepley PetscFunctionBegin; 41913cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 41923cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 41933cd8a7caSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) u);CHKERRQ(ierr); 41943cd8a7caSMatthew G. Knepley ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 41953cd8a7caSMatthew G. Knepley 41963cd8a7caSMatthew G. Knepley snes->vec_sol = u; 41973cd8a7caSMatthew G. Knepley 41983cd8a7caSMatthew G. Knepley ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 41993cd8a7caSMatthew G. Knepley ierr = DMShellSetGlobalVector(dm, u);CHKERRQ(ierr); 42003cd8a7caSMatthew G. Knepley PetscFunctionReturn(0); 42013cd8a7caSMatthew G. Knepley } 42023cd8a7caSMatthew G. Knepley 420352baeb72SSatish Balay /*@ 42049b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 4205c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 42069b94acceSBarry Smith 4207c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4208c7afd0dbSLois Curfman McInnes 42099b94acceSBarry Smith Input Parameter: 42109b94acceSBarry Smith . snes - the SNES context 42119b94acceSBarry Smith 42129b94acceSBarry Smith Output Parameter: 42139b94acceSBarry Smith . x - the solution 42149b94acceSBarry Smith 421570e92668SMatthew Knepley Level: intermediate 421636851e7fSLois Curfman McInnes 42179b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 42189b94acceSBarry Smith 421985385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 42209b94acceSBarry Smith @*/ 42217087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 42229b94acceSBarry Smith { 42233a40ed3dSBarry Smith PetscFunctionBegin; 42240700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 42254482741eSBarry Smith PetscValidPointer(x,2); 422685385478SLisandro Dalcin *x = snes->vec_sol; 422770e92668SMatthew Knepley PetscFunctionReturn(0); 422870e92668SMatthew Knepley } 422970e92668SMatthew Knepley 423052baeb72SSatish Balay /*@ 42319b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 42329b94acceSBarry Smith stored. 42339b94acceSBarry Smith 4234c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4235c7afd0dbSLois Curfman McInnes 42369b94acceSBarry Smith Input Parameter: 42379b94acceSBarry Smith . snes - the SNES context 42389b94acceSBarry Smith 42399b94acceSBarry Smith Output Parameter: 42409b94acceSBarry Smith . x - the solution update 42419b94acceSBarry Smith 424236851e7fSLois Curfman McInnes Level: advanced 424336851e7fSLois Curfman McInnes 42449b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 42459b94acceSBarry Smith 424685385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 42479b94acceSBarry Smith @*/ 42487087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 42499b94acceSBarry Smith { 42503a40ed3dSBarry Smith PetscFunctionBegin; 42510700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 42524482741eSBarry Smith PetscValidPointer(x,2); 425385385478SLisandro Dalcin *x = snes->vec_sol_update; 42543a40ed3dSBarry Smith PetscFunctionReturn(0); 42559b94acceSBarry Smith } 42569b94acceSBarry Smith 42579b94acceSBarry Smith /*@C 42583638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 42599b94acceSBarry Smith 4260a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 4261c7afd0dbSLois Curfman McInnes 42629b94acceSBarry Smith Input Parameter: 42639b94acceSBarry Smith . snes - the SNES context 42649b94acceSBarry Smith 42659b94acceSBarry Smith Output Parameter: 42660298fd71SBarry Smith + r - the vector that is used to store residuals (or NULL if you don't want it) 4267f8b49ee9SBarry Smith . f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details 42680298fd71SBarry Smith - ctx - the function context (or NULL if you don't want it) 42699b94acceSBarry Smith 427036851e7fSLois Curfman McInnes Level: advanced 427136851e7fSLois Curfman McInnes 4272a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 42739b94acceSBarry Smith 4274bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction 42759b94acceSBarry Smith @*/ 4276f8b49ee9SBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx) 42779b94acceSBarry Smith { 4278a63bb30eSJed Brown PetscErrorCode ierr; 42796cab3a1bSJed Brown DM dm; 4280a63bb30eSJed Brown 42813a40ed3dSBarry Smith PetscFunctionBegin; 42820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4283a63bb30eSJed Brown if (r) { 4284a63bb30eSJed Brown if (!snes->vec_func) { 4285a63bb30eSJed Brown if (snes->vec_rhs) { 4286a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 4287a63bb30eSJed Brown } else if (snes->vec_sol) { 4288a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 4289a63bb30eSJed Brown } else if (snes->dm) { 4290a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 4291a63bb30eSJed Brown } 4292a63bb30eSJed Brown } 4293a63bb30eSJed Brown *r = snes->vec_func; 4294a63bb30eSJed Brown } 42956cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4296f8b49ee9SBarry Smith ierr = DMSNESGetFunction(dm,f,ctx);CHKERRQ(ierr); 42973a40ed3dSBarry Smith PetscFunctionReturn(0); 42989b94acceSBarry Smith } 42999b94acceSBarry Smith 4300c79ef259SPeter Brune /*@C 4301be95d8f1SBarry Smith SNESGetNGS - Returns the NGS function and context. 4302c79ef259SPeter Brune 4303c79ef259SPeter Brune Input Parameter: 4304c79ef259SPeter Brune . snes - the SNES context 4305c79ef259SPeter Brune 4306c79ef259SPeter Brune Output Parameter: 4307be95d8f1SBarry Smith + f - the function (or NULL) see SNESNGSFunction for details 43080298fd71SBarry Smith - ctx - the function context (or NULL) 4309c79ef259SPeter Brune 4310c79ef259SPeter Brune Level: advanced 4311c79ef259SPeter Brune 4312c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 4313c79ef259SPeter Brune 4314be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetFunction() 4315c79ef259SPeter Brune @*/ 4316c79ef259SPeter Brune 4317be95d8f1SBarry Smith PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx) 4318646217ecSPeter Brune { 43196cab3a1bSJed Brown PetscErrorCode ierr; 43206cab3a1bSJed Brown DM dm; 43216cab3a1bSJed Brown 4322646217ecSPeter Brune PetscFunctionBegin; 4323646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 43246cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4325be95d8f1SBarry Smith ierr = DMSNESGetNGS(dm,f,ctx);CHKERRQ(ierr); 4326646217ecSPeter Brune PetscFunctionReturn(0); 4327646217ecSPeter Brune } 4328646217ecSPeter Brune 43293c7409f5SSatish Balay /*@C 43303c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 4331d850072dSLois Curfman McInnes SNES options in the database. 43323c7409f5SSatish Balay 43333f9fe445SBarry Smith Logically Collective on SNES 4334fee21e36SBarry Smith 4335c7afd0dbSLois Curfman McInnes Input Parameter: 4336c7afd0dbSLois Curfman McInnes + snes - the SNES context 4337c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4338c7afd0dbSLois Curfman McInnes 4339d850072dSLois Curfman McInnes Notes: 4340a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4341c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4342d850072dSLois Curfman McInnes 434336851e7fSLois Curfman McInnes Level: advanced 434436851e7fSLois Curfman McInnes 43453c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 4346a86d99e1SLois Curfman McInnes 4347a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 43483c7409f5SSatish Balay @*/ 43497087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 43503c7409f5SSatish Balay { 4351dfbe8321SBarry Smith PetscErrorCode ierr; 43523c7409f5SSatish Balay 43533a40ed3dSBarry Smith PetscFunctionBegin; 43540700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4355639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 43561cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 435735f5d045SPeter Brune if (snes->linesearch) { 43587601faf0SJed Brown ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 435908b6c495SPeter Brune ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 436035f5d045SPeter Brune } 436135f5d045SPeter Brune ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 43623a40ed3dSBarry Smith PetscFunctionReturn(0); 43633c7409f5SSatish Balay } 43643c7409f5SSatish Balay 43653c7409f5SSatish Balay /*@C 4366f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 4367d850072dSLois Curfman McInnes SNES options in the database. 43683c7409f5SSatish Balay 43693f9fe445SBarry Smith Logically Collective on SNES 4370fee21e36SBarry Smith 4371c7afd0dbSLois Curfman McInnes Input Parameters: 4372c7afd0dbSLois Curfman McInnes + snes - the SNES context 4373c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4374c7afd0dbSLois Curfman McInnes 4375d850072dSLois Curfman McInnes Notes: 4376a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4377c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4378d850072dSLois Curfman McInnes 437936851e7fSLois Curfman McInnes Level: advanced 438036851e7fSLois Curfman McInnes 43813c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 4382a86d99e1SLois Curfman McInnes 4383a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 43843c7409f5SSatish Balay @*/ 43857087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 43863c7409f5SSatish Balay { 4387dfbe8321SBarry Smith PetscErrorCode ierr; 43883c7409f5SSatish Balay 43893a40ed3dSBarry Smith PetscFunctionBegin; 43900700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4391639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 43921cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 439335f5d045SPeter Brune if (snes->linesearch) { 43947601faf0SJed Brown ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 439508b6c495SPeter Brune ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 439635f5d045SPeter Brune } 439735f5d045SPeter Brune ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 43983a40ed3dSBarry Smith PetscFunctionReturn(0); 43993c7409f5SSatish Balay } 44003c7409f5SSatish Balay 44019ab63eb5SSatish Balay /*@C 44023c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 44033c7409f5SSatish Balay SNES options in the database. 44043c7409f5SSatish Balay 4405c7afd0dbSLois Curfman McInnes Not Collective 4406c7afd0dbSLois Curfman McInnes 44073c7409f5SSatish Balay Input Parameter: 44083c7409f5SSatish Balay . snes - the SNES context 44093c7409f5SSatish Balay 44103c7409f5SSatish Balay Output Parameter: 44113c7409f5SSatish Balay . prefix - pointer to the prefix string used 44123c7409f5SSatish Balay 44134ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 44149ab63eb5SSatish Balay sufficient length to hold the prefix. 44159ab63eb5SSatish Balay 441636851e7fSLois Curfman McInnes Level: advanced 441736851e7fSLois Curfman McInnes 44183c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 4419a86d99e1SLois Curfman McInnes 4420a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 44213c7409f5SSatish Balay @*/ 44227087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 44233c7409f5SSatish Balay { 4424dfbe8321SBarry Smith PetscErrorCode ierr; 44253c7409f5SSatish Balay 44263a40ed3dSBarry Smith PetscFunctionBegin; 44270700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4428639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 44293a40ed3dSBarry Smith PetscFunctionReturn(0); 44303c7409f5SSatish Balay } 44313c7409f5SSatish Balay 4432b2002411SLois Curfman McInnes 44333cea93caSBarry Smith /*@C 44341c84c290SBarry Smith SNESRegister - Adds a method to the nonlinear solver package. 44351c84c290SBarry Smith 44361c84c290SBarry Smith Not collective 44371c84c290SBarry Smith 44381c84c290SBarry Smith Input Parameters: 44391c84c290SBarry Smith + name_solver - name of a new user-defined solver 44401c84c290SBarry Smith - routine_create - routine to create method context 44411c84c290SBarry Smith 44421c84c290SBarry Smith Notes: 44431c84c290SBarry Smith SNESRegister() may be called multiple times to add several user-defined solvers. 44441c84c290SBarry Smith 44451c84c290SBarry Smith Sample usage: 44461c84c290SBarry Smith .vb 4447bdf89e91SBarry Smith SNESRegister("my_solver",MySolverCreate); 44481c84c290SBarry Smith .ve 44491c84c290SBarry Smith 44501c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 44511c84c290SBarry Smith $ SNESSetType(snes,"my_solver") 44521c84c290SBarry Smith or at runtime via the option 44531c84c290SBarry Smith $ -snes_type my_solver 44541c84c290SBarry Smith 44551c84c290SBarry Smith Level: advanced 44561c84c290SBarry Smith 44571c84c290SBarry Smith Note: If your function is not being put into a shared library then use SNESRegister() instead 44581c84c290SBarry Smith 44591c84c290SBarry Smith .keywords: SNES, nonlinear, register 44601c84c290SBarry Smith 44611c84c290SBarry Smith .seealso: SNESRegisterAll(), SNESRegisterDestroy() 44623cea93caSBarry Smith 44637f6c08e0SMatthew Knepley Level: advanced 44643cea93caSBarry Smith @*/ 4465bdf89e91SBarry Smith PetscErrorCode SNESRegister(const char sname[],PetscErrorCode (*function)(SNES)) 4466b2002411SLois Curfman McInnes { 4467dfbe8321SBarry Smith PetscErrorCode ierr; 4468b2002411SLois Curfman McInnes 4469b2002411SLois Curfman McInnes PetscFunctionBegin; 4470a240a19fSJed Brown ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr); 4471b2002411SLois Curfman McInnes PetscFunctionReturn(0); 4472b2002411SLois Curfman McInnes } 4473da9b6338SBarry Smith 44747087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 4475da9b6338SBarry Smith { 4476dfbe8321SBarry Smith PetscErrorCode ierr; 447777431f27SBarry Smith PetscInt N,i,j; 4478da9b6338SBarry Smith Vec u,uh,fh; 4479da9b6338SBarry Smith PetscScalar value; 4480da9b6338SBarry Smith PetscReal norm; 4481da9b6338SBarry Smith 4482da9b6338SBarry Smith PetscFunctionBegin; 4483da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 4484da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 4485da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 4486da9b6338SBarry Smith 4487da9b6338SBarry Smith /* currently only works for sequential */ 448822d28d08SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");CHKERRQ(ierr); 4489da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 4490da9b6338SBarry Smith for (i=0; i<N; i++) { 4491da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 449277431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 4493da9b6338SBarry Smith for (j=-10; j<11; j++) { 44948b49ba18SBarry Smith value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0); 4495da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 44963ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 4497da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 449877431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 4499da9b6338SBarry Smith value = -value; 4500da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 4501da9b6338SBarry Smith } 4502da9b6338SBarry Smith } 45036bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 45046bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 4505da9b6338SBarry Smith PetscFunctionReturn(0); 4506da9b6338SBarry Smith } 450771f87433Sdalcinl 450871f87433Sdalcinl /*@ 4509fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 451071f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 451171f87433Sdalcinl Newton method. 451271f87433Sdalcinl 45133f9fe445SBarry Smith Logically Collective on SNES 451471f87433Sdalcinl 451571f87433Sdalcinl Input Parameters: 451671f87433Sdalcinl + snes - SNES context 451771f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 451871f87433Sdalcinl 451964ba62caSBarry Smith Options Database: 452064ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 452164ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 452264ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 452364ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 452464ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 452564ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 452664ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 452764ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 452864ba62caSBarry Smith 452971f87433Sdalcinl Notes: 453071f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 453171f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 453271f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 453371f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 453471f87433Sdalcinl solver. 453571f87433Sdalcinl 453671f87433Sdalcinl Level: advanced 453771f87433Sdalcinl 453871f87433Sdalcinl Reference: 453971f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 454071f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 454171f87433Sdalcinl 454271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 454371f87433Sdalcinl 4544fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 454571f87433Sdalcinl @*/ 45467087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 454771f87433Sdalcinl { 454871f87433Sdalcinl PetscFunctionBegin; 45490700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4550acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 455171f87433Sdalcinl snes->ksp_ewconv = flag; 455271f87433Sdalcinl PetscFunctionReturn(0); 455371f87433Sdalcinl } 455471f87433Sdalcinl 455571f87433Sdalcinl /*@ 4556fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 455771f87433Sdalcinl for computing relative tolerance for linear solvers within an 455871f87433Sdalcinl inexact Newton method. 455971f87433Sdalcinl 456071f87433Sdalcinl Not Collective 456171f87433Sdalcinl 456271f87433Sdalcinl Input Parameter: 456371f87433Sdalcinl . snes - SNES context 456471f87433Sdalcinl 456571f87433Sdalcinl Output Parameter: 456671f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 456771f87433Sdalcinl 456871f87433Sdalcinl Notes: 456971f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 457071f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 457171f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 457271f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 457371f87433Sdalcinl solver. 457471f87433Sdalcinl 457571f87433Sdalcinl Level: advanced 457671f87433Sdalcinl 457771f87433Sdalcinl Reference: 457871f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 457971f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 458071f87433Sdalcinl 458171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 458271f87433Sdalcinl 4583fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 458471f87433Sdalcinl @*/ 45857087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 458671f87433Sdalcinl { 458771f87433Sdalcinl PetscFunctionBegin; 45880700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 458971f87433Sdalcinl PetscValidPointer(flag,2); 459071f87433Sdalcinl *flag = snes->ksp_ewconv; 459171f87433Sdalcinl PetscFunctionReturn(0); 459271f87433Sdalcinl } 459371f87433Sdalcinl 459471f87433Sdalcinl /*@ 4595fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 459671f87433Sdalcinl convergence criteria for the linear solvers within an inexact 459771f87433Sdalcinl Newton method. 459871f87433Sdalcinl 45993f9fe445SBarry Smith Logically Collective on SNES 460071f87433Sdalcinl 460171f87433Sdalcinl Input Parameters: 460271f87433Sdalcinl + snes - SNES context 460371f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 460471f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 460571f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 460671f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 460771f87433Sdalcinl (0 <= gamma2 <= 1) 460871f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 460971f87433Sdalcinl . alpha2 - power for safeguard 461071f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 461171f87433Sdalcinl 461271f87433Sdalcinl Note: 461371f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 461471f87433Sdalcinl 461571f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 461671f87433Sdalcinl 461771f87433Sdalcinl Level: advanced 461871f87433Sdalcinl 461971f87433Sdalcinl Reference: 462071f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 462171f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 462271f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 462371f87433Sdalcinl 462471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 462571f87433Sdalcinl 4626fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 462771f87433Sdalcinl @*/ 4628f5af7f23SKarl Rupp PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 462971f87433Sdalcinl { 4630fa9f3622SBarry Smith SNESKSPEW *kctx; 46315fd66863SKarl Rupp 463271f87433Sdalcinl PetscFunctionBegin; 46330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4634fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4635e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4636c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 4637c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4638c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4639c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 4640c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 4641c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 4642c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 464371f87433Sdalcinl 464471f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 464571f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 464671f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 464771f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 464871f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 464971f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 465071f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 465171f87433Sdalcinl 4652f23aa3ddSBarry 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); 465357622a8eSBarry 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); 465457622a8eSBarry 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); 465557622a8eSBarry 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); 465657622a8eSBarry 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); 465757622a8eSBarry 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); 465871f87433Sdalcinl PetscFunctionReturn(0); 465971f87433Sdalcinl } 466071f87433Sdalcinl 466171f87433Sdalcinl /*@ 4662fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 466371f87433Sdalcinl convergence criteria for the linear solvers within an inexact 466471f87433Sdalcinl Newton method. 466571f87433Sdalcinl 466671f87433Sdalcinl Not Collective 466771f87433Sdalcinl 466871f87433Sdalcinl Input Parameters: 466971f87433Sdalcinl snes - SNES context 467071f87433Sdalcinl 467171f87433Sdalcinl Output Parameters: 467271f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 467371f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 467471f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 4675bf388a1fSBarry Smith . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 467671f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 467771f87433Sdalcinl . alpha2 - power for safeguard 467871f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 467971f87433Sdalcinl 468071f87433Sdalcinl Level: advanced 468171f87433Sdalcinl 468271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 468371f87433Sdalcinl 4684fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 468571f87433Sdalcinl @*/ 4686bf388a1fSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 468771f87433Sdalcinl { 4688fa9f3622SBarry Smith SNESKSPEW *kctx; 46895fd66863SKarl Rupp 469071f87433Sdalcinl PetscFunctionBegin; 46910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4692fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4693e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 469471f87433Sdalcinl if (version) *version = kctx->version; 469571f87433Sdalcinl if (rtol_0) *rtol_0 = kctx->rtol_0; 469671f87433Sdalcinl if (rtol_max) *rtol_max = kctx->rtol_max; 469771f87433Sdalcinl if (gamma) *gamma = kctx->gamma; 469871f87433Sdalcinl if (alpha) *alpha = kctx->alpha; 469971f87433Sdalcinl if (alpha2) *alpha2 = kctx->alpha2; 470071f87433Sdalcinl if (threshold) *threshold = kctx->threshold; 470171f87433Sdalcinl PetscFunctionReturn(0); 470271f87433Sdalcinl } 470371f87433Sdalcinl 4704d5378b5fSDmitry Karpeev PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 470571f87433Sdalcinl { 470671f87433Sdalcinl PetscErrorCode ierr; 4707fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 470871f87433Sdalcinl PetscReal rtol = PETSC_DEFAULT,stol; 470971f87433Sdalcinl 471071f87433Sdalcinl PetscFunctionBegin; 4711d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 471230058271SDmitry Karpeev if (!snes->iter) { 471330058271SDmitry Karpeev rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 471430058271SDmitry Karpeev ierr = VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);CHKERRQ(ierr); 471530058271SDmitry Karpeev } 4716f5af7f23SKarl Rupp else { 471771f87433Sdalcinl if (kctx->version == 1) { 471871f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 471971f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 472085ec1a3cSBarry Smith stol = PetscPowReal(kctx->rtol_last,kctx->alpha2); 472171f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 472271f87433Sdalcinl } else if (kctx->version == 2) { 472385ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 472485ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha); 472571f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 472671f87433Sdalcinl } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 472785ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 472871f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 472985ec1a3cSBarry Smith stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha); 473071f87433Sdalcinl stol = PetscMax(rtol,stol); 473171f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 473271f87433Sdalcinl /* safeguard: avoid oversolving */ 473330058271SDmitry Karpeev stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm; 473471f87433Sdalcinl stol = PetscMax(rtol,stol); 473571f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4736e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 473771f87433Sdalcinl } 473871f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 473971f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 474071f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 474157622a8eSBarry Smith ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);CHKERRQ(ierr); 474271f87433Sdalcinl PetscFunctionReturn(0); 474371f87433Sdalcinl } 474471f87433Sdalcinl 4745d5378b5fSDmitry Karpeev PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 474671f87433Sdalcinl { 474771f87433Sdalcinl PetscErrorCode ierr; 4748fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 474971f87433Sdalcinl PCSide pcside; 475071f87433Sdalcinl Vec lres; 475171f87433Sdalcinl 475271f87433Sdalcinl PetscFunctionBegin; 4753d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 475471f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 475571dbe336SPeter Brune kctx->norm_last = snes->norm; 475671f87433Sdalcinl if (kctx->version == 1) { 47574f00ce20SMatthew G. Knepley PC pc; 47584f00ce20SMatthew G. Knepley PetscBool isNone; 47594f00ce20SMatthew G. Knepley 47604f00ce20SMatthew G. Knepley ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); 47614f00ce20SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);CHKERRQ(ierr); 4762b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 47634f00ce20SMatthew G. Knepley if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 476471f87433Sdalcinl /* KSP residual is true linear residual */ 476571f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 476671f87433Sdalcinl } else { 476771f87433Sdalcinl /* KSP residual is preconditioned residual */ 476871f87433Sdalcinl /* compute true linear residual norm */ 476971f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 477071f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 477171f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 477271f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 47736bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 477471f87433Sdalcinl } 477571f87433Sdalcinl } 477671f87433Sdalcinl PetscFunctionReturn(0); 477771f87433Sdalcinl } 477871f87433Sdalcinl 4779d4211eb9SBarry Smith /*@ 4780d4211eb9SBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 4781d4211eb9SBarry Smith 4782d4211eb9SBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 4783d4211eb9SBarry Smith 4784d4211eb9SBarry Smith Input Parameter: 4785d4211eb9SBarry Smith . snes - the SNES context 4786d4211eb9SBarry Smith 4787d4211eb9SBarry Smith Output Parameter: 4788d4211eb9SBarry Smith . ksp - the KSP context 4789d4211eb9SBarry Smith 4790d4211eb9SBarry Smith Notes: 4791d4211eb9SBarry Smith The user can then directly manipulate the KSP context to set various 4792d4211eb9SBarry Smith options, etc. Likewise, the user can then extract and manipulate the 4793d4211eb9SBarry Smith PC contexts as well. 4794d4211eb9SBarry Smith 4795d4211eb9SBarry Smith Level: beginner 4796d4211eb9SBarry Smith 4797d4211eb9SBarry Smith .keywords: SNES, nonlinear, get, KSP, context 4798d4211eb9SBarry Smith 4799d4211eb9SBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 4800d4211eb9SBarry Smith @*/ 4801d4211eb9SBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 480271f87433Sdalcinl { 480371f87433Sdalcinl PetscErrorCode ierr; 480471f87433Sdalcinl 480571f87433Sdalcinl PetscFunctionBegin; 4806d4211eb9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4807d4211eb9SBarry Smith PetscValidPointer(ksp,2); 4808d4211eb9SBarry Smith 4809d4211eb9SBarry Smith if (!snes->ksp) { 4810a5c2985bSBarry Smith PetscBool monitor = PETSC_FALSE; 4811a5c2985bSBarry Smith 4812d4211eb9SBarry Smith ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr); 4813d4211eb9SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 48143bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);CHKERRQ(ierr); 4815d4211eb9SBarry Smith 4816d5378b5fSDmitry Karpeev ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);CHKERRQ(ierr); 4817d5378b5fSDmitry Karpeev ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);CHKERRQ(ierr); 4818a5c2985bSBarry Smith 4819c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes",&monitor,NULL);CHKERRQ(ierr); 4820a5c2985bSBarry Smith if (monitor) { 4821a5c2985bSBarry Smith ierr = KSPMonitorSet(snes->ksp,KSPMonitorSNES,snes,NULL);CHKERRQ(ierr); 4822a5c2985bSBarry Smith } 4823e5f7ee39SBarry Smith monitor = PETSC_FALSE; 4824c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes_lg",&monitor,NULL);CHKERRQ(ierr); 4825e5f7ee39SBarry Smith if (monitor) { 4826e5f7ee39SBarry Smith PetscObject *objs; 48278b0b5a47SLisandro Dalcin ierr = KSPMonitorSNESLGResidualNormCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,600,&objs);CHKERRQ(ierr); 4828e5f7ee39SBarry Smith objs[0] = (PetscObject) snes; 4829e5f7ee39SBarry Smith ierr = KSPMonitorSet(snes->ksp,(PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*))KSPMonitorSNESLGResidualNorm,objs,(PetscErrorCode (*)(void**))KSPMonitorSNESLGResidualNormDestroy);CHKERRQ(ierr); 4830e5f7ee39SBarry Smith } 4831d4211eb9SBarry Smith } 4832d4211eb9SBarry Smith *ksp = snes->ksp; 483371f87433Sdalcinl PetscFunctionReturn(0); 483471f87433Sdalcinl } 48356c699258SBarry Smith 4836d4211eb9SBarry Smith 4837af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 48386c699258SBarry Smith /*@ 48392a808120SBarry Smith SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners 48406c699258SBarry Smith 48413f9fe445SBarry Smith Logically Collective on SNES 48426c699258SBarry Smith 48436c699258SBarry Smith Input Parameters: 48442a808120SBarry Smith + snes - the nonlinear solver context 48452a808120SBarry Smith - dm - the dm, cannot be NULL 48466c699258SBarry Smith 48476c699258SBarry Smith Level: intermediate 48486c699258SBarry Smith 48496c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 48506c699258SBarry Smith @*/ 48517087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 48526c699258SBarry Smith { 48536c699258SBarry Smith PetscErrorCode ierr; 4854345fed2cSBarry Smith KSP ksp; 4855942e3340SBarry Smith DMSNES sdm; 48566c699258SBarry Smith 48576c699258SBarry Smith PetscFunctionBegin; 48580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 48592a808120SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,2); 48602a808120SBarry Smith ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 4861942e3340SBarry Smith if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 486251f4b3c7SToby Isaac if (snes->dm->dmsnes && !dm->dmsnes) { 4863942e3340SBarry Smith ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr); 4864942e3340SBarry Smith ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr); 4865f5af7f23SKarl Rupp if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 48666cab3a1bSJed Brown } 48676bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 48686cab3a1bSJed Brown } 48696c699258SBarry Smith snes->dm = dm; 4870116d1032SJed Brown snes->dmAuto = PETSC_FALSE; 4871f5af7f23SKarl Rupp 4872345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4873345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4874f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 48752c155ee1SBarry Smith if (snes->pc) { 48762c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 4877be95d8f1SBarry Smith ierr = SNESSetNPCSide(snes,snes->pcside);CHKERRQ(ierr); 48782c155ee1SBarry Smith } 48796c699258SBarry Smith PetscFunctionReturn(0); 48806c699258SBarry Smith } 48816c699258SBarry Smith 48826c699258SBarry Smith /*@ 48836c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 48846c699258SBarry Smith 48853f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 48866c699258SBarry Smith 48876c699258SBarry Smith Input Parameter: 48886c699258SBarry Smith . snes - the preconditioner context 48896c699258SBarry Smith 48906c699258SBarry Smith Output Parameter: 48916c699258SBarry Smith . dm - the dm 48926c699258SBarry Smith 48936c699258SBarry Smith Level: intermediate 48946c699258SBarry Smith 48956c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 48966c699258SBarry Smith @*/ 48977087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 48986c699258SBarry Smith { 48996cab3a1bSJed Brown PetscErrorCode ierr; 49006cab3a1bSJed Brown 49016c699258SBarry Smith PetscFunctionBegin; 49020700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 49036cab3a1bSJed Brown if (!snes->dm) { 4904ce94432eSBarry Smith ierr = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr); 4905116d1032SJed Brown snes->dmAuto = PETSC_TRUE; 49066cab3a1bSJed Brown } 49076c699258SBarry Smith *dm = snes->dm; 49086c699258SBarry Smith PetscFunctionReturn(0); 49096c699258SBarry Smith } 49100807856dSBarry Smith 491131823bd8SMatthew G Knepley /*@ 4912be95d8f1SBarry Smith SNESSetNPC - Sets the nonlinear preconditioner to be used. 491331823bd8SMatthew G Knepley 491431823bd8SMatthew G Knepley Collective on SNES 491531823bd8SMatthew G Knepley 491631823bd8SMatthew G Knepley Input Parameters: 491731823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 491831823bd8SMatthew G Knepley - pc - the preconditioner object 491931823bd8SMatthew G Knepley 492031823bd8SMatthew G Knepley Notes: 4921be95d8f1SBarry Smith Use SNESGetNPC() to retrieve the preconditioner context (for example, 492231823bd8SMatthew G Knepley to configure it using the API). 492331823bd8SMatthew G Knepley 492431823bd8SMatthew G Knepley Level: developer 492531823bd8SMatthew G Knepley 492631823bd8SMatthew G Knepley .keywords: SNES, set, precondition 49273ad1a0b9SPatrick Farrell .seealso: SNESGetNPC(), SNESHasNPC() 492831823bd8SMatthew G Knepley @*/ 4929be95d8f1SBarry Smith PetscErrorCode SNESSetNPC(SNES snes, SNES pc) 493031823bd8SMatthew G Knepley { 493131823bd8SMatthew G Knepley PetscErrorCode ierr; 493231823bd8SMatthew G Knepley 493331823bd8SMatthew G Knepley PetscFunctionBegin; 493431823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 493531823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 493631823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 493731823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4938bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 493931823bd8SMatthew G Knepley snes->pc = pc; 49403bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->pc);CHKERRQ(ierr); 494131823bd8SMatthew G Knepley PetscFunctionReturn(0); 494231823bd8SMatthew G Knepley } 494331823bd8SMatthew G Knepley 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 49833ad1a0b9SPatrick Farrell /*@ 49843ad1a0b9SPatrick Farrell SNESHasNPC - Returns whether a nonlinear preconditioner exists 49853ad1a0b9SPatrick Farrell 49863ad1a0b9SPatrick Farrell Not Collective 49873ad1a0b9SPatrick Farrell 49883ad1a0b9SPatrick Farrell Input Parameter: 49893ad1a0b9SPatrick Farrell . snes - iterative context obtained from SNESCreate() 49903ad1a0b9SPatrick Farrell 49913ad1a0b9SPatrick Farrell Output Parameter: 49923ad1a0b9SPatrick Farrell . has_npc - whether the SNES has an NPC or not 49933ad1a0b9SPatrick Farrell 49943ad1a0b9SPatrick Farrell Level: developer 49953ad1a0b9SPatrick Farrell 49963ad1a0b9SPatrick Farrell .keywords: SNES, has, preconditioner 49973ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESGetNPC() 49983ad1a0b9SPatrick Farrell @*/ 49993ad1a0b9SPatrick Farrell PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 50003ad1a0b9SPatrick Farrell { 50013ad1a0b9SPatrick Farrell PetscFunctionBegin; 50023ad1a0b9SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 500360c7cefcSBarry Smith *has_npc = (PetscBool) (snes->pc ? PETSC_TRUE : PETSC_FALSE); 50043ad1a0b9SPatrick Farrell PetscFunctionReturn(0); 50053ad1a0b9SPatrick Farrell } 50063ad1a0b9SPatrick Farrell 5007c40d0f55SPeter Brune /*@ 5008be95d8f1SBarry Smith SNESSetNPCSide - Sets the preconditioning side. 5009c40d0f55SPeter Brune 5010c40d0f55SPeter Brune Logically Collective on SNES 5011c40d0f55SPeter Brune 5012c40d0f55SPeter Brune Input Parameter: 5013c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5014c40d0f55SPeter Brune 5015c40d0f55SPeter Brune Output Parameter: 5016c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5017c40d0f55SPeter Brune .vb 50182d547940SBarry Smith PC_LEFT - left preconditioning 50192d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5020c40d0f55SPeter Brune .ve 5021c40d0f55SPeter Brune 5022c40d0f55SPeter Brune Options Database Keys: 5023c40d0f55SPeter Brune . -snes_pc_side <right,left> 5024c40d0f55SPeter Brune 50252d547940SBarry Smith Notes: SNESNRICHARDSON and SNESNCG only support left preconditioning. 50262d547940SBarry Smith 5027c40d0f55SPeter Brune Level: intermediate 5028c40d0f55SPeter Brune 5029c40d0f55SPeter Brune .keywords: SNES, set, right, left, side, preconditioner, flag 5030c40d0f55SPeter Brune 5031be95d8f1SBarry Smith .seealso: SNESGetNPCSide(), KSPSetPCSide() 5032c40d0f55SPeter Brune @*/ 5033be95d8f1SBarry Smith PetscErrorCode SNESSetNPCSide(SNES snes,PCSide side) 5034c40d0f55SPeter Brune { 5035c40d0f55SPeter Brune PetscFunctionBegin; 5036c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5037c40d0f55SPeter Brune PetscValidLogicalCollectiveEnum(snes,side,2); 5038c40d0f55SPeter Brune snes->pcside = side; 5039c40d0f55SPeter Brune PetscFunctionReturn(0); 5040c40d0f55SPeter Brune } 5041c40d0f55SPeter Brune 5042c40d0f55SPeter Brune /*@ 5043be95d8f1SBarry Smith SNESGetNPCSide - Gets the preconditioning side. 5044c40d0f55SPeter Brune 5045c40d0f55SPeter Brune Not Collective 5046c40d0f55SPeter Brune 5047c40d0f55SPeter Brune Input Parameter: 5048c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5049c40d0f55SPeter Brune 5050c40d0f55SPeter Brune Output Parameter: 5051c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5052c40d0f55SPeter Brune .vb 50532d547940SBarry Smith PC_LEFT - left preconditioning 50542d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5055c40d0f55SPeter Brune .ve 5056c40d0f55SPeter Brune 5057c40d0f55SPeter Brune Level: intermediate 5058c40d0f55SPeter Brune 5059c40d0f55SPeter Brune .keywords: SNES, get, right, left, side, preconditioner, flag 5060c40d0f55SPeter Brune 5061be95d8f1SBarry Smith .seealso: SNESSetNPCSide(), KSPGetPCSide() 5062c40d0f55SPeter Brune @*/ 5063be95d8f1SBarry Smith PetscErrorCode SNESGetNPCSide(SNES snes,PCSide *side) 5064c40d0f55SPeter Brune { 5065c40d0f55SPeter Brune PetscFunctionBegin; 5066c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5067c40d0f55SPeter Brune PetscValidPointer(side,2); 5068c40d0f55SPeter Brune *side = snes->pcside; 5069c40d0f55SPeter Brune PetscFunctionReturn(0); 5070c40d0f55SPeter Brune } 5071c40d0f55SPeter Brune 50729e764e56SPeter Brune /*@ 50737601faf0SJed Brown SNESSetLineSearch - Sets the linesearch on the SNES instance. 50749e764e56SPeter Brune 50759e764e56SPeter Brune Collective on SNES 50769e764e56SPeter Brune 50779e764e56SPeter Brune Input Parameters: 50789e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 50799e764e56SPeter Brune - linesearch - the linesearch object 50809e764e56SPeter Brune 50819e764e56SPeter Brune Notes: 50827601faf0SJed Brown Use SNESGetLineSearch() to retrieve the preconditioner context (for example, 50839e764e56SPeter Brune to configure it using the API). 50849e764e56SPeter Brune 50859e764e56SPeter Brune Level: developer 50869e764e56SPeter Brune 50879e764e56SPeter Brune .keywords: SNES, set, linesearch 50887601faf0SJed Brown .seealso: SNESGetLineSearch() 50899e764e56SPeter Brune @*/ 50907601faf0SJed Brown PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 50919e764e56SPeter Brune { 50929e764e56SPeter Brune PetscErrorCode ierr; 50939e764e56SPeter Brune 50949e764e56SPeter Brune PetscFunctionBegin; 50959e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5096f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 50979e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 50989e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 5099f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 5100f5af7f23SKarl Rupp 51019e764e56SPeter Brune snes->linesearch = linesearch; 5102f5af7f23SKarl Rupp 51033bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 51049e764e56SPeter Brune PetscFunctionReturn(0); 51059e764e56SPeter Brune } 51069e764e56SPeter Brune 5107a34ceb2aSJed Brown /*@ 51087601faf0SJed Brown SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 51098141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 51109e764e56SPeter Brune 51119e764e56SPeter Brune Not Collective 51129e764e56SPeter Brune 51139e764e56SPeter Brune Input Parameter: 51149e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 51159e764e56SPeter Brune 51169e764e56SPeter Brune Output Parameter: 51179e764e56SPeter Brune . linesearch - linesearch context 51189e764e56SPeter Brune 5119162e0bf5SPeter Brune Level: beginner 51209e764e56SPeter Brune 51219e764e56SPeter Brune .keywords: SNES, get, linesearch 5122162e0bf5SPeter Brune .seealso: SNESSetLineSearch(), SNESLineSearchCreate() 51239e764e56SPeter Brune @*/ 51247601faf0SJed Brown PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 51259e764e56SPeter Brune { 51269e764e56SPeter Brune PetscErrorCode ierr; 51279e764e56SPeter Brune const char *optionsprefix; 51289e764e56SPeter Brune 51299e764e56SPeter Brune PetscFunctionBegin; 51309e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 51319e764e56SPeter Brune PetscValidPointer(linesearch, 2); 51329e764e56SPeter Brune if (!snes->linesearch) { 51339e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 513482f516ccSBarry Smith ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr); 5135f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 5136b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 51379e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 51383bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 51399e764e56SPeter Brune } 51409e764e56SPeter Brune *linesearch = snes->linesearch; 51419e764e56SPeter Brune PetscFunctionReturn(0); 51429e764e56SPeter Brune } 51439e764e56SPeter Brune 514469b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 5145c6db04a5SJed Brown #include <mex.h> 514669b4f73cSBarry Smith 51478f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 51488f6e6473SBarry Smith 51490807856dSBarry Smith /* 5150bf388a1fSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with SNESSetFunctionMatlab(). 51510807856dSBarry Smith 51520807856dSBarry Smith Collective on SNES 51530807856dSBarry Smith 51540807856dSBarry Smith Input Parameters: 51550807856dSBarry Smith + snes - the SNES context 51560807856dSBarry Smith - x - input vector 51570807856dSBarry Smith 51580807856dSBarry Smith Output Parameter: 51590807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 51600807856dSBarry Smith 51610807856dSBarry Smith Notes: 51620807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 51630807856dSBarry Smith implementations, so most users would not generally call this routine 51640807856dSBarry Smith themselves. 51650807856dSBarry Smith 51660807856dSBarry Smith Level: developer 51670807856dSBarry Smith 51680807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 51690807856dSBarry Smith 51700807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 517161b2408cSBarry Smith */ 51727087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 51730807856dSBarry Smith { 5174e650e774SBarry Smith PetscErrorCode ierr; 51758f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 51768f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 51778f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 517891621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 5179e650e774SBarry Smith 51800807856dSBarry Smith PetscFunctionBegin; 51810807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 51820807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 51830807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 51840807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 51850807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 51860807856dSBarry Smith 51870807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 5188e650e774SBarry Smith 518991621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 5190e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 5191e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 519291621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 519391621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 519491621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 51958f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 51968f6e6473SBarry Smith prhs[4] = sctx->ctx; 5197b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 5198e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5199e650e774SBarry Smith mxDestroyArray(prhs[0]); 5200e650e774SBarry Smith mxDestroyArray(prhs[1]); 5201e650e774SBarry Smith mxDestroyArray(prhs[2]); 52028f6e6473SBarry Smith mxDestroyArray(prhs[3]); 5203e650e774SBarry Smith mxDestroyArray(plhs[0]); 52040807856dSBarry Smith PetscFunctionReturn(0); 52050807856dSBarry Smith } 52060807856dSBarry Smith 520761b2408cSBarry Smith /* 52080807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 52090807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 5210e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 52110807856dSBarry Smith 52120807856dSBarry Smith Logically Collective on SNES 52130807856dSBarry Smith 52140807856dSBarry Smith Input Parameters: 52150807856dSBarry Smith + snes - the SNES context 52160807856dSBarry Smith . r - vector to store function value 5217f8b49ee9SBarry Smith - f - function evaluation routine 52180807856dSBarry Smith 52190807856dSBarry Smith Notes: 52200807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 52210807856dSBarry Smith $ f'(x) x = -f(x), 52220807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 52230807856dSBarry Smith 52240807856dSBarry Smith Level: beginner 52250807856dSBarry Smith 5226c5b75c40SBarry Smith Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5227c5b75c40SBarry Smith 52280807856dSBarry Smith .keywords: SNES, nonlinear, set, function 52290807856dSBarry Smith 52300807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 523161b2408cSBarry Smith */ 5232f8b49ee9SBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *f,mxArray *ctx) 52330807856dSBarry Smith { 52340807856dSBarry Smith PetscErrorCode ierr; 52358f6e6473SBarry Smith SNESMatlabContext *sctx; 52360807856dSBarry Smith 52370807856dSBarry Smith PetscFunctionBegin; 52388f6e6473SBarry Smith /* currently sctx is memory bleed */ 5239854ce69bSBarry Smith ierr = PetscNew(&sctx);CHKERRQ(ierr); 5240f8b49ee9SBarry Smith ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr); 52418f6e6473SBarry Smith /* 52428f6e6473SBarry Smith This should work, but it doesn't 52438f6e6473SBarry Smith sctx->ctx = ctx; 52448f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 52458f6e6473SBarry Smith */ 52468f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 52478f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 52480807856dSBarry Smith PetscFunctionReturn(0); 52490807856dSBarry Smith } 525069b4f73cSBarry Smith 525161b2408cSBarry Smith /* 5252bf388a1fSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with SNESSetJacobianMatlab(). 525361b2408cSBarry Smith 525461b2408cSBarry Smith Collective on SNES 525561b2408cSBarry Smith 525661b2408cSBarry Smith Input Parameters: 525761b2408cSBarry Smith + snes - the SNES context 525861b2408cSBarry Smith . x - input vector 525961b2408cSBarry Smith . A, B - the matrices 526061b2408cSBarry Smith - ctx - user context 526161b2408cSBarry Smith 526261b2408cSBarry Smith Level: developer 526361b2408cSBarry Smith 526461b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 526561b2408cSBarry Smith 526661b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 526761b2408cSBarry Smith @*/ 5268f3229a78SSatish Balay PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat A,Mat B,void *ctx) 526961b2408cSBarry Smith { 527061b2408cSBarry Smith PetscErrorCode ierr; 527161b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 527261b2408cSBarry Smith int nlhs = 2,nrhs = 6; 527361b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 527461b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 527561b2408cSBarry Smith 527661b2408cSBarry Smith PetscFunctionBegin; 527761b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 527861b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 527961b2408cSBarry Smith 528061b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 528161b2408cSBarry Smith 528261b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 528361b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 528461b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 528561b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 528661b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 528761b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 528861b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 528961b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 529061b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 529161b2408cSBarry Smith prhs[5] = sctx->ctx; 5292b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 529361b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 529461b2408cSBarry Smith mxDestroyArray(prhs[0]); 529561b2408cSBarry Smith mxDestroyArray(prhs[1]); 529661b2408cSBarry Smith mxDestroyArray(prhs[2]); 529761b2408cSBarry Smith mxDestroyArray(prhs[3]); 529861b2408cSBarry Smith mxDestroyArray(prhs[4]); 529961b2408cSBarry Smith mxDestroyArray(plhs[0]); 530061b2408cSBarry Smith mxDestroyArray(plhs[1]); 530161b2408cSBarry Smith PetscFunctionReturn(0); 530261b2408cSBarry Smith } 530361b2408cSBarry Smith 530461b2408cSBarry Smith /* 530561b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 530661b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 5307e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 530861b2408cSBarry Smith 530961b2408cSBarry Smith Logically Collective on SNES 531061b2408cSBarry Smith 531161b2408cSBarry Smith Input Parameters: 531261b2408cSBarry Smith + snes - the SNES context 531361b2408cSBarry Smith . A,B - Jacobian matrices 5314f8b49ee9SBarry Smith . J - function evaluation routine 531561b2408cSBarry Smith - ctx - user context 531661b2408cSBarry Smith 531761b2408cSBarry Smith Level: developer 531861b2408cSBarry Smith 5319c5b75c40SBarry Smith Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5320c5b75c40SBarry Smith 532161b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 532261b2408cSBarry Smith 5323f8b49ee9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction(), J 532461b2408cSBarry Smith */ 5325f8b49ee9SBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *J,mxArray *ctx) 532661b2408cSBarry Smith { 532761b2408cSBarry Smith PetscErrorCode ierr; 532861b2408cSBarry Smith SNESMatlabContext *sctx; 532961b2408cSBarry Smith 533061b2408cSBarry Smith PetscFunctionBegin; 533161b2408cSBarry Smith /* currently sctx is memory bleed */ 5332854ce69bSBarry Smith ierr = PetscNew(&sctx);CHKERRQ(ierr); 5333f8b49ee9SBarry Smith ierr = PetscStrallocpy(J,&sctx->funcname);CHKERRQ(ierr); 533461b2408cSBarry Smith /* 533561b2408cSBarry Smith This should work, but it doesn't 533661b2408cSBarry Smith sctx->ctx = ctx; 533761b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 533861b2408cSBarry Smith */ 533961b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 534061b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 534161b2408cSBarry Smith PetscFunctionReturn(0); 534261b2408cSBarry Smith } 534369b4f73cSBarry Smith 5344f9eb7ae2SShri Abhyankar /* 5345f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 5346f9eb7ae2SShri Abhyankar 5347f9eb7ae2SShri Abhyankar Collective on SNES 5348f9eb7ae2SShri Abhyankar 5349f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 5350f9eb7ae2SShri Abhyankar @*/ 53517087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 5352f9eb7ae2SShri Abhyankar { 5353f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 535448f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 5355f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 5356f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 5357f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 5358f9eb7ae2SShri Abhyankar Vec x = snes->vec_sol; 5359f9eb7ae2SShri Abhyankar 5360f9eb7ae2SShri Abhyankar PetscFunctionBegin; 5361f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5362f9eb7ae2SShri Abhyankar 5363f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 5364f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 5365f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 5366f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 5367f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 5368f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 5369f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 5370f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 5371f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 5372f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5373f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 5374f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 5375f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 5376f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 5377f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 5378f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 5379f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 5380f9eb7ae2SShri Abhyankar } 5381f9eb7ae2SShri Abhyankar 5382f9eb7ae2SShri Abhyankar /* 5383e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 5384f9eb7ae2SShri Abhyankar 5385f9eb7ae2SShri Abhyankar Level: developer 5386f9eb7ae2SShri Abhyankar 5387c5b75c40SBarry Smith Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5388c5b75c40SBarry Smith 5389f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 5390f9eb7ae2SShri Abhyankar 5391f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 5392f9eb7ae2SShri Abhyankar */ 53936e4dcb14SBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *f,mxArray *ctx) 5394f9eb7ae2SShri Abhyankar { 5395f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 5396f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 5397f9eb7ae2SShri Abhyankar 5398f9eb7ae2SShri Abhyankar PetscFunctionBegin; 5399f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 5400854ce69bSBarry Smith ierr = PetscNew(&sctx);CHKERRQ(ierr); 54016e4dcb14SBarry Smith ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr); 5402f9eb7ae2SShri Abhyankar /* 5403f9eb7ae2SShri Abhyankar This should work, but it doesn't 5404f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 5405f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 5406f9eb7ae2SShri Abhyankar */ 5407f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 54080298fd71SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,NULL);CHKERRQ(ierr); 5409f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 5410f9eb7ae2SShri Abhyankar } 5411f9eb7ae2SShri Abhyankar 541269b4f73cSBarry Smith #endif 5413