1af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/ 207475bc1SBarry Smith #include <petscdmshell.h> 3d96771aaSLisandro Dalcin #include <petscdraw.h> 4a01aa210SMatthew G. Knepley #include <petscds.h> 534b4d3a8SMatthew G. Knepley #include <petscdmadaptor.h> 606fc46c8SMatthew G. Knepley #include <petscconvest.h> 79b94acceSBarry Smith 8ace3abfcSBarry Smith PetscBool SNESRegisterAllCalled = PETSC_FALSE; 90298fd71SBarry Smith PetscFunctionList SNESList = NULL; 108ba1e511SMatthew Knepley 118ba1e511SMatthew Knepley /* Logging support */ 1222c6f798SBarry Smith PetscClassId SNES_CLASSID, DMSNES_CLASSID; 1394db00ebSBarry Smith PetscLogEvent SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_NGSEval, SNES_NGSFuncEval, SNES_NPCSolve, SNES_ObjectiveEval; 14a09944afSBarry Smith 15e113a28aSBarry Smith /*@ 16e113a28aSBarry Smith SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 17e113a28aSBarry Smith 183f9fe445SBarry Smith Logically Collective on SNES 19e113a28aSBarry Smith 20e113a28aSBarry Smith Input Parameters: 21e113a28aSBarry Smith + snes - iterative context obtained from SNESCreate() 22e113a28aSBarry Smith - flg - PETSC_TRUE indicates you want the error generated 23e113a28aSBarry Smith 24e113a28aSBarry Smith Options database keys: 25e113a28aSBarry Smith . -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false) 26e113a28aSBarry Smith 27e113a28aSBarry Smith Level: intermediate 28e113a28aSBarry Smith 29e113a28aSBarry Smith Notes: 30e113a28aSBarry Smith Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 31e113a28aSBarry Smith to determine if it has converged. 32e113a28aSBarry Smith 33e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 34e113a28aSBarry Smith 35e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 36e113a28aSBarry Smith @*/ 377087cfbeSBarry Smith PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 38e113a28aSBarry Smith { 39e113a28aSBarry Smith PetscFunctionBegin; 40e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flg,2); 42e113a28aSBarry Smith snes->errorifnotconverged = flg; 43e113a28aSBarry Smith PetscFunctionReturn(0); 44e113a28aSBarry Smith } 45e113a28aSBarry Smith 46e113a28aSBarry Smith /*@ 47e113a28aSBarry Smith SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 48e113a28aSBarry Smith 49e113a28aSBarry Smith Not Collective 50e113a28aSBarry Smith 51e113a28aSBarry Smith Input Parameter: 52e113a28aSBarry Smith . snes - iterative context obtained from SNESCreate() 53e113a28aSBarry Smith 54e113a28aSBarry Smith Output Parameter: 55e113a28aSBarry Smith . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 56e113a28aSBarry Smith 57e113a28aSBarry Smith Level: intermediate 58e113a28aSBarry Smith 59e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 60e113a28aSBarry Smith 61e113a28aSBarry Smith .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 62e113a28aSBarry Smith @*/ 637087cfbeSBarry Smith PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 64e113a28aSBarry Smith { 65e113a28aSBarry Smith PetscFunctionBegin; 66e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 67e113a28aSBarry Smith PetscValidPointer(flag,2); 68e113a28aSBarry Smith *flag = snes->errorifnotconverged; 69e113a28aSBarry Smith PetscFunctionReturn(0); 70e113a28aSBarry Smith } 71e113a28aSBarry Smith 724fc747eaSLawrence Mitchell /*@ 734fc747eaSLawrence Mitchell SNESSetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution? 744fc747eaSLawrence Mitchell 754fc747eaSLawrence Mitchell Logically Collective on SNES 764fc747eaSLawrence Mitchell 774fc747eaSLawrence Mitchell Input Parameters: 784fc747eaSLawrence Mitchell + snes - the shell SNES 794fc747eaSLawrence Mitchell - flg - is the residual computed? 804fc747eaSLawrence Mitchell 814fc747eaSLawrence Mitchell Level: advanced 824fc747eaSLawrence Mitchell 834fc747eaSLawrence Mitchell .seealso: SNESGetAlwaysComputesFinalResidual() 844fc747eaSLawrence Mitchell @*/ 854fc747eaSLawrence Mitchell PetscErrorCode SNESSetAlwaysComputesFinalResidual(SNES snes, PetscBool flg) 864fc747eaSLawrence Mitchell { 874fc747eaSLawrence Mitchell PetscFunctionBegin; 884fc747eaSLawrence Mitchell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 894fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = flg; 904fc747eaSLawrence Mitchell PetscFunctionReturn(0); 914fc747eaSLawrence Mitchell } 924fc747eaSLawrence Mitchell 934fc747eaSLawrence Mitchell /*@ 944fc747eaSLawrence Mitchell SNESGetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution? 954fc747eaSLawrence Mitchell 964fc747eaSLawrence Mitchell Logically Collective on SNES 974fc747eaSLawrence Mitchell 984fc747eaSLawrence Mitchell Input Parameter: 994fc747eaSLawrence Mitchell . snes - the shell SNES 1004fc747eaSLawrence Mitchell 1014fc747eaSLawrence Mitchell Output Parameter: 1024fc747eaSLawrence Mitchell . flg - is the residual computed? 1034fc747eaSLawrence Mitchell 1044fc747eaSLawrence Mitchell Level: advanced 1054fc747eaSLawrence Mitchell 1064fc747eaSLawrence Mitchell .seealso: SNESSetAlwaysComputesFinalResidual() 1074fc747eaSLawrence Mitchell @*/ 1084fc747eaSLawrence Mitchell PetscErrorCode SNESGetAlwaysComputesFinalResidual(SNES snes, PetscBool *flg) 1094fc747eaSLawrence Mitchell { 1104fc747eaSLawrence Mitchell PetscFunctionBegin; 1114fc747eaSLawrence Mitchell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1124fc747eaSLawrence Mitchell *flg = snes->alwayscomputesfinalresidual; 1134fc747eaSLawrence Mitchell PetscFunctionReturn(0); 1144fc747eaSLawrence Mitchell } 1154fc747eaSLawrence Mitchell 116e725d27bSBarry Smith /*@ 117bf388a1fSBarry Smith SNESSetFunctionDomainError - tells SNES that the input vector to your SNESFunction is not 1184936397dSBarry Smith in the functions domain. For example, negative pressure. 1194936397dSBarry Smith 1203f9fe445SBarry Smith Logically Collective on SNES 1214936397dSBarry Smith 1224936397dSBarry Smith Input Parameters: 1236a388c36SPeter Brune . snes - the SNES context 1244936397dSBarry Smith 12528529972SSatish Balay Level: advanced 1264936397dSBarry Smith 1274936397dSBarry Smith .keywords: SNES, view 1284936397dSBarry Smith 129bf388a1fSBarry Smith .seealso: SNESCreate(), SNESSetFunction(), SNESFunction 1304936397dSBarry Smith @*/ 1317087cfbeSBarry Smith PetscErrorCode SNESSetFunctionDomainError(SNES snes) 1324936397dSBarry Smith { 1334936397dSBarry Smith PetscFunctionBegin; 1340700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 135422a814eSBarry Smith if (snes->errorifnotconverged) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"User code indicates input vector is not in the function domain"); 1364936397dSBarry Smith snes->domainerror = PETSC_TRUE; 1374936397dSBarry Smith PetscFunctionReturn(0); 1384936397dSBarry Smith } 1394936397dSBarry Smith 1406a388c36SPeter Brune /*@ 141c77b2880SPeter Brune SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction; 1426a388c36SPeter Brune 1436a388c36SPeter Brune Logically Collective on SNES 1446a388c36SPeter Brune 1456a388c36SPeter Brune Input Parameters: 1466a388c36SPeter Brune . snes - the SNES context 1476a388c36SPeter Brune 1486a388c36SPeter Brune Output Parameters: 149bf388a1fSBarry Smith . domainerror - Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise. 1506a388c36SPeter Brune 1516a388c36SPeter Brune Level: advanced 1526a388c36SPeter Brune 1536a388c36SPeter Brune .keywords: SNES, view 1546a388c36SPeter Brune 155bf388a1fSBarry Smith .seealso: SNESSetFunctionDomainError(), SNESComputeFunction() 1566a388c36SPeter Brune @*/ 1576a388c36SPeter Brune PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 1586a388c36SPeter Brune { 1596a388c36SPeter Brune PetscFunctionBegin; 1606a388c36SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1616a388c36SPeter Brune PetscValidPointer(domainerror, 2); 1626a388c36SPeter Brune *domainerror = snes->domainerror; 1636a388c36SPeter Brune PetscFunctionReturn(0); 1646a388c36SPeter Brune } 1656a388c36SPeter Brune 16655849f57SBarry Smith /*@C 16755849f57SBarry Smith SNESLoad - Loads a SNES that has been stored in binary with SNESView(). 16855849f57SBarry Smith 16955849f57SBarry Smith Collective on PetscViewer 17055849f57SBarry Smith 17155849f57SBarry Smith Input Parameters: 17255849f57SBarry Smith + newdm - the newly loaded SNES, this needs to have been created with SNESCreate() or 17355849f57SBarry Smith some related function before a call to SNESLoad(). 17455849f57SBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() 17555849f57SBarry Smith 17655849f57SBarry Smith Level: intermediate 17755849f57SBarry Smith 17855849f57SBarry Smith Notes: 17955849f57SBarry Smith The type is determined by the data in the file, any type set into the SNES before this call is ignored. 18055849f57SBarry Smith 18155849f57SBarry Smith Notes for advanced users: 18255849f57SBarry Smith Most users should not need to know the details of the binary storage 18355849f57SBarry Smith format, since SNESLoad() and TSView() completely hide these details. 18455849f57SBarry Smith But for anyone who's interested, the standard binary matrix storage 18555849f57SBarry Smith format is 18655849f57SBarry Smith .vb 18755849f57SBarry Smith has not yet been determined 18855849f57SBarry Smith .ve 18955849f57SBarry Smith 19055849f57SBarry Smith .seealso: PetscViewerBinaryOpen(), SNESView(), MatLoad(), VecLoad() 19155849f57SBarry Smith @*/ 1922d53ad75SBarry Smith PetscErrorCode SNESLoad(SNES snes, PetscViewer viewer) 19355849f57SBarry Smith { 19455849f57SBarry Smith PetscErrorCode ierr; 19555849f57SBarry Smith PetscBool isbinary; 196060da220SMatthew G. Knepley PetscInt classid; 19755849f57SBarry Smith char type[256]; 19855849f57SBarry Smith KSP ksp; 1992d53ad75SBarry Smith DM dm; 2002d53ad75SBarry Smith DMSNES dmsnes; 20155849f57SBarry Smith 20255849f57SBarry Smith PetscFunctionBegin; 2032d53ad75SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20455849f57SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 20555849f57SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 20655849f57SBarry Smith if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 20755849f57SBarry Smith 208060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr); 209ce94432eSBarry Smith if (classid != SNES_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Not SNES next in file"); 210060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr); 2112d53ad75SBarry Smith ierr = SNESSetType(snes, type);CHKERRQ(ierr); 2122d53ad75SBarry Smith if (snes->ops->load) { 2132d53ad75SBarry Smith ierr = (*snes->ops->load)(snes,viewer);CHKERRQ(ierr); 214f2c2a1b9SBarry Smith } 2152d53ad75SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2162d53ad75SBarry Smith ierr = DMGetDMSNES(dm,&dmsnes);CHKERRQ(ierr); 2172d53ad75SBarry Smith ierr = DMSNESLoad(dmsnes,viewer);CHKERRQ(ierr); 2182d53ad75SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 21955849f57SBarry Smith ierr = KSPLoad(ksp,viewer);CHKERRQ(ierr); 22055849f57SBarry Smith PetscFunctionReturn(0); 22155849f57SBarry Smith } 2226a388c36SPeter Brune 2239804daf3SBarry Smith #include <petscdraw.h> 224e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 225e04113cfSBarry Smith #include <petscviewersaws.h> 226bfb97211SBarry Smith #endif 2278404b7f3SBarry Smith 2287e2c5f70SBarry Smith /*@C 2299b94acceSBarry Smith SNESView - Prints the SNES data structure. 2309b94acceSBarry Smith 2314c49b128SBarry Smith Collective on SNES 232fee21e36SBarry Smith 233c7afd0dbSLois Curfman McInnes Input Parameters: 234c7afd0dbSLois Curfman McInnes + SNES - the SNES context 235c7afd0dbSLois Curfman McInnes - viewer - visualization context 236c7afd0dbSLois Curfman McInnes 2379b94acceSBarry Smith Options Database Key: 238c8a8ba5cSLois Curfman McInnes . -snes_view - Calls SNESView() at end of SNESSolve() 2399b94acceSBarry Smith 2409b94acceSBarry Smith Notes: 2419b94acceSBarry Smith The available visualization contexts include 242b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 243b0a32e0cSBarry Smith - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 244c8a8ba5cSLois Curfman McInnes output where only the first processor opens 245c8a8ba5cSLois Curfman McInnes the file. All other processors send their 246c8a8ba5cSLois Curfman McInnes data to the first processor to print. 2479b94acceSBarry Smith 2483e081fefSLois Curfman McInnes The user can open an alternative visualization context with 249b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 2509b94acceSBarry Smith 25136851e7fSLois Curfman McInnes Level: beginner 25236851e7fSLois Curfman McInnes 2539b94acceSBarry Smith .keywords: SNES, view 2549b94acceSBarry Smith 255b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen() 2569b94acceSBarry Smith @*/ 2577087cfbeSBarry Smith PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 2589b94acceSBarry Smith { 259fa9f3622SBarry Smith SNESKSPEW *kctx; 260dfbe8321SBarry Smith PetscErrorCode ierr; 26194b7f48cSBarry Smith KSP ksp; 2627f1410a3SPeter Brune SNESLineSearch linesearch; 26372a02f06SBarry Smith PetscBool iascii,isstring,isbinary,isdraw; 2642d53ad75SBarry Smith DMSNES dmsnes; 265e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 266536b137fSBarry Smith PetscBool issaws; 267bfb97211SBarry Smith #endif 2689b94acceSBarry Smith 2693a40ed3dSBarry Smith PetscFunctionBegin; 2700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2713050cee2SBarry Smith if (!viewer) { 272ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer);CHKERRQ(ierr); 2733050cee2SBarry Smith } 2740700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 275c9780b6fSBarry Smith PetscCheckSameComm(snes,1,viewer,2); 27674679c65SBarry Smith 277251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 278251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 27955849f57SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 28072a02f06SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 281e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 282536b137fSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 283bfb97211SBarry Smith #endif 28432077d6dSBarry Smith if (iascii) { 285dc0571f2SMatthew G. Knepley SNESNormSchedule normschedule; 2868404b7f3SBarry Smith DM dm; 2878404b7f3SBarry Smith PetscErrorCode (*cJ)(SNES,Vec,Mat,Mat,void*); 2888404b7f3SBarry Smith void *ctx; 289dc0571f2SMatthew G. Knepley 290dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer);CHKERRQ(ierr); 291fce1e034SJed Brown if (!snes->setupcalled) { 292fce1e034SJed Brown ierr = PetscViewerASCIIPrintf(viewer," SNES has not been set up so information may be incomplete\n");CHKERRQ(ierr); 293fce1e034SJed Brown } 294e7788613SBarry Smith if (snes->ops->view) { 295b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 296e7788613SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 297b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2980ef38995SBarry Smith } 29977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 30057622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%g, absolute=%g, solution=%g\n",(double)snes->rtol,(double)snes->abstol,(double)snes->stol);CHKERRQ(ierr); 301efd4aadfSBarry Smith if (snes->usesksp) { 30277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 303efd4aadfSBarry Smith } 30477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 305dc0571f2SMatthew G. Knepley ierr = SNESGetNormSchedule(snes, &normschedule);CHKERRQ(ierr); 306dc0571f2SMatthew G. Knepley if (normschedule > 0) {ierr = PetscViewerASCIIPrintf(viewer," norm schedule %s\n",SNESNormSchedules[normschedule]);CHKERRQ(ierr);} 30717fe4bdfSPeter Brune if (snes->gridsequence) { 30817fe4bdfSPeter Brune ierr = PetscViewerASCIIPrintf(viewer," total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr); 30917fe4bdfSPeter Brune } 3109b94acceSBarry Smith if (snes->ksp_ewconv) { 311fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3129b94acceSBarry Smith if (kctx) { 31377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 31457622a8eSBarry 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); 31557622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," gamma=%g, alpha=%g, alpha2=%g\n",(double)kctx->gamma,(double)kctx->alpha,(double)kctx->alpha2);CHKERRQ(ierr); 3169b94acceSBarry Smith } 3179b94acceSBarry Smith } 318eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 319eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 320eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 321eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 322eb1f6c34SBarry Smith } 323eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 324eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 325eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 32642f4f86dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 327eb1f6c34SBarry Smith } 3288404b7f3SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3298404b7f3SBarry Smith ierr = DMSNESGetJacobian(dm,&cJ,&ctx);CHKERRQ(ierr); 3308404b7f3SBarry Smith if (cJ == SNESComputeJacobianDefault) { 3318404b7f3SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is built using finite differences one column at a time\n");CHKERRQ(ierr); 3328404b7f3SBarry Smith } else if (cJ == SNESComputeJacobianDefaultColor) { 3338404b7f3SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is built using finite differences with coloring\n");CHKERRQ(ierr); 3348404b7f3SBarry Smith } 3350f5bd95cSBarry Smith } else if (isstring) { 336317d6ea6SBarry Smith const char *type; 337454a90a3SBarry Smith ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 338b0a32e0cSBarry Smith ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 33955849f57SBarry Smith } else if (isbinary) { 34055849f57SBarry Smith PetscInt classid = SNES_FILE_CLASSID; 34155849f57SBarry Smith MPI_Comm comm; 34255849f57SBarry Smith PetscMPIInt rank; 34355849f57SBarry Smith char type[256]; 34455849f57SBarry Smith 34555849f57SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 34655849f57SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 34755849f57SBarry Smith if (!rank) { 34855849f57SBarry Smith ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 34989d949e2SBarry Smith ierr = PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type));CHKERRQ(ierr); 35089d949e2SBarry Smith ierr = PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 35155849f57SBarry Smith } 35255849f57SBarry Smith if (snes->ops->view) { 35355849f57SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 35455849f57SBarry Smith } 35572a02f06SBarry Smith } else if (isdraw) { 35672a02f06SBarry Smith PetscDraw draw; 35772a02f06SBarry Smith char str[36]; 35889fd9fafSBarry Smith PetscReal x,y,bottom,h; 35972a02f06SBarry Smith 36072a02f06SBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 36172a02f06SBarry Smith ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr); 362a126751eSBarry Smith ierr = PetscStrncpy(str,"SNES: ",sizeof(str));CHKERRQ(ierr); 363a126751eSBarry Smith ierr = PetscStrlcat(str,((PetscObject)snes)->type_name,sizeof(str));CHKERRQ(ierr); 36451fa3d41SBarry Smith ierr = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr); 36589fd9fafSBarry Smith bottom = y - h; 36672a02f06SBarry Smith ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr); 367c4646bacSPeter Brune if (snes->ops->view) { 368c4646bacSPeter Brune ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 369c4646bacSPeter Brune } 370e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 371536b137fSBarry Smith } else if (issaws) { 372d45a07a7SBarry Smith PetscMPIInt rank; 3732657e9d9SBarry Smith const char *name; 374d45a07a7SBarry Smith 3752657e9d9SBarry Smith ierr = PetscObjectGetName((PetscObject)snes,&name);CHKERRQ(ierr); 376d45a07a7SBarry Smith ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 377d45a07a7SBarry Smith if (!((PetscObject)snes)->amsmem && !rank) { 378d45a07a7SBarry Smith char dir[1024]; 379d45a07a7SBarry Smith 380e04113cfSBarry Smith ierr = PetscObjectViewSAWs((PetscObject)snes,viewer);CHKERRQ(ierr); 3812657e9d9SBarry Smith ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name);CHKERRQ(ierr); 3822657e9d9SBarry Smith PetscStackCallSAWs(SAWs_Register,(dir,&snes->iter,1,SAWs_READ,SAWs_INT)); 383bfb97211SBarry Smith if (!snes->conv_hist) { 384a0931e03SBarry Smith ierr = SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE);CHKERRQ(ierr); 385bfb97211SBarry Smith } 3862657e9d9SBarry Smith ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/conv_hist",name);CHKERRQ(ierr); 3872657e9d9SBarry Smith PetscStackCallSAWs(SAWs_Register,(dir,snes->conv_hist,10,SAWs_READ,SAWs_DOUBLE)); 388f05ece33SBarry Smith } 389bfb97211SBarry Smith #endif 39072a02f06SBarry Smith } 39172a02f06SBarry Smith if (snes->linesearch) { 3927601faf0SJed Brown ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr); 39385928a98SStefano Zampini ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 39472a02f06SBarry Smith ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr); 39585928a98SStefano Zampini ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 39619bcc07fSBarry Smith } 397efd4aadfSBarry Smith if (snes->npc && snes->usesnpc) { 39885928a98SStefano Zampini ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 399efd4aadfSBarry Smith ierr = SNESView(snes->npc, viewer);CHKERRQ(ierr); 40085928a98SStefano Zampini ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 4014a0c5b0cSMatthew G Knepley } 4022d53ad75SBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 4032d53ad75SBarry Smith ierr = DMGetDMSNES(snes->dm,&dmsnes);CHKERRQ(ierr); 4042d53ad75SBarry Smith ierr = DMSNESView(dmsnes, viewer);CHKERRQ(ierr); 4052d53ad75SBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 4062c155ee1SBarry Smith if (snes->usesksp) { 4072c155ee1SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 40885928a98SStefano Zampini ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 40994b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 41085928a98SStefano Zampini ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 4112c155ee1SBarry Smith } 41272a02f06SBarry Smith if (isdraw) { 41372a02f06SBarry Smith PetscDraw draw; 41472a02f06SBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 41572a02f06SBarry Smith ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr); 4167f1410a3SPeter Brune } 4173a40ed3dSBarry Smith PetscFunctionReturn(0); 4189b94acceSBarry Smith } 4199b94acceSBarry Smith 42076b2cf59SMatthew Knepley /* 42176b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 42276b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 42376b2cf59SMatthew Knepley */ 42476b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 425a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 4266849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 42776b2cf59SMatthew Knepley 428ac226902SBarry Smith /*@C 42976b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 43076b2cf59SMatthew Knepley 43176b2cf59SMatthew Knepley Not Collective 43276b2cf59SMatthew Knepley 43376b2cf59SMatthew Knepley Input Parameter: 43476b2cf59SMatthew Knepley . snescheck - function that checks for options 43576b2cf59SMatthew Knepley 43676b2cf59SMatthew Knepley Level: developer 43776b2cf59SMatthew Knepley 43876b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 43976b2cf59SMatthew Knepley @*/ 4407087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 44176b2cf59SMatthew Knepley { 44276b2cf59SMatthew Knepley PetscFunctionBegin; 443f23aa3ddSBarry Smith if (numberofsetfromoptions >= MAXSETFROMOPTIONS) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 44476b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 44576b2cf59SMatthew Knepley PetscFunctionReturn(0); 44676b2cf59SMatthew Knepley } 44776b2cf59SMatthew Knepley 44825acbd8eSLisandro Dalcin PETSC_INTERN PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 449aa3661deSLisandro Dalcin 450ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 451aa3661deSLisandro Dalcin { 452aa3661deSLisandro Dalcin Mat J; 453aa3661deSLisandro Dalcin KSP ksp; 454aa3661deSLisandro Dalcin PC pc; 455ace3abfcSBarry Smith PetscBool match; 456aa3661deSLisandro Dalcin PetscErrorCode ierr; 457895c21f2SBarry Smith MatNullSpace nullsp; 458aa3661deSLisandro Dalcin 459aa3661deSLisandro Dalcin PetscFunctionBegin; 4600700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 461aa3661deSLisandro Dalcin 46298613b67SLisandro Dalcin if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 46398613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 4642a7a6963SBarry Smith ierr = MatCreateVecs(A ? A : B, NULL,&snes->vec_func);CHKERRQ(ierr); 46598613b67SLisandro Dalcin } 46698613b67SLisandro Dalcin 467aa3661deSLisandro Dalcin if (version == 1) { 468aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 46998613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4709c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 471aa3661deSLisandro Dalcin } else if (version == 2) { 472e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 473570b7f6dSBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16) 474aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 475aa3661deSLisandro Dalcin #else 476e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 477aa3661deSLisandro Dalcin #endif 478a8248277SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 479aa3661deSLisandro Dalcin 480895c21f2SBarry Smith /* attach any user provided null space that was on Amat to the newly created matrix free matrix */ 481895c21f2SBarry Smith if (snes->jacobian) { 482895c21f2SBarry Smith ierr = MatGetNullSpace(snes->jacobian,&nullsp);CHKERRQ(ierr); 483895c21f2SBarry Smith if (nullsp) { 484895c21f2SBarry Smith ierr = MatSetNullSpace(J,nullsp);CHKERRQ(ierr); 485895c21f2SBarry Smith } 486895c21f2SBarry Smith } 487895c21f2SBarry Smith 488aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 489d3462f78SMatthew Knepley if (hasOperator) { 4903232da50SPeter Brune 491aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 492aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 493aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 494aa3661deSLisandro Dalcin } else { 495aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 4963232da50SPeter Brune provided preconditioner Jacobian with the default matrix free version. */ 497efd4aadfSBarry Smith if ((snes->npcside== PC_LEFT) && snes->npc) { 498d728fb7dSPeter Brune if (!snes->jacobian){ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);} 499172a4300SPeter Brune } else { 50028a52e04SBarry Smith ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,0);CHKERRQ(ierr); 501172a4300SPeter Brune } 502aa3661deSLisandro Dalcin /* Force no preconditioner */ 503aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 504aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 505251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 506aa3661deSLisandro Dalcin if (!match) { 507aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 508aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 509aa3661deSLisandro Dalcin } 510aa3661deSLisandro Dalcin } 5116bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 512aa3661deSLisandro Dalcin PetscFunctionReturn(0); 513aa3661deSLisandro Dalcin } 514aa3661deSLisandro Dalcin 515dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx) 516dfe15315SJed Brown { 517dfe15315SJed Brown SNES snes = (SNES)ctx; 518dfe15315SJed Brown PetscErrorCode ierr; 5190298fd71SBarry Smith Vec Xfine,Xfine_named = NULL,Xcoarse; 520dfe15315SJed Brown 521dfe15315SJed Brown PetscFunctionBegin; 52216ebb321SJed Brown if (PetscLogPrintInfo) { 52316ebb321SJed Brown PetscInt finelevel,coarselevel,fineclevel,coarseclevel; 52416ebb321SJed Brown ierr = DMGetRefineLevel(dmfine,&finelevel);CHKERRQ(ierr); 52516ebb321SJed Brown ierr = DMGetCoarsenLevel(dmfine,&fineclevel);CHKERRQ(ierr); 52616ebb321SJed Brown ierr = DMGetRefineLevel(dmcoarse,&coarselevel);CHKERRQ(ierr); 52716ebb321SJed Brown ierr = DMGetCoarsenLevel(dmcoarse,&coarseclevel);CHKERRQ(ierr); 52816ebb321SJed Brown ierr = PetscInfo4(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel);CHKERRQ(ierr); 52916ebb321SJed Brown } 530dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 531dfe15315SJed Brown else { 532dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr); 533dfe15315SJed Brown Xfine = Xfine_named; 534dfe15315SJed Brown } 535dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 536907f5c5aSLawrence Mitchell if (Inject) { 537907f5c5aSLawrence Mitchell ierr = MatRestrict(Inject,Xfine,Xcoarse);CHKERRQ(ierr); 538907f5c5aSLawrence Mitchell } else { 539dfe15315SJed Brown ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr); 540dfe15315SJed Brown ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr); 541907f5c5aSLawrence Mitchell } 542dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 543dfe15315SJed Brown if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);} 544dfe15315SJed Brown PetscFunctionReturn(0); 545dfe15315SJed Brown } 546dfe15315SJed Brown 54716ebb321SJed Brown static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx) 54816ebb321SJed Brown { 54916ebb321SJed Brown PetscErrorCode ierr; 55016ebb321SJed Brown 55116ebb321SJed Brown PetscFunctionBegin; 55216ebb321SJed Brown ierr = DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);CHKERRQ(ierr); 55316ebb321SJed Brown PetscFunctionReturn(0); 55416ebb321SJed Brown } 55516ebb321SJed Brown 556a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 557a6950cb2SJed Brown * safely call SNESGetDM() in their residual evaluation routine. */ 55823ee1639SBarry Smith static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx) 559caa4e7f2SJed Brown { 560caa4e7f2SJed Brown SNES snes = (SNES)ctx; 561caa4e7f2SJed Brown PetscErrorCode ierr; 5620298fd71SBarry Smith Vec X,Xnamed = NULL; 563dfe15315SJed Brown DM dmsave; 5644e269d77SPeter Brune void *ctxsave; 56525ce1634SJed Brown PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*) = NULL; 566caa4e7f2SJed Brown 567caa4e7f2SJed Brown PetscFunctionBegin; 568dfe15315SJed Brown dmsave = snes->dm; 569dfe15315SJed Brown ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr); 570dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 571dfe15315SJed Brown else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ 572dfe15315SJed Brown ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 573dfe15315SJed Brown X = Xnamed; 5740298fd71SBarry Smith ierr = SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave);CHKERRQ(ierr); 5754e269d77SPeter Brune /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */ 5768d359177SBarry Smith if (jac == SNESComputeJacobianDefaultColor) { 5778d359177SBarry Smith ierr = SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr); 578dfe15315SJed Brown } 5794e269d77SPeter Brune } 5804e269d77SPeter Brune 581*2b93b426SMatthew G. Knepley /* Compute the operators */ 582d1e9a80fSBarry Smith ierr = SNESComputeJacobian(snes,X,A,B);CHKERRQ(ierr); 583*2b93b426SMatthew G. Knepley /* Put the previous context back */ 5848d359177SBarry Smith if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) { 5850298fd71SBarry Smith ierr = SNESSetJacobian(snes,NULL,NULL,jac,ctxsave);CHKERRQ(ierr); 5864e269d77SPeter Brune } 5874e269d77SPeter Brune 588*2b93b426SMatthew G. Knepley if (Xnamed) {ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);} 589dfe15315SJed Brown snes->dm = dmsave; 590caa4e7f2SJed Brown PetscFunctionReturn(0); 591caa4e7f2SJed Brown } 592caa4e7f2SJed Brown 5936cab3a1bSJed Brown /*@ 5946cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 5956cab3a1bSJed Brown 5966cab3a1bSJed Brown Collective 5976cab3a1bSJed Brown 5986cab3a1bSJed Brown Input Arguments: 5996cab3a1bSJed Brown . snes - snes to configure 6006cab3a1bSJed Brown 6016cab3a1bSJed Brown Level: developer 6026cab3a1bSJed Brown 6036cab3a1bSJed Brown .seealso: SNESSetUp() 6046cab3a1bSJed Brown @*/ 6056cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 6066cab3a1bSJed Brown { 6076cab3a1bSJed Brown PetscErrorCode ierr; 6086cab3a1bSJed Brown DM dm; 609942e3340SBarry Smith DMSNES sdm; 6106cab3a1bSJed Brown 6116cab3a1bSJed Brown PetscFunctionBegin; 6126cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 613942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 614ce94432eSBarry Smith if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"DMSNES not properly configured"); 615f5af7f23SKarl Rupp else if (!snes->jacobian && snes->mf) { 6166cab3a1bSJed Brown Mat J; 6176cab3a1bSJed Brown void *functx; 6186cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 6196cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 6206cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 6210298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 6223232da50SPeter Brune ierr = SNESSetJacobian(snes,J,J,0,0);CHKERRQ(ierr); 6236cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 624caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 6256cab3a1bSJed Brown Mat J,B; 6266cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 6276cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 6286cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 629b412c318SBarry Smith ierr = DMCreateMatrix(snes->dm,&B);CHKERRQ(ierr); 63006f20277SJed Brown /* sdm->computejacobian was already set to reach here */ 6310298fd71SBarry Smith ierr = SNESSetJacobian(snes,J,B,NULL,NULL);CHKERRQ(ierr); 6326cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 6336cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 634caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 6354f3e65b0SMatthew G. Knepley PetscErrorCode (*nspconstr)(DM, PetscInt, MatNullSpace *); 6361ba9b98eSMatthew G. Knepley PetscDS prob; 6376cab3a1bSJed Brown Mat J, B; 6384f3e65b0SMatthew G. Knepley MatNullSpace nullspace = NULL; 6391ba9b98eSMatthew G. Knepley PetscBool hasPrec = PETSC_FALSE; 6404f3e65b0SMatthew G. Knepley PetscInt Nf; 6411ba9b98eSMatthew G. Knepley 6426cab3a1bSJed Brown J = snes->jacobian; 6431ba9b98eSMatthew G. Knepley ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 6441ba9b98eSMatthew G. Knepley if (prob) {ierr = PetscDSHasJacobianPreconditioner(prob, &hasPrec);CHKERRQ(ierr);} 645ec9a985fSMatthew G. Knepley if (J) {ierr = PetscObjectReference((PetscObject) J);CHKERRQ(ierr);} 646ec9a985fSMatthew G. Knepley else if (hasPrec) {ierr = DMCreateMatrix(snes->dm, &J);CHKERRQ(ierr);} 647b412c318SBarry Smith ierr = DMCreateMatrix(snes->dm, &B);CHKERRQ(ierr); 6484f3e65b0SMatthew G. Knepley ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 6494f3e65b0SMatthew G. Knepley ierr = DMGetNullSpaceConstructor(snes->dm, Nf, &nspconstr);CHKERRQ(ierr); 6504f3e65b0SMatthew G. Knepley if (nspconstr) (*nspconstr)(snes->dm, -1, &nullspace); 6514f3e65b0SMatthew G. Knepley ierr = MatSetNullSpace(B, nullspace);CHKERRQ(ierr); 6524f3e65b0SMatthew G. Knepley ierr = MatNullSpaceDestroy(&nullspace);CHKERRQ(ierr); 6530298fd71SBarry Smith ierr = SNESSetJacobian(snes, J ? J : B, B, NULL, NULL);CHKERRQ(ierr); 6541ba9b98eSMatthew G. Knepley ierr = MatDestroy(&J);CHKERRQ(ierr); 6556cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 6566cab3a1bSJed Brown } 657caa4e7f2SJed Brown { 658caa4e7f2SJed Brown KSP ksp; 659caa4e7f2SJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 660caa4e7f2SJed Brown ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr); 66116ebb321SJed Brown ierr = DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 662caa4e7f2SJed Brown } 6636cab3a1bSJed Brown PetscFunctionReturn(0); 6646cab3a1bSJed Brown } 6656cab3a1bSJed Brown 666fde5950dSBarry Smith /*@C 667fde5950dSBarry Smith SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 668fde5950dSBarry Smith 669fde5950dSBarry Smith Collective on SNES 670fde5950dSBarry Smith 671fde5950dSBarry Smith Input Parameters: 672fde5950dSBarry Smith + snes - SNES object you wish to monitor 673fde5950dSBarry Smith . name - the monitor type one is seeking 674fde5950dSBarry Smith . help - message indicating what monitoring is done 675fde5950dSBarry Smith . manual - manual page for the monitor 676fde5950dSBarry Smith . monitor - the monitor function 677fde5950dSBarry 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 678fde5950dSBarry Smith 679fde5950dSBarry Smith Level: developer 680fde5950dSBarry Smith 681fde5950dSBarry Smith .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 682fde5950dSBarry Smith PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 683fde5950dSBarry Smith PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 684fde5950dSBarry Smith PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 685fde5950dSBarry Smith PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 686fde5950dSBarry Smith PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 687fde5950dSBarry Smith PetscOptionsFList(), PetscOptionsEList() 688fde5950dSBarry Smith @*/ 689d43b4f6eSBarry Smith PetscErrorCode SNESMonitorSetFromOptions(SNES snes,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNES,PetscViewerAndFormat*)) 690fde5950dSBarry Smith { 691fde5950dSBarry Smith PetscErrorCode ierr; 692fde5950dSBarry Smith PetscViewer viewer; 693fde5950dSBarry Smith PetscViewerFormat format; 694fde5950dSBarry Smith PetscBool flg; 695fde5950dSBarry Smith 696fde5950dSBarry Smith PetscFunctionBegin; 697fde5950dSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr); 698fde5950dSBarry Smith if (flg) { 699d43b4f6eSBarry Smith PetscViewerAndFormat *vf; 700d43b4f6eSBarry Smith ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr); 701d43b4f6eSBarry Smith ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr); 702fde5950dSBarry Smith if (monitorsetup) { 703d43b4f6eSBarry Smith ierr = (*monitorsetup)(snes,vf);CHKERRQ(ierr); 704fde5950dSBarry Smith } 705d43b4f6eSBarry Smith ierr = SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr); 706fde5950dSBarry Smith } 707fde5950dSBarry Smith PetscFunctionReturn(0); 708fde5950dSBarry Smith } 709fde5950dSBarry Smith 7109b94acceSBarry Smith /*@ 71194b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 7129b94acceSBarry Smith 713c7afd0dbSLois Curfman McInnes Collective on SNES 714c7afd0dbSLois Curfman McInnes 7159b94acceSBarry Smith Input Parameter: 7169b94acceSBarry Smith . snes - the SNES context 7179b94acceSBarry Smith 71836851e7fSLois Curfman McInnes Options Database Keys: 719722329fbSBarry Smith + -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list 72082738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 72182738288SBarry Smith of the change in the solution between steps 72270441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 723b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 724e4d06f11SPatrick Farrell . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 725be5caee7SBarry Smith . -snes_force_iteration <force> - force SNESSolve() to take at least one iteration 726b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 727b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 7284839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 729ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 730a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 731e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 732b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 7332492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 73482738288SBarry Smith solver; hence iterations will continue until max_it 7351fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 73682738288SBarry Smith of convergence test 737fde5950dSBarry Smith . -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout 738fde5950dSBarry Smith . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 739fde5950dSBarry Smith . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 740fde5950dSBarry Smith . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 7414619e776SBarry Smith . -snes_monitor_lg_residualnorm - plots residual norm at each iteration 742459f5d12SBarry Smith . -snes_monitor_lg_range - plots residual norm at each iteration 743e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 744e2e60de9SPeter Brune . -snes_fd_color - use finite differences with coloring to compute Jacobian 7455968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 746fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 74782738288SBarry Smith 74882738288SBarry Smith Options Database for Eisenstat-Walker method: 749fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 7504b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 75136851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 75236851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 75336851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 75436851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 75536851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 75636851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 75782738288SBarry Smith 75811ca99fdSLois Curfman McInnes Notes: 75911ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 760a7f22e61SSatish Balay Users-Manual: ch_snes 76183e2fdc7SBarry Smith 76236851e7fSLois Curfman McInnes Level: beginner 76336851e7fSLois Curfman McInnes 7649b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 7659b94acceSBarry Smith 766b3cd9a81SMatthew G. Knepley .seealso: SNESSetOptionsPrefix(), SNESResetFromOptions() 7679b94acceSBarry Smith @*/ 7687087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 7699b94acceSBarry Smith { 7708afaa268SBarry Smith PetscBool flg,pcset,persist,set; 771d8f46077SPeter Brune PetscInt i,indx,lag,grids; 77204d7464bSBarry Smith const char *deft = SNESNEWTONLS; 77385385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 77485385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 775e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 77685385478SLisandro Dalcin PetscErrorCode ierr; 777c40d0f55SPeter Brune PCSide pcside; 778a64e098fSPeter Brune const char *optionsprefix; 7799b94acceSBarry Smith 7803a40ed3dSBarry Smith PetscFunctionBegin; 7810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7820f51fdf8SToby Isaac ierr = SNESRegisterAll();CHKERRQ(ierr); 7833194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 784639ff905SBarry Smith if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name; 785a264d7a6SBarry Smith ierr = PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 786d64ed03dSBarry Smith if (flg) { 787186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 7887adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 789186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 790d64ed03dSBarry Smith } 79194ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL);CHKERRQ(ierr); 79294ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL);CHKERRQ(ierr); 793186905e3SBarry Smith 79494ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL);CHKERRQ(ierr); 795e4d06f11SPatrick Farrell ierr = PetscOptionsReal("-snes_divergence_tolerance","Stop if residual norm increases by this factor","SNESSetDivergenceTolerance",snes->divtol,&snes->divtol,NULL);CHKERRQ(ierr); 7960298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL);CHKERRQ(ierr); 7970298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL);CHKERRQ(ierr); 7980298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL);CHKERRQ(ierr); 7990298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL);CHKERRQ(ierr); 8000298fd71SBarry Smith ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL);CHKERRQ(ierr); 8010d6f27a8SBarry Smith ierr = PetscOptionsBool("-snes_force_iteration","Force SNESSolve() to take at least one iteration","SNESSetForceIteration",snes->forceiteration,&snes->forceiteration,NULL);CHKERRQ(ierr); 80285385478SLisandro Dalcin 803a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 804a8054027SBarry Smith if (flg) { 805a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 806a8054027SBarry Smith } 80737ec4e1aSPeter Brune ierr = PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr); 80837ec4e1aSPeter Brune if (flg) { 80937ec4e1aSPeter Brune ierr = SNESSetLagPreconditionerPersists(snes,persist);CHKERRQ(ierr); 81037ec4e1aSPeter Brune } 811e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 812e35cf81dSBarry Smith if (flg) { 813e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 814e35cf81dSBarry Smith } 81537ec4e1aSPeter Brune ierr = PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr); 81637ec4e1aSPeter Brune if (flg) { 81737ec4e1aSPeter Brune ierr = SNESSetLagJacobianPersists(snes,persist);CHKERRQ(ierr); 81837ec4e1aSPeter Brune } 81937ec4e1aSPeter Brune 820efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 821efd51863SBarry Smith if (flg) { 822efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 823efd51863SBarry Smith } 824a8054027SBarry Smith 82585385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 82685385478SLisandro Dalcin if (flg) { 82785385478SLisandro Dalcin switch (indx) { 8288d359177SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL);CHKERRQ(ierr); break; 829e2a6519dSDmitry Karpeev case 1: ierr = SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL);CHKERRQ(ierr); break; 83085385478SLisandro Dalcin } 83185385478SLisandro Dalcin } 83285385478SLisandro Dalcin 833365a6726SPeter Brune ierr = PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg);CHKERRQ(ierr); 834365a6726SPeter Brune if (flg) { ierr = SNESSetNormSchedule(snes,(SNESNormSchedule)indx);CHKERRQ(ierr); } 835fdacfa88SPeter Brune 83647073ea2SPeter Brune ierr = PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg);CHKERRQ(ierr); 83747073ea2SPeter Brune if (flg) { ierr = SNESSetFunctionType(snes,(SNESFunctionType)indx);CHKERRQ(ierr); } 838186905e3SBarry Smith 83985385478SLisandro Dalcin kctx = (SNESKSPEW*)snes->kspconvctx; 84085385478SLisandro Dalcin 8410298fd71SBarry Smith ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL);CHKERRQ(ierr); 842186905e3SBarry Smith 84394ae4db5SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL);CHKERRQ(ierr); 84494ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL);CHKERRQ(ierr); 84594ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL);CHKERRQ(ierr); 84694ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL);CHKERRQ(ierr); 84794ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL);CHKERRQ(ierr); 84894ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL);CHKERRQ(ierr); 84994ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL);CHKERRQ(ierr); 850186905e3SBarry Smith 85190d69ab7SBarry Smith flg = PETSC_FALSE; 8528afaa268SBarry Smith ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set);CHKERRQ(ierr); 8538afaa268SBarry Smith if (set && flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 854eabae89aSBarry Smith 855fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,NULL);CHKERRQ(ierr); 856fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_short","Monitor norm of function with fewer digits","SNESMonitorDefaultShort",SNESMonitorDefaultShort,NULL);CHKERRQ(ierr); 857fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_range","Monitor range of elements of function","SNESMonitorRange",SNESMonitorRange,NULL);CHKERRQ(ierr); 858eabae89aSBarry Smith 859fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_ratio","Monitor ratios of the norm of function for consecutive steps","SNESMonitorRatio",SNESMonitorRatio,SNESMonitorRatioSetUp);CHKERRQ(ierr); 860fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorDefaultField",SNESMonitorDefaultField,NULL);CHKERRQ(ierr); 861fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution","View solution at each iteration","SNESMonitorSolution",SNESMonitorSolution,NULL);CHKERRQ(ierr); 862fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution_update","View correction at each iteration","SNESMonitorSolutionUpdate",SNESMonitorSolutionUpdate,NULL);CHKERRQ(ierr); 863fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_residual","View residual at each iteration","SNESMonitorResidual",SNESMonitorResidual,NULL);CHKERRQ(ierr); 864fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",SNESMonitorJacUpdateSpectrum,NULL);CHKERRQ(ierr); 865fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet",SNESMonitorFields,NULL);CHKERRQ(ierr); 8662db13446SMatthew G. Knepley 8675180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 8685180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 8695180491cSLisandro Dalcin 870fde5950dSBarry Smith 87190d69ab7SBarry Smith flg = PETSC_FALSE; 8720298fd71SBarry Smith ierr = PetscOptionsBool("-snes_monitor_lg_residualnorm","Plot function norm at each iteration","SNESMonitorLGResidualNorm",flg,&flg,NULL);CHKERRQ(ierr); 873459f5d12SBarry Smith if (flg) { 874d96771aaSLisandro Dalcin PetscDrawLG ctx; 875459f5d12SBarry Smith 8766ba87a44SLisandro Dalcin ierr = SNESMonitorLGCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr); 877d96771aaSLisandro Dalcin ierr = SNESMonitorSet(snes,SNESMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);CHKERRQ(ierr); 878459f5d12SBarry Smith } 87990d69ab7SBarry Smith flg = PETSC_FALSE; 8800298fd71SBarry Smith ierr = PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL);CHKERRQ(ierr); 881459f5d12SBarry Smith if (flg) { 882459f5d12SBarry Smith PetscViewer ctx; 883e24b481bSBarry Smith 8846ba87a44SLisandro Dalcin ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr); 885459f5d12SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 886459f5d12SBarry Smith } 8872e7541e6SPeter Brune 8882e7541e6SPeter Brune 889cc0c4584SMatthew G. Knepley 89090d69ab7SBarry Smith flg = PETSC_FALSE; 8918d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL);CHKERRQ(ierr); 8924b27c08aSLois Curfman McInnes if (flg) { 8936cab3a1bSJed Brown void *functx; 894b1f624c7SBarry Smith DM dm; 895b1f624c7SBarry Smith DMSNES sdm; 896b1f624c7SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 897b1f624c7SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 898b1f624c7SBarry Smith sdm->jacobianctx = NULL; 8990298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 9008d359177SBarry Smith ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx);CHKERRQ(ierr); 901ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 9029b94acceSBarry Smith } 903639f9d9dSBarry Smith 90444848bc4SPeter Brune flg = PETSC_FALSE; 9058d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL);CHKERRQ(ierr); 90697584545SPeter Brune if (flg) { 9078d359177SBarry Smith ierr = SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL);CHKERRQ(ierr); 90897584545SPeter Brune } 90997584545SPeter Brune 91097584545SPeter Brune flg = PETSC_FALSE; 9118d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL);CHKERRQ(ierr); 91244848bc4SPeter Brune if (flg) { 913c52e227fSPeter Brune DM dm; 914c52e227fSPeter Brune DMSNES sdm; 915c52e227fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 916aace71b7SPeter Brune ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 917aace71b7SPeter Brune sdm->jacobianctx = NULL; 9188d359177SBarry Smith ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr); 91944848bc4SPeter Brune ierr = PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr); 92044848bc4SPeter Brune } 92144848bc4SPeter Brune 922aa3661deSLisandro Dalcin flg = PETSC_FALSE; 923f871313dSBarry Smith ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf_operator,&flg);CHKERRQ(ierr); 924d8f46077SPeter Brune if (flg && snes->mf_operator) { 925a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 926d8f46077SPeter Brune snes->mf = PETSC_TRUE; 927a8248277SBarry Smith } 928aa3661deSLisandro Dalcin flg = PETSC_FALSE; 929f871313dSBarry Smith ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf,&flg);CHKERRQ(ierr); 930d8f46077SPeter Brune if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 931d8f46077SPeter Brune ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,0);CHKERRQ(ierr); 932d28543b3SPeter Brune 933c40d0f55SPeter Brune flg = PETSC_FALSE; 934be95d8f1SBarry Smith ierr = SNESGetNPCSide(snes,&pcside);CHKERRQ(ierr); 935be95d8f1SBarry Smith ierr = PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr); 936be95d8f1SBarry Smith if (flg) {ierr = SNESSetNPCSide(snes,pcside);CHKERRQ(ierr);} 937c40d0f55SPeter Brune 938e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 9398a70d858SHong Zhang /* 9408a70d858SHong Zhang Publish convergence information using SAWs 9418a70d858SHong Zhang */ 9428a70d858SHong Zhang flg = PETSC_FALSE; 9438a70d858SHong Zhang ierr = PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); 9448a70d858SHong Zhang if (flg) { 9458a70d858SHong Zhang void *ctx; 9468a70d858SHong Zhang ierr = SNESMonitorSAWsCreate(snes,&ctx);CHKERRQ(ierr); 9478a70d858SHong Zhang ierr = SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy);CHKERRQ(ierr); 9488a70d858SHong Zhang } 9498a70d858SHong Zhang #endif 9508a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS) 951b90c6cbeSBarry Smith { 952b90c6cbeSBarry Smith PetscBool set; 953b90c6cbeSBarry Smith flg = PETSC_FALSE; 9548a70d858SHong Zhang ierr = PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set);CHKERRQ(ierr); 955b90c6cbeSBarry Smith if (set) { 956e04113cfSBarry Smith ierr = PetscObjectSAWsSetBlock((PetscObject)snes,flg);CHKERRQ(ierr); 957b90c6cbeSBarry Smith } 958b90c6cbeSBarry Smith } 959b90c6cbeSBarry Smith #endif 960b90c6cbeSBarry Smith 96176b2cf59SMatthew Knepley for (i = 0; i < numberofsetfromoptions; i++) { 96276b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 96376b2cf59SMatthew Knepley } 96476b2cf59SMatthew Knepley 965e7788613SBarry Smith if (snes->ops->setfromoptions) { 966e55864a3SBarry Smith ierr = (*snes->ops->setfromoptions)(PetscOptionsObject,snes);CHKERRQ(ierr); 967639f9d9dSBarry Smith } 9685d973c19SBarry Smith 9695d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 9700633abcbSJed Brown ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)snes);CHKERRQ(ierr); 971b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 9724bbc92c1SBarry Smith 9739e764e56SPeter Brune if (!snes->linesearch) { 9747601faf0SJed Brown ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 9759e764e56SPeter Brune } 976f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 9779e764e56SPeter Brune 9786991f827SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 9796991f827SBarry Smith ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr); 9806991f827SBarry Smith ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 9816991f827SBarry Smith 982be95d8f1SBarry Smith /* if someone has set the SNES NPC type, create it. */ 98351e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 984c5929fdfSBarry Smith ierr = PetscOptionsHasName(((PetscObject)snes)->options,optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 985efd4aadfSBarry Smith if (pcset && (!snes->npc)) { 986efd4aadfSBarry Smith ierr = SNESGetNPC(snes, &snes->npc);CHKERRQ(ierr); 98751e86f29SPeter Brune } 988b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled++; 989b3cd9a81SMatthew G. Knepley PetscFunctionReturn(0); 990b3cd9a81SMatthew G. Knepley } 991b3cd9a81SMatthew G. Knepley 992b3cd9a81SMatthew G. Knepley /*@ 993b3cd9a81SMatthew G. Knepley SNESResetFromOptions - Sets various SNES and KSP parameters from user options ONLY if the SNES was previously set from options 994b3cd9a81SMatthew G. Knepley 995b3cd9a81SMatthew G. Knepley Collective on SNES 996b3cd9a81SMatthew G. Knepley 997b3cd9a81SMatthew G. Knepley Input Parameter: 998b3cd9a81SMatthew G. Knepley . snes - the SNES context 999b3cd9a81SMatthew G. Knepley 1000b3cd9a81SMatthew G. Knepley Level: beginner 1001b3cd9a81SMatthew G. Knepley 1002b3cd9a81SMatthew G. Knepley .keywords: SNES, nonlinear, set, options, database 1003b3cd9a81SMatthew G. Knepley 1004b3cd9a81SMatthew G. Knepley .seealso: SNESSetFromOptions(), SNESSetOptionsPrefix() 1005b3cd9a81SMatthew G. Knepley @*/ 1006b3cd9a81SMatthew G. Knepley PetscErrorCode SNESResetFromOptions(SNES snes) 1007b3cd9a81SMatthew G. Knepley { 1008b3cd9a81SMatthew G. Knepley PetscErrorCode ierr; 1009b3cd9a81SMatthew G. Knepley 1010b3cd9a81SMatthew G. Knepley PetscFunctionBegin; 1011b3cd9a81SMatthew G. Knepley if (snes->setfromoptionscalled) {ierr = SNESSetFromOptions(snes);CHKERRQ(ierr);} 10123a40ed3dSBarry Smith PetscFunctionReturn(0); 10139b94acceSBarry Smith } 10149b94acceSBarry Smith 1015bb9467b5SJed Brown /*@C 1016d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 1017d25893d9SBarry Smith the nonlinear solvers. 1018d25893d9SBarry Smith 1019d25893d9SBarry Smith Logically Collective on SNES 1020d25893d9SBarry Smith 1021d25893d9SBarry Smith Input Parameters: 1022d25893d9SBarry Smith + snes - the SNES context 1023d25893d9SBarry Smith . compute - function to compute the context 1024d25893d9SBarry Smith - destroy - function to destroy the context 1025d25893d9SBarry Smith 1026d25893d9SBarry Smith Level: intermediate 1027d25893d9SBarry Smith 1028bb9467b5SJed Brown Notes: 1029bb9467b5SJed Brown This function is currently not available from Fortran. 1030bb9467b5SJed Brown 1031d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 1032d25893d9SBarry Smith 1033d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 1034d25893d9SBarry Smith @*/ 1035d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 1036d25893d9SBarry Smith { 1037d25893d9SBarry Smith PetscFunctionBegin; 1038d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1039d25893d9SBarry Smith snes->ops->usercompute = compute; 1040d25893d9SBarry Smith snes->ops->userdestroy = destroy; 1041d25893d9SBarry Smith PetscFunctionReturn(0); 1042d25893d9SBarry Smith } 1043a847f771SSatish Balay 1044b07ff414SBarry Smith /*@ 10459b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 10469b94acceSBarry Smith the nonlinear solvers. 10479b94acceSBarry Smith 10483f9fe445SBarry Smith Logically Collective on SNES 1049fee21e36SBarry Smith 1050c7afd0dbSLois Curfman McInnes Input Parameters: 1051c7afd0dbSLois Curfman McInnes + snes - the SNES context 1052c7afd0dbSLois Curfman McInnes - usrP - optional user context 1053c7afd0dbSLois Curfman McInnes 105436851e7fSLois Curfman McInnes Level: intermediate 105536851e7fSLois Curfman McInnes 105695452b02SPatrick Sanan Fortran Notes: 105795452b02SPatrick Sanan To use this from Fortran you must write a Fortran interface definition for this 1058daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1059daf670e6SBarry Smith 10609b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 10619b94acceSBarry Smith 1062ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext() 10639b94acceSBarry Smith @*/ 10647087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 10659b94acceSBarry Smith { 10661b2093e4SBarry Smith PetscErrorCode ierr; 1067b07ff414SBarry Smith KSP ksp; 10681b2093e4SBarry Smith 10693a40ed3dSBarry Smith PetscFunctionBegin; 10700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1071b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 1072b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 10739b94acceSBarry Smith snes->user = usrP; 10743a40ed3dSBarry Smith PetscFunctionReturn(0); 10759b94acceSBarry Smith } 107674679c65SBarry Smith 1077b07ff414SBarry Smith /*@ 10789b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 10799b94acceSBarry Smith nonlinear solvers. 10809b94acceSBarry Smith 1081c7afd0dbSLois Curfman McInnes Not Collective 1082c7afd0dbSLois Curfman McInnes 10839b94acceSBarry Smith Input Parameter: 10849b94acceSBarry Smith . snes - SNES context 10859b94acceSBarry Smith 10869b94acceSBarry Smith Output Parameter: 10879b94acceSBarry Smith . usrP - user context 10889b94acceSBarry Smith 108995452b02SPatrick Sanan Fortran Notes: 109095452b02SPatrick Sanan To use this from Fortran you must write a Fortran interface definition for this 1091daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1092daf670e6SBarry Smith 109336851e7fSLois Curfman McInnes Level: intermediate 109436851e7fSLois Curfman McInnes 10959b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 10969b94acceSBarry Smith 10979b94acceSBarry Smith .seealso: SNESSetApplicationContext() 10989b94acceSBarry Smith @*/ 1099e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 11009b94acceSBarry Smith { 11013a40ed3dSBarry Smith PetscFunctionBegin; 11020700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1103e71120c6SJed Brown *(void**)usrP = snes->user; 11043a40ed3dSBarry Smith PetscFunctionReturn(0); 11059b94acceSBarry Smith } 110674679c65SBarry Smith 11079b94acceSBarry Smith /*@ 11083565c898SBarry Smith SNESSetUseMatrixFree - indicates that SNES should use matrix free finite difference matrix vector products internally to apply 11093565c898SBarry Smith the Jacobian. 11103565c898SBarry Smith 11113565c898SBarry Smith Collective on SNES 11123565c898SBarry Smith 11133565c898SBarry Smith Input Parameters: 11143565c898SBarry Smith + snes - SNES context 11153565c898SBarry 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 11163565c898SBarry Smith - mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 11173565c898SBarry Smith 11183565c898SBarry Smith Options Database: 11193565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator 11203565c898SBarry Smith - -snes_mf_operator - use matrix free only for the mat operator 11213565c898SBarry Smith 11223565c898SBarry Smith Level: intermediate 11233565c898SBarry Smith 11243565c898SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 11253565c898SBarry Smith 11263565c898SBarry Smith .seealso: SNESGetUseMatrixFree(), MatCreateSNESMF() 11273565c898SBarry Smith @*/ 11283565c898SBarry Smith PetscErrorCode SNESSetUseMatrixFree(SNES snes,PetscBool mf_operator,PetscBool mf) 11293565c898SBarry Smith { 11303565c898SBarry Smith PetscFunctionBegin; 11313565c898SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 113288b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes,mf_operator,2); 113388b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes,mf,3); 11343565c898SBarry Smith if (mf && !mf_operator) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"If using mf must also use mf_operator"); 11353565c898SBarry Smith snes->mf = mf; 11363565c898SBarry Smith snes->mf_operator = mf_operator; 11373565c898SBarry Smith PetscFunctionReturn(0); 11383565c898SBarry Smith } 11393565c898SBarry Smith 11403565c898SBarry Smith /*@ 11413565c898SBarry Smith SNESGetUseMatrixFree - indicates if the SNES uses matrix free finite difference matrix vector products to apply 11423565c898SBarry Smith the Jacobian. 11433565c898SBarry Smith 11443565c898SBarry Smith Collective on SNES 11453565c898SBarry Smith 11463565c898SBarry Smith Input Parameter: 11473565c898SBarry Smith . snes - SNES context 11483565c898SBarry Smith 11493565c898SBarry Smith Output Parameters: 11503565c898SBarry 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 11513565c898SBarry Smith - mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 11523565c898SBarry Smith 11533565c898SBarry Smith Options Database: 11543565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator 11553565c898SBarry Smith - -snes_mf_operator - use matrix free only for the mat operator 11563565c898SBarry Smith 11573565c898SBarry Smith Level: intermediate 11583565c898SBarry Smith 11593565c898SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 11603565c898SBarry Smith 11613565c898SBarry Smith .seealso: SNESSetUseMatrixFree(), MatCreateSNESMF() 11623565c898SBarry Smith @*/ 11633565c898SBarry Smith PetscErrorCode SNESGetUseMatrixFree(SNES snes,PetscBool *mf_operator,PetscBool *mf) 11643565c898SBarry Smith { 11653565c898SBarry Smith PetscFunctionBegin; 11663565c898SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11673565c898SBarry Smith if (mf) *mf = snes->mf; 11683565c898SBarry Smith if (mf_operator) *mf_operator = snes->mf_operator; 11693565c898SBarry Smith PetscFunctionReturn(0); 11703565c898SBarry Smith } 11713565c898SBarry Smith 11723565c898SBarry Smith /*@ 1173c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 1174c8228a4eSBarry Smith at this time. 11759b94acceSBarry Smith 1176c7afd0dbSLois Curfman McInnes Not Collective 1177c7afd0dbSLois Curfman McInnes 11789b94acceSBarry Smith Input Parameter: 11799b94acceSBarry Smith . snes - SNES context 11809b94acceSBarry Smith 11819b94acceSBarry Smith Output Parameter: 11829b94acceSBarry Smith . iter - iteration number 11839b94acceSBarry Smith 1184c8228a4eSBarry Smith Notes: 1185c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 1186c8228a4eSBarry Smith 1187c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 118808405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 118908405cd6SLois Curfman McInnes .vb 119008405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 119108405cd6SLois Curfman McInnes if (!(it % 2)) { 119208405cd6SLois Curfman McInnes [compute Jacobian here] 119308405cd6SLois Curfman McInnes } 119408405cd6SLois Curfman McInnes .ve 1195c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 119608405cd6SLois Curfman McInnes recomputed every second SNES iteration. 1197c8228a4eSBarry Smith 1198c04deec6SBarry Smith After the SNES solve is complete this will return the number of nonlinear iterations used. 1199c04deec6SBarry Smith 120036851e7fSLois Curfman McInnes Level: intermediate 120136851e7fSLois Curfman McInnes 12022b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 12032b668275SBarry Smith 120471dbe336SPeter Brune .seealso: SNESGetLinearSolveIterations() 12059b94acceSBarry Smith @*/ 12067087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt *iter) 12079b94acceSBarry Smith { 12083a40ed3dSBarry Smith PetscFunctionBegin; 12090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12104482741eSBarry Smith PetscValidIntPointer(iter,2); 12119b94acceSBarry Smith *iter = snes->iter; 12123a40ed3dSBarry Smith PetscFunctionReturn(0); 12139b94acceSBarry Smith } 121474679c65SBarry Smith 1215360c497dSPeter Brune /*@ 1216360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 1217360c497dSPeter Brune 1218360c497dSPeter Brune Not Collective 1219360c497dSPeter Brune 1220360c497dSPeter Brune Input Parameter: 1221360c497dSPeter Brune . snes - SNES context 1222360c497dSPeter Brune . iter - iteration number 1223360c497dSPeter Brune 1224360c497dSPeter Brune Level: developer 1225360c497dSPeter Brune 1226360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 1227360c497dSPeter Brune 122871dbe336SPeter Brune .seealso: SNESGetLinearSolveIterations() 1229360c497dSPeter Brune @*/ 1230360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 1231360c497dSPeter Brune { 1232360c497dSPeter Brune PetscErrorCode ierr; 1233360c497dSPeter Brune 1234360c497dSPeter Brune PetscFunctionBegin; 1235360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1236e04113cfSBarry Smith ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr); 1237360c497dSPeter Brune snes->iter = iter; 1238e04113cfSBarry Smith ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr); 1239360c497dSPeter Brune PetscFunctionReturn(0); 1240360c497dSPeter Brune } 1241360c497dSPeter Brune 12429b94acceSBarry Smith /*@ 1243b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 12449b94acceSBarry Smith attempted by the nonlinear solver. 12459b94acceSBarry Smith 1246c7afd0dbSLois Curfman McInnes Not Collective 1247c7afd0dbSLois Curfman McInnes 12489b94acceSBarry Smith Input Parameter: 12499b94acceSBarry Smith . snes - SNES context 12509b94acceSBarry Smith 12519b94acceSBarry Smith Output Parameter: 12529b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 12539b94acceSBarry Smith 1254c96a6f78SLois Curfman McInnes Notes: 1255c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1256c96a6f78SLois Curfman McInnes 125736851e7fSLois Curfman McInnes Level: intermediate 125836851e7fSLois Curfman McInnes 12599b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 126058ebbce7SBarry Smith 1261e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 126258ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 12639b94acceSBarry Smith @*/ 12647087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails) 12659b94acceSBarry Smith { 12663a40ed3dSBarry Smith PetscFunctionBegin; 12670700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12684482741eSBarry Smith PetscValidIntPointer(nfails,2); 126950ffb88aSMatthew Knepley *nfails = snes->numFailures; 127050ffb88aSMatthew Knepley PetscFunctionReturn(0); 127150ffb88aSMatthew Knepley } 127250ffb88aSMatthew Knepley 127350ffb88aSMatthew Knepley /*@ 1274b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 127550ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 127650ffb88aSMatthew Knepley 127750ffb88aSMatthew Knepley Not Collective 127850ffb88aSMatthew Knepley 127950ffb88aSMatthew Knepley Input Parameters: 128050ffb88aSMatthew Knepley + snes - SNES context 128150ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 128250ffb88aSMatthew Knepley 128350ffb88aSMatthew Knepley Level: intermediate 128450ffb88aSMatthew Knepley 128550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 128658ebbce7SBarry Smith 1287e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 128858ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 128950ffb88aSMatthew Knepley @*/ 12907087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 129150ffb88aSMatthew Knepley { 129250ffb88aSMatthew Knepley PetscFunctionBegin; 12930700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 129450ffb88aSMatthew Knepley snes->maxFailures = maxFails; 129550ffb88aSMatthew Knepley PetscFunctionReturn(0); 129650ffb88aSMatthew Knepley } 129750ffb88aSMatthew Knepley 129850ffb88aSMatthew Knepley /*@ 1299b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 130050ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 130150ffb88aSMatthew Knepley 130250ffb88aSMatthew Knepley Not Collective 130350ffb88aSMatthew Knepley 130450ffb88aSMatthew Knepley Input Parameter: 130550ffb88aSMatthew Knepley . snes - SNES context 130650ffb88aSMatthew Knepley 130750ffb88aSMatthew Knepley Output Parameter: 130850ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 130950ffb88aSMatthew Knepley 131050ffb88aSMatthew Knepley Level: intermediate 131150ffb88aSMatthew Knepley 131250ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 131358ebbce7SBarry Smith 1314e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 131558ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 131658ebbce7SBarry Smith 131750ffb88aSMatthew Knepley @*/ 13187087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 131950ffb88aSMatthew Knepley { 132050ffb88aSMatthew Knepley PetscFunctionBegin; 13210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13224482741eSBarry Smith PetscValidIntPointer(maxFails,2); 132350ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 13243a40ed3dSBarry Smith PetscFunctionReturn(0); 13259b94acceSBarry Smith } 1326a847f771SSatish Balay 13272541af92SBarry Smith /*@ 13282541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 13292541af92SBarry Smith done by SNES. 13302541af92SBarry Smith 13312541af92SBarry Smith Not Collective 13322541af92SBarry Smith 13332541af92SBarry Smith Input Parameter: 13342541af92SBarry Smith . snes - SNES context 13352541af92SBarry Smith 13362541af92SBarry Smith Output Parameter: 13372541af92SBarry Smith . nfuncs - number of evaluations 13382541af92SBarry Smith 13392541af92SBarry Smith Level: intermediate 13402541af92SBarry Smith 134195452b02SPatrick Sanan Notes: 134295452b02SPatrick Sanan Reset every time SNESSolve is called unless SNESSetCountersReset() is used. 1343971e163fSPeter Brune 13442541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 134558ebbce7SBarry Smith 1346971e163fSPeter Brune .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), SNESSetCountersReset() 13472541af92SBarry Smith @*/ 13487087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 13492541af92SBarry Smith { 13502541af92SBarry Smith PetscFunctionBegin; 13510700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13522541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 13532541af92SBarry Smith *nfuncs = snes->nfuncs; 13542541af92SBarry Smith PetscFunctionReturn(0); 13552541af92SBarry Smith } 13562541af92SBarry Smith 13573d4c4710SBarry Smith /*@ 13583d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 13593d4c4710SBarry Smith linear solvers. 13603d4c4710SBarry Smith 13613d4c4710SBarry Smith Not Collective 13623d4c4710SBarry Smith 13633d4c4710SBarry Smith Input Parameter: 13643d4c4710SBarry Smith . snes - SNES context 13653d4c4710SBarry Smith 13663d4c4710SBarry Smith Output Parameter: 13673d4c4710SBarry Smith . nfails - number of failed solves 13683d4c4710SBarry Smith 13699d85da0cSMatthew G. Knepley Level: intermediate 13709d85da0cSMatthew G. Knepley 13719d85da0cSMatthew G. Knepley Options Database Keys: 13729d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 13739d85da0cSMatthew G. Knepley 13743d4c4710SBarry Smith Notes: 13753d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 13763d4c4710SBarry Smith 13773d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 137858ebbce7SBarry Smith 1379e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 13803d4c4710SBarry Smith @*/ 13817087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails) 13823d4c4710SBarry Smith { 13833d4c4710SBarry Smith PetscFunctionBegin; 13840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13853d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 13863d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 13873d4c4710SBarry Smith PetscFunctionReturn(0); 13883d4c4710SBarry Smith } 13893d4c4710SBarry Smith 13903d4c4710SBarry Smith /*@ 13913d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 13923d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 13933d4c4710SBarry Smith 13943f9fe445SBarry Smith Logically Collective on SNES 13953d4c4710SBarry Smith 13963d4c4710SBarry Smith Input Parameters: 13973d4c4710SBarry Smith + snes - SNES context 13983d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 13993d4c4710SBarry Smith 14003d4c4710SBarry Smith Level: intermediate 14013d4c4710SBarry Smith 14029d85da0cSMatthew G. Knepley Options Database Keys: 14039d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 14049d85da0cSMatthew G. Knepley 140595452b02SPatrick Sanan Notes: 140695452b02SPatrick Sanan By default this is 0; that is SNES returns on the first failed linear solve 14073d4c4710SBarry Smith 14083d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 14093d4c4710SBarry Smith 141058ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 14113d4c4710SBarry Smith @*/ 14127087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 14133d4c4710SBarry Smith { 14143d4c4710SBarry Smith PetscFunctionBegin; 14150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1416c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 14173d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 14183d4c4710SBarry Smith PetscFunctionReturn(0); 14193d4c4710SBarry Smith } 14203d4c4710SBarry Smith 14213d4c4710SBarry Smith /*@ 14223d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 14233d4c4710SBarry Smith are allowed before SNES terminates 14243d4c4710SBarry Smith 14253d4c4710SBarry Smith Not Collective 14263d4c4710SBarry Smith 14273d4c4710SBarry Smith Input Parameter: 14283d4c4710SBarry Smith . snes - SNES context 14293d4c4710SBarry Smith 14303d4c4710SBarry Smith Output Parameter: 14313d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 14323d4c4710SBarry Smith 14333d4c4710SBarry Smith Level: intermediate 14343d4c4710SBarry Smith 143595452b02SPatrick Sanan Notes: 143695452b02SPatrick Sanan By default this is 1; that is SNES returns on the first failed linear solve 14373d4c4710SBarry Smith 14383d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 14393d4c4710SBarry Smith 1440e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 14413d4c4710SBarry Smith @*/ 14427087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 14433d4c4710SBarry Smith { 14443d4c4710SBarry Smith PetscFunctionBegin; 14450700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14463d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 14473d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 14483d4c4710SBarry Smith PetscFunctionReturn(0); 14493d4c4710SBarry Smith } 14503d4c4710SBarry Smith 1451c96a6f78SLois Curfman McInnes /*@ 1452b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1453c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1454c96a6f78SLois Curfman McInnes 1455c7afd0dbSLois Curfman McInnes Not Collective 1456c7afd0dbSLois Curfman McInnes 1457c96a6f78SLois Curfman McInnes Input Parameter: 1458c96a6f78SLois Curfman McInnes . snes - SNES context 1459c96a6f78SLois Curfman McInnes 1460c96a6f78SLois Curfman McInnes Output Parameter: 1461c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1462c96a6f78SLois Curfman McInnes 1463c96a6f78SLois Curfman McInnes Notes: 1464971e163fSPeter Brune This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used. 1465c96a6f78SLois Curfman McInnes 1466010be392SBarry 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 1467010be392SBarry Smith then call KSPGetIterationNumber() after the failed solve. 1468010be392SBarry Smith 146936851e7fSLois Curfman McInnes Level: intermediate 147036851e7fSLois Curfman McInnes 1471c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 14722b668275SBarry Smith 147371dbe336SPeter Brune .seealso: SNESGetIterationNumber(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESSetCountersReset() 1474c96a6f78SLois Curfman McInnes @*/ 14757087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt *lits) 1476c96a6f78SLois Curfman McInnes { 14773a40ed3dSBarry Smith PetscFunctionBegin; 14780700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14794482741eSBarry Smith PetscValidIntPointer(lits,2); 1480c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 14813a40ed3dSBarry Smith PetscFunctionReturn(0); 1482c96a6f78SLois Curfman McInnes } 1483c96a6f78SLois Curfman McInnes 1484971e163fSPeter Brune /*@ 1485971e163fSPeter Brune SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations 1486971e163fSPeter Brune are reset every time SNESSolve() is called. 1487971e163fSPeter Brune 1488971e163fSPeter Brune Logically Collective on SNES 1489971e163fSPeter Brune 1490971e163fSPeter Brune Input Parameter: 1491971e163fSPeter Brune + snes - SNES context 1492971e163fSPeter Brune - reset - whether to reset the counters or not 1493971e163fSPeter Brune 1494971e163fSPeter Brune Notes: 1495fa19ca70SBarry Smith This defaults to PETSC_TRUE 1496971e163fSPeter Brune 1497971e163fSPeter Brune Level: developer 1498971e163fSPeter Brune 1499971e163fSPeter Brune .keywords: SNES, nonlinear, set, reset, number, linear, iterations 1500971e163fSPeter Brune 1501734794cfSBarry Smith .seealso: SNESGetNumberFunctionEvals(), SNESGetLinearSolveIterations(), SNESGetNPC() 1502971e163fSPeter Brune @*/ 1503971e163fSPeter Brune PetscErrorCode SNESSetCountersReset(SNES snes,PetscBool reset) 1504971e163fSPeter Brune { 1505971e163fSPeter Brune PetscFunctionBegin; 1506971e163fSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1507971e163fSPeter Brune PetscValidLogicalCollectiveBool(snes,reset,2); 1508971e163fSPeter Brune snes->counters_reset = reset; 1509971e163fSPeter Brune PetscFunctionReturn(0); 1510971e163fSPeter Brune } 1511971e163fSPeter Brune 151282bf6240SBarry Smith 15132999313aSBarry Smith /*@ 15142999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 15152999313aSBarry Smith 15162999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 15172999313aSBarry Smith 15182999313aSBarry Smith Input Parameters: 15192999313aSBarry Smith + snes - the SNES context 15202999313aSBarry Smith - ksp - the KSP context 15212999313aSBarry Smith 15222999313aSBarry Smith Notes: 15232999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 15242999313aSBarry Smith so this routine is rarely needed. 15252999313aSBarry Smith 15262999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 15272999313aSBarry Smith decreased by one. 15282999313aSBarry Smith 15292999313aSBarry Smith Level: developer 15302999313aSBarry Smith 15312999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 15322999313aSBarry Smith 15332999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 15342999313aSBarry Smith @*/ 15357087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 15362999313aSBarry Smith { 15372999313aSBarry Smith PetscErrorCode ierr; 15382999313aSBarry Smith 15392999313aSBarry Smith PetscFunctionBegin; 15400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15410700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 15422999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 15437dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1544906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 15452999313aSBarry Smith snes->ksp = ksp; 15462999313aSBarry Smith PetscFunctionReturn(0); 15472999313aSBarry Smith } 15482999313aSBarry Smith 15499b94acceSBarry Smith /* -----------------------------------------------------------*/ 155052baeb72SSatish Balay /*@ 15519b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 15529b94acceSBarry Smith 1553c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1554c7afd0dbSLois Curfman McInnes 1555c7afd0dbSLois Curfman McInnes Input Parameters: 1556906ed7ccSBarry Smith . comm - MPI communicator 15579b94acceSBarry Smith 15589b94acceSBarry Smith Output Parameter: 15599b94acceSBarry Smith . outsnes - the new SNES context 15609b94acceSBarry Smith 1561c7afd0dbSLois Curfman McInnes Options Database Keys: 1562c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1563c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1564c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1565c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1566c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1567c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1568c1f60f51SBarry Smith 156936851e7fSLois Curfman McInnes Level: beginner 157036851e7fSLois Curfman McInnes 157195452b02SPatrick Sanan Developer Notes: 157295452b02SPatrick Sanan SNES always creates a KSP object even though many SNES methods do not use it. This is 1573efd4aadfSBarry Smith unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the 1574efd4aadfSBarry Smith particular method does use KSP and regulates if the information about the KSP is printed 1575efd4aadfSBarry Smith in SNESView(). TSSetFromOptions() does call SNESSetFromOptions() which can lead to users being confused 1576efd4aadfSBarry Smith by help messages about meaningless SNES options. 1577efd4aadfSBarry Smith 1578efd4aadfSBarry Smith SNES always creates the snes->kspconvctx even though it is used by only one type. This should 1579efd4aadfSBarry Smith be fixed. 1580efd4aadfSBarry Smith 15819b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 15829b94acceSBarry Smith 1583a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1584a8054027SBarry Smith 15859b94acceSBarry Smith @*/ 15867087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 15879b94acceSBarry Smith { 1588dfbe8321SBarry Smith PetscErrorCode ierr; 15899b94acceSBarry Smith SNES snes; 1590fa9f3622SBarry Smith SNESKSPEW *kctx; 159137fcc0dbSBarry Smith 15923a40ed3dSBarry Smith PetscFunctionBegin; 1593ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 15940298fd71SBarry Smith *outsnes = NULL; 1595607a6623SBarry Smith ierr = SNESInitializePackage();CHKERRQ(ierr); 15968ba1e511SMatthew Knepley 159773107ff1SLisandro Dalcin ierr = PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 15987adad957SLisandro Dalcin 15998d359177SBarry Smith snes->ops->converged = SNESConvergedDefault; 16002c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 160188976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 16029b94acceSBarry Smith snes->max_its = 50; 16039750a799SBarry Smith snes->max_funcs = 10000; 16049b94acceSBarry Smith snes->norm = 0.0; 1605365a6726SPeter Brune snes->normschedule = SNES_NORM_ALWAYS; 16066c67d002SPeter Brune snes->functype = SNES_FUNCTION_DEFAULT; 16073a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 16083a2046daSBarry Smith snes->rtol = 1.e-5; 16093a2046daSBarry Smith #else 1610b4874afaSBarry Smith snes->rtol = 1.e-8; 16113a2046daSBarry Smith #endif 1612b4874afaSBarry Smith snes->ttol = 0.0; 16133a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 16143a2046daSBarry Smith snes->abstol = 1.e-25; 16153a2046daSBarry Smith #else 161670441072SBarry Smith snes->abstol = 1.e-50; 16173a2046daSBarry Smith #endif 16187cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE) 16197cd0ae37SLisandro Dalcin snes->stol = 1.e-5; 16207cd0ae37SLisandro Dalcin #else 1621c60f73f4SPeter Brune snes->stol = 1.e-8; 16227cd0ae37SLisandro Dalcin #endif 16233a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 16243a2046daSBarry Smith snes->deltatol = 1.e-6; 16253a2046daSBarry Smith #else 16264b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 16273a2046daSBarry Smith #endif 1628e37c518bSBarry Smith snes->divtol = 1.e4; 1629e37c518bSBarry Smith snes->rnorm0 = 0; 16309b94acceSBarry Smith snes->nfuncs = 0; 163150ffb88aSMatthew Knepley snes->numFailures = 0; 163250ffb88aSMatthew Knepley snes->maxFailures = 1; 16337a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1634e35cf81dSBarry Smith snes->lagjacobian = 1; 163537ec4e1aSPeter Brune snes->jac_iter = 0; 163637ec4e1aSPeter Brune snes->lagjac_persist = PETSC_FALSE; 1637a8054027SBarry Smith snes->lagpreconditioner = 1; 163837ec4e1aSPeter Brune snes->pre_iter = 0; 163937ec4e1aSPeter Brune snes->lagpre_persist = PETSC_FALSE; 1640639f9d9dSBarry Smith snes->numbermonitors = 0; 16419b94acceSBarry Smith snes->data = 0; 16424dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1643186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 16446f24a144SLois Curfman McInnes snes->nwork = 0; 164558c9b817SLisandro Dalcin snes->work = 0; 164658c9b817SLisandro Dalcin snes->nvwork = 0; 164758c9b817SLisandro Dalcin snes->vwork = 0; 1648758f92a0SBarry Smith snes->conv_hist_len = 0; 1649758f92a0SBarry Smith snes->conv_hist_max = 0; 16500298fd71SBarry Smith snes->conv_hist = NULL; 16510298fd71SBarry Smith snes->conv_hist_its = NULL; 1652758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1653971e163fSPeter Brune snes->counters_reset = PETSC_TRUE; 1654e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1655184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 1656efd4aadfSBarry Smith snes->npcside = PC_RIGHT; 1657b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled = 0; 1658c40d0f55SPeter Brune 1659d8f46077SPeter Brune snes->mf = PETSC_FALSE; 1660d8f46077SPeter Brune snes->mf_operator = PETSC_FALSE; 1661d8f46077SPeter Brune snes->mf_version = 1; 1662d8f46077SPeter Brune 16633d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 16643d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 16653d4c4710SBarry Smith 1666349187a7SBarry Smith snes->vizerotolerance = 1.e-8; 1667349187a7SBarry Smith 16684fc747eaSLawrence Mitchell /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */ 16694fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 16704fc747eaSLawrence Mitchell 16719b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 1672b00a9115SJed Brown ierr = PetscNewLog(snes,&kctx);CHKERRQ(ierr); 1673f5af7f23SKarl Rupp 16749b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 16759b94acceSBarry Smith kctx->version = 2; 16769b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 16779b94acceSBarry Smith this was too large for some test cases */ 167875567043SBarry Smith kctx->rtol_last = 0.0; 16799b94acceSBarry Smith kctx->rtol_max = .9; 16809b94acceSBarry Smith kctx->gamma = 1.0; 168162d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 168271f87433Sdalcinl kctx->alpha2 = kctx->alpha; 16839b94acceSBarry Smith kctx->threshold = .1; 168475567043SBarry Smith kctx->lresid_last = 0.0; 168575567043SBarry Smith kctx->norm_last = 0.0; 16869b94acceSBarry Smith 16879b94acceSBarry Smith *outsnes = snes; 16883a40ed3dSBarry Smith PetscFunctionReturn(0); 16899b94acceSBarry Smith } 16909b94acceSBarry Smith 169188f0584fSBarry Smith /*MC 1692411c0326SBarry Smith SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES 169388f0584fSBarry Smith 169488f0584fSBarry Smith Synopsis: 1695411c0326SBarry Smith #include "petscsnes.h" 1696411c0326SBarry Smith PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx); 169788f0584fSBarry Smith 169888f0584fSBarry Smith Input Parameters: 169988f0584fSBarry Smith + snes - the SNES context 170088f0584fSBarry Smith . x - state at which to evaluate residual 170188f0584fSBarry Smith - ctx - optional user-defined function context, passed in with SNESSetFunction() 170288f0584fSBarry Smith 170388f0584fSBarry Smith Output Parameter: 170488f0584fSBarry Smith . f - vector to put residual (function value) 170588f0584fSBarry Smith 1706878cb397SSatish Balay Level: intermediate 1707878cb397SSatish Balay 170888f0584fSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 170988f0584fSBarry Smith M*/ 171088f0584fSBarry Smith 17119b94acceSBarry Smith /*@C 17129b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 17139b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 17149b94acceSBarry Smith equations. 17159b94acceSBarry Smith 17163f9fe445SBarry Smith Logically Collective on SNES 1717fee21e36SBarry Smith 1718c7afd0dbSLois Curfman McInnes Input Parameters: 1719c7afd0dbSLois Curfman McInnes + snes - the SNES context 1720c7afd0dbSLois Curfman McInnes . r - vector to store function value 1721f8b49ee9SBarry Smith . f - function evaluation routine; see SNESFunction for calling sequence details 1722c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 17230298fd71SBarry Smith function evaluation routine (may be NULL) 17249b94acceSBarry Smith 17259b94acceSBarry Smith Notes: 17269b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 17279b94acceSBarry Smith $ f'(x) x = -f(x), 1728c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 17299b94acceSBarry Smith 173036851e7fSLois Curfman McInnes Level: beginner 173136851e7fSLois Curfman McInnes 17329b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 17339b94acceSBarry Smith 1734bf388a1fSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction 17359b94acceSBarry Smith @*/ 1736f8b49ee9SBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 17379b94acceSBarry Smith { 173885385478SLisandro Dalcin PetscErrorCode ierr; 17396cab3a1bSJed Brown DM dm; 17406cab3a1bSJed Brown 17413a40ed3dSBarry Smith PetscFunctionBegin; 17420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1743d2a683ecSLisandro Dalcin if (r) { 1744d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1745d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 174685385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 17476bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 1748f5af7f23SKarl Rupp 174985385478SLisandro Dalcin snes->vec_func = r; 1750d2a683ecSLisandro Dalcin } 17516cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1752f8b49ee9SBarry Smith ierr = DMSNESSetFunction(dm,f,ctx);CHKERRQ(ierr); 17533a40ed3dSBarry Smith PetscFunctionReturn(0); 17549b94acceSBarry Smith } 17559b94acceSBarry Smith 1756646217ecSPeter Brune 1757e4ed7901SPeter Brune /*@C 1758e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1759e4ed7901SPeter Brune function norm at the initialization of the method. In some 1760e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1761e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1762e4ed7901SPeter Brune to SNESComputeFunction in that case. 1763e4ed7901SPeter Brune 1764e4ed7901SPeter Brune Logically Collective on SNES 1765e4ed7901SPeter Brune 1766e4ed7901SPeter Brune Input Parameters: 1767e4ed7901SPeter Brune + snes - the SNES context 1768e4ed7901SPeter Brune - f - vector to store function value 1769e4ed7901SPeter Brune 1770e4ed7901SPeter Brune Notes: 1771e4ed7901SPeter Brune This should not be modified during the solution procedure. 1772e4ed7901SPeter Brune 1773e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1774e4ed7901SPeter Brune 1775e4ed7901SPeter Brune Level: developer 1776e4ed7901SPeter Brune 1777e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function 1778e4ed7901SPeter Brune 1779e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1780e4ed7901SPeter Brune @*/ 1781e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1782e4ed7901SPeter Brune { 1783e4ed7901SPeter Brune PetscErrorCode ierr; 1784e4ed7901SPeter Brune Vec vec_func; 1785e4ed7901SPeter Brune 1786e4ed7901SPeter Brune PetscFunctionBegin; 1787e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1788e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1789e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 1790efd4aadfSBarry Smith if (snes->npcside== PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) { 1791902f982fSPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1792902f982fSPeter Brune PetscFunctionReturn(0); 1793902f982fSPeter Brune } 17940298fd71SBarry Smith ierr = SNESGetFunction(snes,&vec_func,NULL,NULL);CHKERRQ(ierr); 1795e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1796f5af7f23SKarl Rupp 1797217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1798e4ed7901SPeter Brune PetscFunctionReturn(0); 1799e4ed7901SPeter Brune } 1800e4ed7901SPeter Brune 1801534ebe21SPeter Brune /*@ 1802365a6726SPeter Brune SNESSetNormSchedule - Sets the SNESNormSchedule used in covergence and monitoring 1803534ebe21SPeter Brune of the SNES method. 1804534ebe21SPeter Brune 1805534ebe21SPeter Brune Logically Collective on SNES 1806534ebe21SPeter Brune 1807534ebe21SPeter Brune Input Parameters: 1808534ebe21SPeter Brune + snes - the SNES context 1809365a6726SPeter Brune - normschedule - the frequency of norm computation 1810534ebe21SPeter Brune 1811517f1916SMatthew G. Knepley Options Database Key: 1812517f1916SMatthew G. Knepley . -snes_norm_schedule <none, always, initialonly, finalonly, initalfinalonly> 1813517f1916SMatthew G. Knepley 1814534ebe21SPeter Brune Notes: 1815365a6726SPeter Brune Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 1816534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1817534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1818be95d8f1SBarry Smith (SNESNGS) and the like do not require the norm of the function to be computed, and therfore 1819534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1820534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1821534ebe21SPeter Brune their solution. 1822534ebe21SPeter Brune 1823534ebe21SPeter Brune Level: developer 1824534ebe21SPeter Brune 1825534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1826534ebe21SPeter Brune 1827365a6726SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1828534ebe21SPeter Brune @*/ 1829365a6726SPeter Brune PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule) 1830534ebe21SPeter Brune { 1831534ebe21SPeter Brune PetscFunctionBegin; 1832534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1833365a6726SPeter Brune snes->normschedule = normschedule; 1834534ebe21SPeter Brune PetscFunctionReturn(0); 1835534ebe21SPeter Brune } 1836534ebe21SPeter Brune 1837534ebe21SPeter Brune 1838534ebe21SPeter Brune /*@ 1839365a6726SPeter Brune SNESGetNormSchedule - Gets the SNESNormSchedule used in covergence and monitoring 1840534ebe21SPeter Brune of the SNES method. 1841534ebe21SPeter Brune 1842534ebe21SPeter Brune Logically Collective on SNES 1843534ebe21SPeter Brune 1844534ebe21SPeter Brune Input Parameters: 1845534ebe21SPeter Brune + snes - the SNES context 1846365a6726SPeter Brune - normschedule - the type of the norm used 1847534ebe21SPeter Brune 1848534ebe21SPeter Brune Level: advanced 1849534ebe21SPeter Brune 1850534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1851534ebe21SPeter Brune 1852365a6726SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1853534ebe21SPeter Brune @*/ 1854365a6726SPeter Brune PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule) 1855534ebe21SPeter Brune { 1856534ebe21SPeter Brune PetscFunctionBegin; 1857534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1858365a6726SPeter Brune *normschedule = snes->normschedule; 1859534ebe21SPeter Brune PetscFunctionReturn(0); 1860534ebe21SPeter Brune } 1861534ebe21SPeter Brune 186247073ea2SPeter Brune 1863c5ce4427SMatthew G. Knepley /*@ 1864c5ce4427SMatthew G. Knepley SNESSetFunctionNorm - Sets the last computed residual norm. 1865c5ce4427SMatthew G. Knepley 1866c5ce4427SMatthew G. Knepley Logically Collective on SNES 1867c5ce4427SMatthew G. Knepley 1868c5ce4427SMatthew G. Knepley Input Parameters: 1869c5ce4427SMatthew G. Knepley + snes - the SNES context 1870c5ce4427SMatthew G. Knepley 1871c5ce4427SMatthew G. Knepley - normschedule - the frequency of norm computation 1872c5ce4427SMatthew G. Knepley 1873c5ce4427SMatthew G. Knepley Level: developer 1874c5ce4427SMatthew G. Knepley 1875c5ce4427SMatthew G. Knepley .keywords: SNES, nonlinear, set, function, norm, type 1876c5ce4427SMatthew G. Knepley .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1877c5ce4427SMatthew G. Knepley @*/ 1878c5ce4427SMatthew G. Knepley PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm) 1879c5ce4427SMatthew G. Knepley { 1880c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1881c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1882c5ce4427SMatthew G. Knepley snes->norm = norm; 1883c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 1884c5ce4427SMatthew G. Knepley } 1885c5ce4427SMatthew G. Knepley 1886c5ce4427SMatthew G. Knepley /*@ 1887c5ce4427SMatthew G. Knepley SNESGetFunctionNorm - Gets the last computed norm of the residual 1888c5ce4427SMatthew G. Knepley 1889c5ce4427SMatthew G. Knepley Not Collective 1890c5ce4427SMatthew G. Knepley 1891c5ce4427SMatthew G. Knepley Input Parameter: 1892c5ce4427SMatthew G. Knepley . snes - the SNES context 1893c5ce4427SMatthew G. Knepley 1894c5ce4427SMatthew G. Knepley Output Parameter: 1895c5ce4427SMatthew G. Knepley . norm - the last computed residual norm 1896c5ce4427SMatthew G. Knepley 1897c5ce4427SMatthew G. Knepley Level: developer 1898c5ce4427SMatthew G. Knepley 1899c5ce4427SMatthew G. Knepley .keywords: SNES, nonlinear, set, function, norm, type 1900c5ce4427SMatthew G. Knepley .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1901c5ce4427SMatthew G. Knepley @*/ 1902c5ce4427SMatthew G. Knepley PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm) 1903c5ce4427SMatthew G. Knepley { 1904c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1905c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1906c5ce4427SMatthew G. Knepley PetscValidPointer(norm, 2); 1907c5ce4427SMatthew G. Knepley *norm = snes->norm; 1908c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 1909c5ce4427SMatthew G. Knepley } 1910c5ce4427SMatthew G. Knepley 191147073ea2SPeter Brune /*@C 191247073ea2SPeter Brune SNESSetFunctionType - Sets the SNESNormSchedule used in covergence and monitoring 191347073ea2SPeter Brune of the SNES method. 191447073ea2SPeter Brune 191547073ea2SPeter Brune Logically Collective on SNES 191647073ea2SPeter Brune 191747073ea2SPeter Brune Input Parameters: 191847073ea2SPeter Brune + snes - the SNES context 191947073ea2SPeter Brune - normschedule - the frequency of norm computation 192047073ea2SPeter Brune 192147073ea2SPeter Brune Notes: 192247073ea2SPeter Brune Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 192347073ea2SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 192447073ea2SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1925be95d8f1SBarry Smith (SNESNGS) and the like do not require the norm of the function to be computed, and therfore 192647073ea2SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 192747073ea2SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 192847073ea2SPeter Brune their solution. 192947073ea2SPeter Brune 193047073ea2SPeter Brune Level: developer 193147073ea2SPeter Brune 193247073ea2SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 193347073ea2SPeter Brune 193447073ea2SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 193547073ea2SPeter Brune @*/ 193647073ea2SPeter Brune PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type) 193747073ea2SPeter Brune { 193847073ea2SPeter Brune PetscFunctionBegin; 193947073ea2SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 194047073ea2SPeter Brune snes->functype = type; 194147073ea2SPeter Brune PetscFunctionReturn(0); 194247073ea2SPeter Brune } 194347073ea2SPeter Brune 194447073ea2SPeter Brune 194547073ea2SPeter Brune /*@C 194647073ea2SPeter Brune SNESGetFunctionType - Gets the SNESNormSchedule used in covergence and monitoring 194747073ea2SPeter Brune of the SNES method. 194847073ea2SPeter Brune 194947073ea2SPeter Brune Logically Collective on SNES 195047073ea2SPeter Brune 195147073ea2SPeter Brune Input Parameters: 195247073ea2SPeter Brune + snes - the SNES context 195347073ea2SPeter Brune - normschedule - the type of the norm used 195447073ea2SPeter Brune 195547073ea2SPeter Brune Level: advanced 195647073ea2SPeter Brune 195747073ea2SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 195847073ea2SPeter Brune 195947073ea2SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 196047073ea2SPeter Brune @*/ 196147073ea2SPeter Brune PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type) 196247073ea2SPeter Brune { 196347073ea2SPeter Brune PetscFunctionBegin; 196447073ea2SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 196547073ea2SPeter Brune *type = snes->functype; 1966534ebe21SPeter Brune PetscFunctionReturn(0); 1967534ebe21SPeter Brune } 1968534ebe21SPeter Brune 1969bf388a1fSBarry Smith /*MC 1970be95d8f1SBarry Smith SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function 1971bf388a1fSBarry Smith 1972bf388a1fSBarry Smith Synopsis: 1973aaa7dc30SBarry Smith #include <petscsnes.h> 1974be95d8f1SBarry Smith $ SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx); 1975bf388a1fSBarry Smith 1976bf388a1fSBarry Smith + X - solution vector 1977bf388a1fSBarry Smith . B - RHS vector 1978bf388a1fSBarry Smith - ctx - optional user-defined Gauss-Seidel context 1979bf388a1fSBarry Smith 1980878cb397SSatish Balay Level: intermediate 1981878cb397SSatish Balay 1982be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetNGS() 1983bf388a1fSBarry Smith M*/ 1984bf388a1fSBarry Smith 1985c79ef259SPeter Brune /*@C 1986be95d8f1SBarry Smith SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for 1987c79ef259SPeter Brune use with composed nonlinear solvers. 1988c79ef259SPeter Brune 1989c79ef259SPeter Brune Input Parameters: 1990c79ef259SPeter Brune + snes - the SNES context 1991be95d8f1SBarry Smith . f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction 1992c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 19930298fd71SBarry Smith smoother evaluation routine (may be NULL) 1994c79ef259SPeter Brune 1995c79ef259SPeter Brune Notes: 1996be95d8f1SBarry Smith The NGS routines are used by the composed nonlinear solver to generate 1997c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1998c79ef259SPeter Brune 1999d28543b3SPeter Brune Level: intermediate 2000c79ef259SPeter Brune 2001d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 2002c79ef259SPeter Brune 2003be95d8f1SBarry Smith .seealso: SNESGetFunction(), SNESComputeNGS() 2004c79ef259SPeter Brune @*/ 2005be95d8f1SBarry Smith PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 20066cab3a1bSJed Brown { 20076cab3a1bSJed Brown PetscErrorCode ierr; 20086cab3a1bSJed Brown DM dm; 20096cab3a1bSJed Brown 2010646217ecSPeter Brune PetscFunctionBegin; 20116cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20126cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2013be95d8f1SBarry Smith ierr = DMSNESSetNGS(dm,f,ctx);CHKERRQ(ierr); 2014646217ecSPeter Brune PetscFunctionReturn(0); 2015646217ecSPeter Brune } 2016646217ecSPeter Brune 201725acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 20188b0a5094SBarry Smith { 20198b0a5094SBarry Smith PetscErrorCode ierr; 2020e03ab78fSPeter Brune DM dm; 2021942e3340SBarry Smith DMSNES sdm; 20226cab3a1bSJed Brown 20238b0a5094SBarry Smith PetscFunctionBegin; 2024e03ab78fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2025942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 202625acbd8eSLisandro Dalcin if (!sdm->ops->computepfunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard function."); 202725acbd8eSLisandro Dalcin if (!sdm->ops->computepjacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian."); 20288b0a5094SBarry Smith /* A(x)*x - b(x) */ 202925acbd8eSLisandro Dalcin PetscStackPush("SNES Picard user function"); 203022c6f798SBarry Smith ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr); 203125acbd8eSLisandro Dalcin PetscStackPop; 203225acbd8eSLisandro Dalcin PetscStackPush("SNES Picard user Jacobian"); 2033d1e9a80fSBarry Smith ierr = (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);CHKERRQ(ierr); 203425acbd8eSLisandro Dalcin PetscStackPop; 20358b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 203695eabcedSBarry Smith ierr = MatMultAdd(snes->jacobian,x,f,f);CHKERRQ(ierr); 20378b0a5094SBarry Smith PetscFunctionReturn(0); 20388b0a5094SBarry Smith } 20398b0a5094SBarry Smith 204025acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx) 20418b0a5094SBarry Smith { 20428b0a5094SBarry Smith PetscFunctionBegin; 2043e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 20448b0a5094SBarry Smith PetscFunctionReturn(0); 20458b0a5094SBarry Smith } 20468b0a5094SBarry Smith 20478b0a5094SBarry Smith /*@C 20480d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 20498b0a5094SBarry Smith 20508b0a5094SBarry Smith Logically Collective on SNES 20518b0a5094SBarry Smith 20528b0a5094SBarry Smith Input Parameters: 20538b0a5094SBarry Smith + snes - the SNES context 20548b0a5094SBarry Smith . r - vector to store function value 2055f8b49ee9SBarry Smith . b - function evaluation routine 2056e5d3d808SBarry Smith . Amat - matrix with which A(x) x - b(x) is to be computed 2057e5d3d808SBarry Smith . Pmat - matrix from which preconditioner is computed (usually the same as Amat) 2058411c0326SBarry Smith . J - function to compute matrix value, see SNESJacobianFunction for details on its calling sequence 20598b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 20600298fd71SBarry Smith function evaluation routine (may be NULL) 20618b0a5094SBarry Smith 20628b0a5094SBarry Smith Notes: 2063f450aa47SBarry 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 2064f450aa47SBarry 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. 2065f450aa47SBarry Smith 20668b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 20678b0a5094SBarry Smith 20688b0a5094SBarry 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} 20698b0a5094SBarry 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. 20708b0a5094SBarry Smith 20718b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 20728b0a5094SBarry Smith 20730d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 20740d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 20758b0a5094SBarry Smith 20768b0a5094SBarry 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 20778b0a5094SBarry 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 20788b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 20798b0a5094SBarry Smith 2080f450aa47SBarry Smith Level: intermediate 20818b0a5094SBarry Smith 20828b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 20838b0a5094SBarry Smith 2084411c0326SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard(), SNESJacobianFunction 20858b0a5094SBarry Smith @*/ 2086d1e9a80fSBarry 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) 20878b0a5094SBarry Smith { 20888b0a5094SBarry Smith PetscErrorCode ierr; 2089e03ab78fSPeter Brune DM dm; 2090e03ab78fSPeter Brune 20918b0a5094SBarry Smith PetscFunctionBegin; 20928b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2093e03ab78fSPeter Brune ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 2094f8b49ee9SBarry Smith ierr = DMSNESSetPicard(dm,b,J,ctx);CHKERRQ(ierr); 20958b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 2096e5d3d808SBarry Smith ierr = SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 20978b0a5094SBarry Smith PetscFunctionReturn(0); 20988b0a5094SBarry Smith } 20998b0a5094SBarry Smith 21007971a8bfSPeter Brune /*@C 21017971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 21027971a8bfSPeter Brune 21037971a8bfSPeter Brune Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 21047971a8bfSPeter Brune 21057971a8bfSPeter Brune Input Parameter: 21067971a8bfSPeter Brune . snes - the SNES context 21077971a8bfSPeter Brune 21087971a8bfSPeter Brune Output Parameter: 21090298fd71SBarry Smith + r - the function (or NULL) 2110f8b49ee9SBarry Smith . f - the function (or NULL); see SNESFunction for calling sequence details 2111e4357dc4SBarry Smith . Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL) 2112e4357dc4SBarry Smith . Pmat - the matrix from which the preconditioner will be constructed (or NULL) 2113f8b49ee9SBarry Smith . J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details 21140298fd71SBarry Smith - ctx - the function context (or NULL) 21157971a8bfSPeter Brune 21167971a8bfSPeter Brune Level: advanced 21177971a8bfSPeter Brune 21187971a8bfSPeter Brune .keywords: SNES, nonlinear, get, function 21197971a8bfSPeter Brune 2120e4357dc4SBarry Smith .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction 21217971a8bfSPeter Brune @*/ 2122d1e9a80fSBarry 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) 21237971a8bfSPeter Brune { 21247971a8bfSPeter Brune PetscErrorCode ierr; 21257971a8bfSPeter Brune DM dm; 21267971a8bfSPeter Brune 21277971a8bfSPeter Brune PetscFunctionBegin; 21287971a8bfSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21290298fd71SBarry Smith ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 2130e4357dc4SBarry Smith ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 21317971a8bfSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2132f8b49ee9SBarry Smith ierr = DMSNESGetPicard(dm,f,J,ctx);CHKERRQ(ierr); 21337971a8bfSPeter Brune PetscFunctionReturn(0); 21347971a8bfSPeter Brune } 21357971a8bfSPeter Brune 2136d25893d9SBarry Smith /*@C 2137d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 2138d25893d9SBarry Smith 2139d25893d9SBarry Smith Logically Collective on SNES 2140d25893d9SBarry Smith 2141d25893d9SBarry Smith Input Parameters: 2142d25893d9SBarry Smith + snes - the SNES context 2143d25893d9SBarry Smith . func - function evaluation routine 2144d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 21450298fd71SBarry Smith function evaluation routine (may be NULL) 2146d25893d9SBarry Smith 2147d25893d9SBarry Smith Calling sequence of func: 2148d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 2149d25893d9SBarry Smith 2150d25893d9SBarry Smith . f - function vector 2151d25893d9SBarry Smith - ctx - optional user-defined function context 2152d25893d9SBarry Smith 2153d25893d9SBarry Smith Level: intermediate 2154d25893d9SBarry Smith 2155d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 2156d25893d9SBarry Smith 2157d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 2158d25893d9SBarry Smith @*/ 2159d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 2160d25893d9SBarry Smith { 2161d25893d9SBarry Smith PetscFunctionBegin; 2162d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2163d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 2164d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 2165d25893d9SBarry Smith PetscFunctionReturn(0); 2166d25893d9SBarry Smith } 2167d25893d9SBarry Smith 21683ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 21691096aae1SMatthew Knepley /*@C 21701096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 21711096aae1SMatthew Knepley it assumes a zero right hand side. 21721096aae1SMatthew Knepley 21733f9fe445SBarry Smith Logically Collective on SNES 21741096aae1SMatthew Knepley 21751096aae1SMatthew Knepley Input Parameter: 21761096aae1SMatthew Knepley . snes - the SNES context 21771096aae1SMatthew Knepley 21781096aae1SMatthew Knepley Output Parameter: 21790298fd71SBarry Smith . rhs - the right hand side vector or NULL if the right hand side vector is null 21801096aae1SMatthew Knepley 21811096aae1SMatthew Knepley Level: intermediate 21821096aae1SMatthew Knepley 21831096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 21841096aae1SMatthew Knepley 218585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 21861096aae1SMatthew Knepley @*/ 21877087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 21881096aae1SMatthew Knepley { 21891096aae1SMatthew Knepley PetscFunctionBegin; 21900700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21911096aae1SMatthew Knepley PetscValidPointer(rhs,2); 219285385478SLisandro Dalcin *rhs = snes->vec_rhs; 21931096aae1SMatthew Knepley PetscFunctionReturn(0); 21941096aae1SMatthew Knepley } 21951096aae1SMatthew Knepley 21969b94acceSBarry Smith /*@ 2197bf388a1fSBarry Smith SNESComputeFunction - Calls the function that has been set with SNESSetFunction(). 21989b94acceSBarry Smith 2199c7afd0dbSLois Curfman McInnes Collective on SNES 2200c7afd0dbSLois Curfman McInnes 22019b94acceSBarry Smith Input Parameters: 2202c7afd0dbSLois Curfman McInnes + snes - the SNES context 2203c7afd0dbSLois Curfman McInnes - x - input vector 22049b94acceSBarry Smith 22059b94acceSBarry Smith Output Parameter: 22063638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 22079b94acceSBarry Smith 22081bffabb2SLois Curfman McInnes Notes: 220936851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 221036851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 221136851e7fSLois Curfman McInnes themselves. 221236851e7fSLois Curfman McInnes 221336851e7fSLois Curfman McInnes Level: developer 221436851e7fSLois Curfman McInnes 22159b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 22169b94acceSBarry Smith 2217a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 22189b94acceSBarry Smith @*/ 22197087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 22209b94acceSBarry Smith { 2221dfbe8321SBarry Smith PetscErrorCode ierr; 22226cab3a1bSJed Brown DM dm; 2223942e3340SBarry Smith DMSNES sdm; 22249b94acceSBarry Smith 22253a40ed3dSBarry Smith PetscFunctionBegin; 22260700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 22270700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 22280700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2229c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 2230c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 223162796dfbSBarry Smith ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr); 2232184914b5SBarry Smith 22336cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2234942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 223532f3f7c2SPeter Brune if (sdm->ops->computefunction) { 223694db00ebSBarry Smith if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2237ccf3c845SPeter Brune ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 223894db00ebSBarry Smith } 22395edff71fSBarry Smith ierr = VecLockPush(x);CHKERRQ(ierr); 2240d64ed03dSBarry Smith PetscStackPush("SNES user function"); 224122c6f798SBarry Smith ierr = (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 2242d64ed03dSBarry Smith PetscStackPop; 22435edff71fSBarry Smith ierr = VecLockPop(x);CHKERRQ(ierr); 224494db00ebSBarry Smith if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2245ccf3c845SPeter Brune ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 224694db00ebSBarry Smith } 2247c90fad12SPeter Brune } else if (snes->vec_rhs) { 2248c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 2249644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 225085385478SLisandro Dalcin if (snes->vec_rhs) { 225185385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 22523ab0aad5SBarry Smith } 2253ae3c334cSLois Curfman McInnes snes->nfuncs++; 2254422a814eSBarry Smith /* 2255422a814eSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2256422a814eSBarry Smith propagate the value to all processes 2257422a814eSBarry Smith */ 2258422a814eSBarry Smith if (snes->domainerror) { 2259422a814eSBarry Smith ierr = VecSetInf(y);CHKERRQ(ierr); 2260422a814eSBarry Smith } 22613a40ed3dSBarry Smith PetscFunctionReturn(0); 22629b94acceSBarry Smith } 22639b94acceSBarry Smith 2264c79ef259SPeter Brune /*@ 2265be95d8f1SBarry Smith SNESComputeNGS - Calls the Gauss-Seidel function that has been set with SNESSetNGS(). 2266c79ef259SPeter Brune 2267c79ef259SPeter Brune Collective on SNES 2268c79ef259SPeter Brune 2269c79ef259SPeter Brune Input Parameters: 2270c79ef259SPeter Brune + snes - the SNES context 2271c79ef259SPeter Brune . x - input vector 2272c79ef259SPeter Brune - b - rhs vector 2273c79ef259SPeter Brune 2274c79ef259SPeter Brune Output Parameter: 2275c79ef259SPeter Brune . x - new solution vector 2276c79ef259SPeter Brune 2277c79ef259SPeter Brune Notes: 2278be95d8f1SBarry Smith SNESComputeNGS() is typically used within composed nonlinear solver 2279c79ef259SPeter Brune implementations, so most users would not generally call this routine 2280c79ef259SPeter Brune themselves. 2281c79ef259SPeter Brune 2282c79ef259SPeter Brune Level: developer 2283c79ef259SPeter Brune 2284c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 2285c79ef259SPeter Brune 2286be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESComputeFunction() 2287c79ef259SPeter Brune @*/ 2288be95d8f1SBarry Smith PetscErrorCode SNESComputeNGS(SNES snes,Vec b,Vec x) 2289646217ecSPeter Brune { 2290646217ecSPeter Brune PetscErrorCode ierr; 22916cab3a1bSJed Brown DM dm; 2292942e3340SBarry Smith DMSNES sdm; 2293646217ecSPeter Brune 2294646217ecSPeter Brune PetscFunctionBegin; 2295646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2296646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2297646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 2298646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 2299646217ecSPeter Brune if (b) PetscCheckSameComm(snes,1,b,3); 230062796dfbSBarry Smith if (b) {ierr = VecValidValues(b,2,PETSC_TRUE);CHKERRQ(ierr);} 2301be95d8f1SBarry Smith ierr = PetscLogEventBegin(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr); 23026cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2303942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 230422c6f798SBarry Smith if (sdm->ops->computegs) { 23055edff71fSBarry Smith if (b) {ierr = VecLockPush(b);CHKERRQ(ierr);} 2306be95d8f1SBarry Smith PetscStackPush("SNES user NGS"); 230722c6f798SBarry Smith ierr = (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 2308646217ecSPeter Brune PetscStackPop; 23095edff71fSBarry Smith if (b) {ierr = VecLockPop(b);CHKERRQ(ierr);} 2310be95d8f1SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 2311be95d8f1SBarry Smith ierr = PetscLogEventEnd(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr); 2312646217ecSPeter Brune PetscFunctionReturn(0); 2313646217ecSPeter Brune } 2314646217ecSPeter Brune 2315e885f1abSBarry Smith PetscErrorCode SNESTestJacobian(SNES snes) 2316e885f1abSBarry Smith { 231712837594SBarry Smith Mat A,B,C,D,jacobian; 2318e885f1abSBarry Smith Vec x = snes->vec_sol,f = snes->vec_func; 2319e885f1abSBarry Smith PetscErrorCode ierr; 2320e885f1abSBarry Smith PetscReal nrm,gnorm; 232181e7118cSBarry Smith PetscReal threshold = 1.e-5; 2322e885f1abSBarry Smith PetscInt m,n,M,N; 2323e885f1abSBarry Smith void *functx; 232418d89885SKarl Rupp PetscBool complete_print = PETSC_FALSE,threshold_print = PETSC_FALSE,test = PETSC_FALSE,flg; 23253325ff46SBarry Smith PetscViewer viewer,mviewer; 2326e885f1abSBarry Smith MPI_Comm comm; 2327e885f1abSBarry Smith PetscInt tabs; 232812837594SBarry Smith static PetscBool directionsprinted = PETSC_FALSE; 23293325ff46SBarry Smith PetscViewerFormat format; 2330e885f1abSBarry Smith 2331e885f1abSBarry Smith PetscFunctionBegin; 2332fc35ed60SBarry Smith ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 233312837594SBarry Smith ierr = PetscOptionsName("-snes_test_jacobian","Compare hand-coded and finite difference Jacobians","None",&test);CHKERRQ(ierr); 233412837594SBarry Smith ierr = PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold,NULL);CHKERRQ(ierr); 23353325ff46SBarry Smith ierr = PetscOptionsViewer("-snes_test_jacobian_view","View difference between hand-coded and finite difference Jacobians element entries","None",&mviewer,&format,&complete_print);CHKERRQ(ierr); 233618d89885SKarl Rupp if (!complete_print) { 233718d89885SKarl Rupp ierr = PetscOptionsViewer("-snes_test_jacobian_display","Display difference between hand-coded and finite difference Jacobians","None",&mviewer,&format,&complete_print);CHKERRQ(ierr); 233818d89885SKarl Rupp } 233918d89885SKarl Rupp /* for compatibility with PETSc 3.9 and older. */ 234018d89885SKarl Rupp ierr = PetscOptionsReal("-snes_test_jacobian_display_threshold", "Display difference between hand-coded and finite difference Jacobians which exceed input threshold", "None", threshold, &threshold, &threshold_print);CHKERRQ(ierr); 2341e885f1abSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 2342e885f1abSBarry Smith if (!test) PetscFunctionReturn(0); 2343e885f1abSBarry Smith 2344e885f1abSBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2345e885f1abSBarry Smith ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr); 2346e885f1abSBarry Smith ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr); 2347e885f1abSBarry Smith ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel);CHKERRQ(ierr); 234812837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ---------- Testing Jacobian -------------\n");CHKERRQ(ierr); 234912837594SBarry Smith if (!complete_print && !directionsprinted) { 235012837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n");CHKERRQ(ierr); 2351fc35ed60SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," of hand-coded and finite difference Jacobian entries greater than <threshold>.\n");CHKERRQ(ierr); 235212837594SBarry Smith } 235312837594SBarry Smith if (!directionsprinted) { 235412837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n");CHKERRQ(ierr); 2355e885f1abSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," O(1.e-8), the hand-coded Jacobian is probably correct.\n");CHKERRQ(ierr); 235612837594SBarry Smith directionsprinted = PETSC_TRUE; 2357e885f1abSBarry Smith } 23583325ff46SBarry Smith if (complete_print) { 23593325ff46SBarry Smith ierr = PetscViewerPushFormat(mviewer,format);CHKERRQ(ierr); 2360e885f1abSBarry Smith } 2361e885f1abSBarry Smith 236212837594SBarry Smith /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */ 2363e885f1abSBarry Smith ierr = SNESComputeFunction(snes,x,f);CHKERRQ(ierr); 236412837594SBarry Smith 236512837594SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)snes->jacobian,MATMFFD,&flg);CHKERRQ(ierr); 236612837594SBarry Smith if (!flg) jacobian = snes->jacobian; 236712837594SBarry Smith else jacobian = snes->jacobian_pre; 236812837594SBarry Smith 236912837594SBarry Smith while (jacobian) { 237012837594SBarry Smith ierr = PetscObjectTypeCompareAny((PetscObject)jacobian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 237112837594SBarry Smith if (flg) { 237212837594SBarry Smith A = jacobian; 237312837594SBarry Smith ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 237412837594SBarry Smith } else { 237512837594SBarry Smith ierr = MatComputeExplicitOperator(jacobian,&A);CHKERRQ(ierr); 237612837594SBarry Smith } 2377e885f1abSBarry Smith 2378e885f1abSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr); 2379e885f1abSBarry Smith ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 2380e885f1abSBarry Smith ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 2381e885f1abSBarry Smith ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr); 2382e885f1abSBarry Smith ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2383e885f1abSBarry Smith ierr = MatSetUp(B);CHKERRQ(ierr); 2384e885f1abSBarry Smith ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 2385e885f1abSBarry Smith 2386e885f1abSBarry Smith ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 2387e885f1abSBarry Smith ierr = SNESComputeJacobianDefault(snes,x,B,B,functx);CHKERRQ(ierr); 238812837594SBarry Smith 238912837594SBarry Smith ierr = MatDuplicate(B,MAT_COPY_VALUES,&D);CHKERRQ(ierr); 239012837594SBarry Smith ierr = MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 239112837594SBarry Smith ierr = MatNorm(D,NORM_FROBENIUS,&nrm);CHKERRQ(ierr); 2392e885f1abSBarry Smith ierr = MatNorm(A,NORM_FROBENIUS,&gnorm);CHKERRQ(ierr); 239312837594SBarry Smith ierr = MatDestroy(&D);CHKERRQ(ierr); 239412837594SBarry Smith if (!gnorm) gnorm = 1; /* just in case */ 239512837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm);CHKERRQ(ierr); 239612837594SBarry Smith 2397e885f1abSBarry Smith if (complete_print) { 239812837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Hand-coded Jacobian ----------\n");CHKERRQ(ierr); 23993325ff46SBarry Smith ierr = MatView(jacobian,mviewer);CHKERRQ(ierr); 240012837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Finite difference Jacobian ----------\n");CHKERRQ(ierr); 24013325ff46SBarry Smith ierr = MatView(B,mviewer);CHKERRQ(ierr); 2402e885f1abSBarry Smith } 2403e885f1abSBarry Smith 240418d89885SKarl Rupp if (threshold_print) { 2405e885f1abSBarry Smith PetscInt Istart, Iend, *ccols, bncols, cncols, j, row; 2406e885f1abSBarry Smith PetscScalar *cvals; 2407e885f1abSBarry Smith const PetscInt *bcols; 2408e885f1abSBarry Smith const PetscScalar *bvals; 2409e885f1abSBarry Smith 241012837594SBarry Smith ierr = MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 2411e885f1abSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2412e885f1abSBarry Smith ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 2413e885f1abSBarry Smith ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2414e885f1abSBarry Smith ierr = MatSetUp(C);CHKERRQ(ierr); 2415e885f1abSBarry Smith ierr = MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 2416e885f1abSBarry Smith ierr = MatGetOwnershipRange(B,&Istart,&Iend);CHKERRQ(ierr); 2417e885f1abSBarry Smith 2418e885f1abSBarry Smith for (row = Istart; row < Iend; row++) { 2419e885f1abSBarry Smith ierr = MatGetRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr); 2420e885f1abSBarry Smith ierr = PetscMalloc2(bncols,&ccols,bncols,&cvals);CHKERRQ(ierr); 2421e885f1abSBarry Smith for (j = 0, cncols = 0; j < bncols; j++) { 242223a52b1dSBarry Smith if (PetscAbsScalar(bvals[j]) > threshold) { 2423e885f1abSBarry Smith ccols[cncols] = bcols[j]; 2424e885f1abSBarry Smith cvals[cncols] = bvals[j]; 2425e885f1abSBarry Smith cncols += 1; 2426e885f1abSBarry Smith } 2427e885f1abSBarry Smith } 2428e885f1abSBarry Smith if (cncols) { 2429e885f1abSBarry Smith ierr = MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES);CHKERRQ(ierr); 2430e885f1abSBarry Smith } 2431e885f1abSBarry Smith ierr = MatRestoreRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr); 2432e885f1abSBarry Smith ierr = PetscFree2(ccols,cvals);CHKERRQ(ierr); 2433e885f1abSBarry Smith } 2434e885f1abSBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2435e885f1abSBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 243612837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n",(double)threshold);CHKERRQ(ierr); 243718d89885SKarl Rupp ierr = MatView(C,complete_print ? mviewer : viewer);CHKERRQ(ierr); 2438e885f1abSBarry Smith ierr = MatDestroy(&C);CHKERRQ(ierr); 2439e885f1abSBarry Smith } 244012837594SBarry Smith ierr = MatDestroy(&A);CHKERRQ(ierr); 2441e885f1abSBarry Smith ierr = MatDestroy(&B);CHKERRQ(ierr); 244212837594SBarry Smith 244312837594SBarry Smith if (jacobian != snes->jacobian_pre) { 244412837594SBarry Smith jacobian = snes->jacobian_pre; 244512837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ---------- Testing Jacobian for preconditioner -------------\n");CHKERRQ(ierr); 244612837594SBarry Smith } 244712837594SBarry Smith else jacobian = NULL; 244812837594SBarry Smith } 24493325ff46SBarry Smith if (complete_print) { 24503325ff46SBarry Smith ierr = PetscViewerPopFormat(mviewer);CHKERRQ(ierr); 24513325ff46SBarry Smith } 2452e885f1abSBarry Smith ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr); 2453e885f1abSBarry Smith PetscFunctionReturn(0); 2454e885f1abSBarry Smith } 2455e885f1abSBarry Smith 245662fef451SLois Curfman McInnes /*@ 2457bf388a1fSBarry Smith SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian(). 245862fef451SLois Curfman McInnes 2459c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 2460c7afd0dbSLois Curfman McInnes 246162fef451SLois Curfman McInnes Input Parameters: 2462c7afd0dbSLois Curfman McInnes + snes - the SNES context 2463c7afd0dbSLois Curfman McInnes - x - input vector 246462fef451SLois Curfman McInnes 246562fef451SLois Curfman McInnes Output Parameters: 2466c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 2467d1e9a80fSBarry Smith - B - optional preconditioning matrix 2468fee21e36SBarry Smith 2469e35cf81dSBarry Smith Options Database Keys: 2470e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 2471693365a8SJed Brown . -snes_lag_jacobian <lag> 2472e885f1abSBarry Smith . -snes_test_jacobian - compare the user provided Jacobian with one compute via finite differences to check for errors 2473e885f1abSBarry Smith . -snes_test_jacobian_display - display the user provided Jacobian, the finite difference Jacobian and the difference between them to help users detect the location of errors in the user provided Jacobian 2474e885f1abSBarry Smith . -snes_test_jacobian_display_threshold <numerical value> - display entries in the difference between the user provided Jacobian and finite difference Jacobian that are greater than a certain value to help users detect errors 2475693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2476693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2477693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 24784c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 247994d6a431SBarry Smith . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2480c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 2481c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2482c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2483c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 24844c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 2485c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 2486c01495d3SJed Brown 2487e35cf81dSBarry Smith 248862fef451SLois Curfman McInnes Notes: 248962fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 249062fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 249162fef451SLois Curfman McInnes 249295452b02SPatrick Sanan Developer Notes: 249395452b02SPatrick Sanan This has duplicative ways of checking the accuracy of the user provided Jacobian (see the options above). This is for historical reasons, the routine SNESTestJacobian() use to used 2494e885f1abSBarry Smith for with the SNESType of test that has been removed. 2495e885f1abSBarry Smith 249636851e7fSLois Curfman McInnes Level: developer 249736851e7fSLois Curfman McInnes 249862fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 249962fef451SLois Curfman McInnes 2500e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 250162fef451SLois Curfman McInnes @*/ 2502d1e9a80fSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B) 25039b94acceSBarry Smith { 2504dfbe8321SBarry Smith PetscErrorCode ierr; 2505ace3abfcSBarry Smith PetscBool flag; 25066cab3a1bSJed Brown DM dm; 2507942e3340SBarry Smith DMSNES sdm; 2508e0e3a89bSBarry Smith KSP ksp; 25093a40ed3dSBarry Smith 25103a40ed3dSBarry Smith PetscFunctionBegin; 25110700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 25120700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2513c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 251462796dfbSBarry Smith ierr = VecValidValues(X,2,PETSC_TRUE);CHKERRQ(ierr); 25156cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2516942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 25173232da50SPeter Brune 2518ce94432eSBarry Smith if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 2519ebd3b9afSBarry Smith 2520ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2521ebd3b9afSBarry Smith 2522fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2523fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2524f5af7f23SKarl Rupp 2525fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 2526fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 2527e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 252894ab13aaSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2529ebd3b9afSBarry Smith if (flag) { 253094ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 253194ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2532ebd3b9afSBarry Smith } 2533e35cf81dSBarry Smith PetscFunctionReturn(0); 253437ec4e1aSPeter Brune } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 2535e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 253694ab13aaSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2537ebd3b9afSBarry Smith if (flag) { 253894ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 253994ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2540ebd3b9afSBarry Smith } 2541e35cf81dSBarry Smith PetscFunctionReturn(0); 2542e35cf81dSBarry Smith } 2543efd4aadfSBarry Smith if (snes->npc && snes->npcside== PC_LEFT) { 254494ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 254594ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2546d728fb7dSPeter Brune PetscFunctionReturn(0); 2547d728fb7dSPeter Brune } 2548e35cf81dSBarry Smith 254994ab13aaSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 25505edff71fSBarry Smith ierr = VecLockPush(X);CHKERRQ(ierr); 2551d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 2552d1e9a80fSBarry Smith ierr = (*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx);CHKERRQ(ierr); 2553d64ed03dSBarry Smith PetscStackPop; 25545edff71fSBarry Smith ierr = VecLockPop(X);CHKERRQ(ierr); 255594ab13aaSBarry Smith ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 2556a8054027SBarry Smith 2557e0e3a89bSBarry Smith /* the next line ensures that snes->ksp exists */ 2558e0e3a89bSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 25593b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 25603b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 2561d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 25623b4f5425SBarry Smith snes->lagpreconditioner = -1; 25633b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 2564a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2565d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 256637ec4e1aSPeter Brune } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 2567a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2568d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 2569d1e9a80fSBarry Smith } else { 2570d1e9a80fSBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner\n");CHKERRQ(ierr); 2571d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 2572a8054027SBarry Smith } 2573a8054027SBarry Smith 2574e885f1abSBarry Smith ierr = SNESTestJacobian(snes);CHKERRQ(ierr); 25756d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 257694ab13aaSBarry Smith /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 257794ab13aaSBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2578693365a8SJed Brown { 2579693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 258027b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag);CHKERRQ(ierr); 258127b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr); 258227b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr); 258327b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator);CHKERRQ(ierr); 2584693365a8SJed Brown if (flag || flag_draw || flag_contour) { 25850298fd71SBarry Smith Mat Bexp_mine = NULL,Bexp,FDexp; 2586693365a8SJed Brown PetscViewer vdraw,vstdout; 25876b3a5b13SJed Brown PetscBool flg; 2588693365a8SJed Brown if (flag_operator) { 258994ab13aaSBarry Smith ierr = MatComputeExplicitOperator(A,&Bexp_mine);CHKERRQ(ierr); 2590693365a8SJed Brown Bexp = Bexp_mine; 2591693365a8SJed Brown } else { 2592693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 259394ab13aaSBarry Smith ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 259494ab13aaSBarry Smith if (flg) Bexp = B; 2595693365a8SJed Brown else { 2596693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 259794ab13aaSBarry Smith ierr = MatComputeExplicitOperator(B,&Bexp_mine);CHKERRQ(ierr); 2598693365a8SJed Brown Bexp = Bexp_mine; 2599693365a8SJed Brown } 2600693365a8SJed Brown } 2601693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2602d1e9a80fSBarry Smith ierr = SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL);CHKERRQ(ierr); 2603ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 2604693365a8SJed Brown if (flag_draw || flag_contour) { 2605ce94432eSBarry Smith ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2606693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 26070298fd71SBarry Smith } else vdraw = NULL; 2608693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");CHKERRQ(ierr); 2609693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2610693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2611693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2612693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2613693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2614693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2615693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2616693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2617693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2618693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2619693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2620693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2621693365a8SJed Brown } 2622693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2623693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2624693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2625693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2626693365a8SJed Brown } 2627693365a8SJed Brown } 26284c30e9fbSJed Brown { 26296719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 26306719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 263127b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag);CHKERRQ(ierr); 263227b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display);CHKERRQ(ierr); 263327b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr); 263427b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr); 263527b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold);CHKERRQ(ierr); 263627b0f280SBarry Smith if (flag_threshold) { 2637c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);CHKERRQ(ierr); 2638c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);CHKERRQ(ierr); 263927b0f280SBarry Smith } 26406719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 26414c30e9fbSJed Brown Mat Bfd; 26424c30e9fbSJed Brown PetscViewer vdraw,vstdout; 2643335efc43SPeter Brune MatColoring coloring; 26444c30e9fbSJed Brown ISColoring iscoloring; 26454c30e9fbSJed Brown MatFDColoring matfdcoloring; 26464c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 26474c30e9fbSJed Brown void *funcctx; 26486719d8e4SJed Brown PetscReal norm1,norm2,normmax; 26494c30e9fbSJed Brown 265094ab13aaSBarry Smith ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 2651335efc43SPeter Brune ierr = MatColoringCreate(Bfd,&coloring);CHKERRQ(ierr); 2652335efc43SPeter Brune ierr = MatColoringSetType(coloring,MATCOLORINGSL);CHKERRQ(ierr); 2653335efc43SPeter Brune ierr = MatColoringSetFromOptions(coloring);CHKERRQ(ierr); 2654335efc43SPeter Brune ierr = MatColoringApply(coloring,&iscoloring);CHKERRQ(ierr); 2655335efc43SPeter Brune ierr = MatColoringDestroy(&coloring);CHKERRQ(ierr); 26564c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 2657f86b9fbaSHong Zhang ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2658f86b9fbaSHong Zhang ierr = MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring);CHKERRQ(ierr); 26594c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 26604c30e9fbSJed Brown 26614c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 26620298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,&func,&funcctx);CHKERRQ(ierr); 26634c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr); 26644c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 26654c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 26664c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2667d1e9a80fSBarry Smith ierr = MatFDColoringApply(Bfd,matfdcoloring,X,snes);CHKERRQ(ierr); 26684c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 26694c30e9fbSJed Brown 2670ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 26714c30e9fbSJed Brown if (flag_draw || flag_contour) { 2672ce94432eSBarry Smith ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 26734c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 26740298fd71SBarry Smith } else vdraw = NULL; 26754c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 267694ab13aaSBarry Smith if (flag_display) {ierr = MatView(B,vstdout);CHKERRQ(ierr);} 267794ab13aaSBarry Smith if (vdraw) {ierr = MatView(B,vdraw);CHKERRQ(ierr);} 26784c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 26796719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 26804c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 268194ab13aaSBarry Smith ierr = MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 26824c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 26836719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 26844c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 268557622a8eSBarry 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); 26866719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 26874c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 26884c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 26894c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 26904c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 26914c30e9fbSJed Brown } 26924c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 26936719d8e4SJed Brown 26946719d8e4SJed Brown if (flag_threshold) { 26956719d8e4SJed Brown PetscInt bs,rstart,rend,i; 269694ab13aaSBarry Smith ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr); 269794ab13aaSBarry Smith ierr = MatGetOwnershipRange(B,&rstart,&rend);CHKERRQ(ierr); 26986719d8e4SJed Brown for (i=rstart; i<rend; i++) { 26996719d8e4SJed Brown const PetscScalar *ba,*ca; 27006719d8e4SJed Brown const PetscInt *bj,*cj; 27016719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 27026719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 270394ab13aaSBarry Smith ierr = MatGetRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 27046719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 270594ab13aaSBarry Smith if (bn != cn) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 27066719d8e4SJed Brown for (j=0; j<bn; j++) { 27076719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 27086719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 27096719d8e4SJed Brown maxentrycol = bj[j]; 27106719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 27116719d8e4SJed Brown } 27126719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 27136719d8e4SJed Brown maxdiffcol = bj[j]; 27146719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 27156719d8e4SJed Brown } 27166719d8e4SJed Brown if (rdiff > maxrdiff) { 27176719d8e4SJed Brown maxrdiffcol = bj[j]; 27186719d8e4SJed Brown maxrdiff = rdiff; 27196719d8e4SJed Brown } 27206719d8e4SJed Brown } 27216719d8e4SJed Brown if (maxrdiff > 1) { 272257622a8eSBarry 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); 27236719d8e4SJed Brown for (j=0; j<bn; j++) { 27246719d8e4SJed Brown PetscReal rdiff; 27256719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 27266719d8e4SJed Brown if (rdiff > 1) { 272757622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]));CHKERRQ(ierr); 27286719d8e4SJed Brown } 27296719d8e4SJed Brown } 27306719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 27316719d8e4SJed Brown } 273294ab13aaSBarry Smith ierr = MatRestoreRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 27336719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 27346719d8e4SJed Brown } 27356719d8e4SJed Brown } 27364c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 27374c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 27384c30e9fbSJed Brown } 27394c30e9fbSJed Brown } 27403a40ed3dSBarry Smith PetscFunctionReturn(0); 27419b94acceSBarry Smith } 27429b94acceSBarry Smith 2743bf388a1fSBarry Smith /*MC 2744411c0326SBarry Smith SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES 2745bf388a1fSBarry Smith 2746bf388a1fSBarry Smith Synopsis: 2747411c0326SBarry Smith #include "petscsnes.h" 2748411c0326SBarry Smith PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 2749bf388a1fSBarry Smith 2750bf388a1fSBarry Smith + x - input vector 2751e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 2752e5d3d808SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 2753bf388a1fSBarry Smith - ctx - [optional] user-defined Jacobian context 2754bf388a1fSBarry Smith 2755878cb397SSatish Balay Level: intermediate 2756878cb397SSatish Balay 2757bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian() 2758bf388a1fSBarry Smith M*/ 2759bf388a1fSBarry Smith 27609b94acceSBarry Smith /*@C 27619b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2762044dda88SLois Curfman McInnes location to store the matrix. 27639b94acceSBarry Smith 27643f9fe445SBarry Smith Logically Collective on SNES and Mat 2765c7afd0dbSLois Curfman McInnes 27669b94acceSBarry Smith Input Parameters: 2767c7afd0dbSLois Curfman McInnes + snes - the SNES context 2768e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 2769e5d3d808SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 2770411c0326SBarry Smith . J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details 2771c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 27720298fd71SBarry Smith Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value) 27739b94acceSBarry Smith 27749b94acceSBarry Smith Notes: 2775e5d3d808SBarry Smith If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on 277616913363SBarry Smith each matrix. 277716913363SBarry Smith 2778895c21f2SBarry Smith If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null 2779895c21f2SBarry Smith space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 2780895c21f2SBarry Smith 27818d359177SBarry Smith If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument 2782a8a26c1eSJed Brown must be a MatFDColoring. 2783a8a26c1eSJed Brown 2784c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2785c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2786c3cc8fd1SJed Brown 278736851e7fSLois Curfman McInnes Level: beginner 278836851e7fSLois Curfman McInnes 27899b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 27909b94acceSBarry Smith 2791411c0326SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J, 2792411c0326SBarry Smith SNESSetPicard(), SNESJacobianFunction 27939b94acceSBarry Smith @*/ 2794d1e9a80fSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 27959b94acceSBarry Smith { 2796dfbe8321SBarry Smith PetscErrorCode ierr; 27976cab3a1bSJed Brown DM dm; 27983a7fca6bSBarry Smith 27993a40ed3dSBarry Smith PetscFunctionBegin; 28000700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2801e5d3d808SBarry Smith if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 2802e5d3d808SBarry Smith if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 2803e5d3d808SBarry Smith if (Amat) PetscCheckSameComm(snes,1,Amat,2); 2804e5d3d808SBarry Smith if (Pmat) PetscCheckSameComm(snes,1,Pmat,3); 28056cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2806f8b49ee9SBarry Smith ierr = DMSNESSetJacobian(dm,J,ctx);CHKERRQ(ierr); 2807e5d3d808SBarry Smith if (Amat) { 2808e5d3d808SBarry Smith ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 28096bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 2810f5af7f23SKarl Rupp 2811e5d3d808SBarry Smith snes->jacobian = Amat; 28123a7fca6bSBarry Smith } 2813e5d3d808SBarry Smith if (Pmat) { 2814e5d3d808SBarry Smith ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr); 28156bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2816f5af7f23SKarl Rupp 2817e5d3d808SBarry Smith snes->jacobian_pre = Pmat; 28183a7fca6bSBarry Smith } 28193a40ed3dSBarry Smith PetscFunctionReturn(0); 28209b94acceSBarry Smith } 282162fef451SLois Curfman McInnes 2822c2aafc4cSSatish Balay /*@C 2823b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2824b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2825b4fd4287SBarry Smith 2826c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2827c7afd0dbSLois Curfman McInnes 2828b4fd4287SBarry Smith Input Parameter: 2829b4fd4287SBarry Smith . snes - the nonlinear solver context 2830b4fd4287SBarry Smith 2831b4fd4287SBarry Smith Output Parameters: 2832e5d3d808SBarry Smith + Amat - location to stash (approximate) Jacobian matrix (or NULL) 2833e5d3d808SBarry Smith . Pmat - location to stash matrix used to compute the preconditioner (or NULL) 2834411c0326SBarry Smith . J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence 28350298fd71SBarry Smith - ctx - location to stash Jacobian ctx (or NULL) 2836fee21e36SBarry Smith 283736851e7fSLois Curfman McInnes Level: advanced 283836851e7fSLois Curfman McInnes 2839411c0326SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction() 2840b4fd4287SBarry Smith @*/ 2841d1e9a80fSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 2842b4fd4287SBarry Smith { 28436cab3a1bSJed Brown PetscErrorCode ierr; 28446cab3a1bSJed Brown DM dm; 2845942e3340SBarry Smith DMSNES sdm; 28466cab3a1bSJed Brown 28473a40ed3dSBarry Smith PetscFunctionBegin; 28480700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2849e5d3d808SBarry Smith if (Amat) *Amat = snes->jacobian; 2850e5d3d808SBarry Smith if (Pmat) *Pmat = snes->jacobian_pre; 28516cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2852942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2853f8b49ee9SBarry Smith if (J) *J = sdm->ops->computejacobian; 28546cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 28553a40ed3dSBarry Smith PetscFunctionReturn(0); 2856b4fd4287SBarry Smith } 2857b4fd4287SBarry Smith 28589b94acceSBarry Smith /*@ 28599b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2860272ac6f2SLois Curfman McInnes of a nonlinear solver. 28619b94acceSBarry Smith 2862fee21e36SBarry Smith Collective on SNES 2863fee21e36SBarry Smith 2864c7afd0dbSLois Curfman McInnes Input Parameters: 286570e92668SMatthew Knepley . snes - the SNES context 2866c7afd0dbSLois Curfman McInnes 2867272ac6f2SLois Curfman McInnes Notes: 2868272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2869272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2870272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2871272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2872272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2873272ac6f2SLois Curfman McInnes 287436851e7fSLois Curfman McInnes Level: advanced 287536851e7fSLois Curfman McInnes 28769b94acceSBarry Smith .keywords: SNES, nonlinear, setup 28779b94acceSBarry Smith 28789b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 28799b94acceSBarry Smith @*/ 28807087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 28819b94acceSBarry Smith { 2882dfbe8321SBarry Smith PetscErrorCode ierr; 28836cab3a1bSJed Brown DM dm; 2884942e3340SBarry Smith DMSNES sdm; 2885c35f09e5SBarry Smith SNESLineSearch linesearch, pclinesearch; 28866e2a1849SPeter Brune void *lsprectx,*lspostctx; 28876b2b7091SBarry Smith PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*); 28886b2b7091SBarry Smith PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*); 28896e2a1849SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 28906e2a1849SPeter Brune Vec f,fpc; 28916e2a1849SPeter Brune void *funcctx; 2892d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 28931eb13d49SPeter Brune void *jacctx,*appctx; 289432b97717SPeter Brune Mat j,jpre; 28953a40ed3dSBarry Smith 28963a40ed3dSBarry Smith PetscFunctionBegin; 28970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 28984dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 28999b94acceSBarry Smith 29007adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 290104d7464bSBarry Smith ierr = SNESSetType(snes,SNESNEWTONLS);CHKERRQ(ierr); 290285385478SLisandro Dalcin } 290385385478SLisandro Dalcin 29040298fd71SBarry Smith ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr); 290558c9b817SLisandro Dalcin 29066cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2907942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2908ce94432eSBarry Smith if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object"); 290922c6f798SBarry Smith if (!sdm->ops->computejacobian) { 29108d359177SBarry Smith ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr); 291119f7a02aSBarry Smith } 29126cab3a1bSJed Brown if (!snes->vec_func) { 29136cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2914214df951SJed Brown } 2915efd51863SBarry Smith 291622d28d08SBarry Smith if (!snes->ksp) { 291722d28d08SBarry Smith ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr); 291822d28d08SBarry Smith } 2919b710008aSBarry Smith 292022d28d08SBarry Smith if (!snes->linesearch) { 29217601faf0SJed Brown ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 292222d28d08SBarry Smith } 2923ed07d7d7SPeter Brune ierr = SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction);CHKERRQ(ierr); 29249e764e56SPeter Brune 2925efd4aadfSBarry Smith if (snes->npc && (snes->npcside== PC_LEFT)) { 2926172a4300SPeter Brune snes->mf = PETSC_TRUE; 2927172a4300SPeter Brune snes->mf_operator = PETSC_FALSE; 2928172a4300SPeter Brune } 2929d8f46077SPeter Brune 2930efd4aadfSBarry Smith if (snes->npc) { 29316e2a1849SPeter Brune /* copy the DM over */ 29326e2a1849SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2933efd4aadfSBarry Smith ierr = SNESSetDM(snes->npc,dm);CHKERRQ(ierr); 29346e2a1849SPeter Brune 29356e2a1849SPeter Brune ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr); 29366e2a1849SPeter Brune ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr); 2937efd4aadfSBarry Smith ierr = SNESSetFunction(snes->npc,fpc,func,funcctx);CHKERRQ(ierr); 293832b97717SPeter Brune ierr = SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx);CHKERRQ(ierr); 2939efd4aadfSBarry Smith ierr = SNESSetJacobian(snes->npc,j,jpre,jac,jacctx);CHKERRQ(ierr); 29401eb13d49SPeter Brune ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr); 2941efd4aadfSBarry Smith ierr = SNESSetApplicationContext(snes->npc,appctx);CHKERRQ(ierr); 29426e2a1849SPeter Brune ierr = VecDestroy(&fpc);CHKERRQ(ierr); 29436e2a1849SPeter Brune 29446e2a1849SPeter Brune /* copy the function pointers over */ 2945efd4aadfSBarry Smith ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr); 29466e2a1849SPeter Brune 29476e2a1849SPeter Brune /* default to 1 iteration */ 2948efd4aadfSBarry Smith ierr = SNESSetTolerances(snes->npc,0.0,0.0,0.0,1,snes->npc->max_funcs);CHKERRQ(ierr); 2949efd4aadfSBarry Smith if (snes->npcside==PC_RIGHT) { 2950efd4aadfSBarry Smith ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 2951a9936a0cSPeter Brune } else { 2952efd4aadfSBarry Smith ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_NONE);CHKERRQ(ierr); 2953a9936a0cSPeter Brune } 2954efd4aadfSBarry Smith ierr = SNESSetFromOptions(snes->npc);CHKERRQ(ierr); 29556e2a1849SPeter Brune 29566e2a1849SPeter Brune /* copy the line search context over */ 29577601faf0SJed Brown ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 2958efd4aadfSBarry Smith ierr = SNESGetLineSearch(snes->npc,&pclinesearch);CHKERRQ(ierr); 29596b2b7091SBarry Smith ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr); 29606b2b7091SBarry Smith ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr); 29616b2b7091SBarry Smith ierr = SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);CHKERRQ(ierr); 29626b2b7091SBarry Smith ierr = SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);CHKERRQ(ierr); 29636e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 29646e2a1849SPeter Brune } 296532b97717SPeter Brune if (snes->mf) { 296632b97717SPeter Brune ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr); 296732b97717SPeter Brune } 296832b97717SPeter Brune if (snes->ops->usercompute && !snes->user) { 296932b97717SPeter Brune ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 297032b97717SPeter Brune } 29716e2a1849SPeter Brune 297237ec4e1aSPeter Brune snes->jac_iter = 0; 297337ec4e1aSPeter Brune snes->pre_iter = 0; 297437ec4e1aSPeter Brune 2975410397dcSLisandro Dalcin if (snes->ops->setup) { 2976410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2977410397dcSLisandro Dalcin } 297858c9b817SLisandro Dalcin 2979efd4aadfSBarry Smith if (snes->npc && (snes->npcside== PC_LEFT)) { 29806c67d002SPeter Brune if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 298155d4788fSPeter Brune ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 2982be95d8f1SBarry Smith ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC);CHKERRQ(ierr); 29836c67d002SPeter Brune } 29846c67d002SPeter Brune } 29856c67d002SPeter Brune 29867aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 29873a40ed3dSBarry Smith PetscFunctionReturn(0); 29889b94acceSBarry Smith } 29899b94acceSBarry Smith 299037596af1SLisandro Dalcin /*@ 299137596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 299237596af1SLisandro Dalcin 299337596af1SLisandro Dalcin Collective on SNES 299437596af1SLisandro Dalcin 299537596af1SLisandro Dalcin Input Parameter: 299637596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 299737596af1SLisandro Dalcin 2998d25893d9SBarry Smith Level: intermediate 2999d25893d9SBarry Smith 300095452b02SPatrick Sanan Notes: 300195452b02SPatrick Sanan Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 300237596af1SLisandro Dalcin 300337596af1SLisandro Dalcin .keywords: SNES, destroy 300437596af1SLisandro Dalcin 300537596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 300637596af1SLisandro Dalcin @*/ 300737596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 300837596af1SLisandro Dalcin { 300937596af1SLisandro Dalcin PetscErrorCode ierr; 301037596af1SLisandro Dalcin 301137596af1SLisandro Dalcin PetscFunctionBegin; 301237596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3013d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 3014d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 30150298fd71SBarry Smith snes->user = NULL; 3016d25893d9SBarry Smith } 3017efd4aadfSBarry Smith if (snes->npc) { 3018efd4aadfSBarry Smith ierr = SNESReset(snes->npc);CHKERRQ(ierr); 30198a23116dSBarry Smith } 30208a23116dSBarry Smith 302137596af1SLisandro Dalcin if (snes->ops->reset) { 302237596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 302337596af1SLisandro Dalcin } 30249e764e56SPeter Brune if (snes->ksp) { 30259e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 30269e764e56SPeter Brune } 30279e764e56SPeter Brune 30289e764e56SPeter Brune if (snes->linesearch) { 3029f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 30309e764e56SPeter Brune } 30319e764e56SPeter Brune 30326bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 30336bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 30346bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 30356bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 30366bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 30376bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 3038c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 3039c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 3040f5af7f23SKarl Rupp 304140fdac6aSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 304240fdac6aSLawrence Mitchell 304337596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 304437596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 304537596af1SLisandro Dalcin PetscFunctionReturn(0); 304637596af1SLisandro Dalcin } 304737596af1SLisandro Dalcin 304852baeb72SSatish Balay /*@ 30499b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 30509b94acceSBarry Smith with SNESCreate(). 30519b94acceSBarry Smith 3052c7afd0dbSLois Curfman McInnes Collective on SNES 3053c7afd0dbSLois Curfman McInnes 30549b94acceSBarry Smith Input Parameter: 30559b94acceSBarry Smith . snes - the SNES context 30569b94acceSBarry Smith 305736851e7fSLois Curfman McInnes Level: beginner 305836851e7fSLois Curfman McInnes 30599b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 30609b94acceSBarry Smith 306163a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 30629b94acceSBarry Smith @*/ 30636bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 30649b94acceSBarry Smith { 30656849ba73SBarry Smith PetscErrorCode ierr; 30663a40ed3dSBarry Smith 30673a40ed3dSBarry Smith PetscFunctionBegin; 30686bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 30696bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 30706bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 3071d4bb536fSBarry Smith 30726bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 3073efd4aadfSBarry Smith ierr = SNESDestroy(&(*snes)->npc);CHKERRQ(ierr); 30746b8b9a38SLisandro Dalcin 3075e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 3076e04113cfSBarry Smith ierr = PetscObjectSAWsViewOff((PetscObject)*snes);CHKERRQ(ierr); 30776bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 30786d4c513bSLisandro Dalcin 307933124788SMatthew G. Knepley if ((*snes)->dm) {ierr = DMCoarsenHookRemove((*snes)->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,*snes);CHKERRQ(ierr);} 30806bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 30816bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 3082f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 30836b8b9a38SLisandro Dalcin 30846bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 30856bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 30866bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 30876b8b9a38SLisandro Dalcin } 30886bf464f9SBarry Smith if ((*snes)->conv_malloc) { 30896bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 30906bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 309158c9b817SLisandro Dalcin } 30926bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 3093a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 30943a40ed3dSBarry Smith PetscFunctionReturn(0); 30959b94acceSBarry Smith } 30969b94acceSBarry Smith 30979b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 30989b94acceSBarry Smith 3099a8054027SBarry Smith /*@ 3100a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 3101a8054027SBarry Smith 31023f9fe445SBarry Smith Logically Collective on SNES 3103a8054027SBarry Smith 3104a8054027SBarry Smith Input Parameters: 3105a8054027SBarry Smith + snes - the SNES context 3106a8054027SBarry 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 31073b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3108a8054027SBarry Smith 3109a8054027SBarry Smith Options Database Keys: 3110a8054027SBarry Smith . -snes_lag_preconditioner <lag> 3111a8054027SBarry Smith 3112a8054027SBarry Smith Notes: 3113a8054027SBarry Smith The default is 1 3114a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3115a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 3116a8054027SBarry Smith 3117a8054027SBarry Smith Level: intermediate 3118a8054027SBarry Smith 3119a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 3120a8054027SBarry Smith 3121e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 3122a8054027SBarry Smith 3123a8054027SBarry Smith @*/ 31247087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 3125a8054027SBarry Smith { 3126a8054027SBarry Smith PetscFunctionBegin; 31270700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3128e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3129e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3130c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 3131a8054027SBarry Smith snes->lagpreconditioner = lag; 3132a8054027SBarry Smith PetscFunctionReturn(0); 3133a8054027SBarry Smith } 3134a8054027SBarry Smith 3135efd51863SBarry Smith /*@ 3136efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 3137efd51863SBarry Smith 3138efd51863SBarry Smith Logically Collective on SNES 3139efd51863SBarry Smith 3140efd51863SBarry Smith Input Parameters: 3141efd51863SBarry Smith + snes - the SNES context 3142efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 3143efd51863SBarry Smith 3144efd51863SBarry Smith Options Database Keys: 3145efd51863SBarry Smith . -snes_grid_sequence <steps> 3146efd51863SBarry Smith 3147efd51863SBarry Smith Level: intermediate 3148efd51863SBarry Smith 3149c0df2a02SJed Brown Notes: 3150c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3151c0df2a02SJed Brown 3152efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 3153efd51863SBarry Smith 3154fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetGridSequence() 3155efd51863SBarry Smith 3156efd51863SBarry Smith @*/ 3157efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 3158efd51863SBarry Smith { 3159efd51863SBarry Smith PetscFunctionBegin; 3160efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3161efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 3162efd51863SBarry Smith snes->gridsequence = steps; 3163efd51863SBarry Smith PetscFunctionReturn(0); 3164efd51863SBarry Smith } 3165efd51863SBarry Smith 3166fa19ca70SBarry Smith /*@ 3167fa19ca70SBarry Smith SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does 3168fa19ca70SBarry Smith 3169fa19ca70SBarry Smith Logically Collective on SNES 3170fa19ca70SBarry Smith 3171fa19ca70SBarry Smith Input Parameter: 3172fa19ca70SBarry Smith . snes - the SNES context 3173fa19ca70SBarry Smith 3174fa19ca70SBarry Smith Output Parameter: 3175fa19ca70SBarry Smith . steps - the number of refinements to do, defaults to 0 3176fa19ca70SBarry Smith 3177fa19ca70SBarry Smith Options Database Keys: 3178fa19ca70SBarry Smith . -snes_grid_sequence <steps> 3179fa19ca70SBarry Smith 3180fa19ca70SBarry Smith Level: intermediate 3181fa19ca70SBarry Smith 3182fa19ca70SBarry Smith Notes: 3183fa19ca70SBarry Smith Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3184fa19ca70SBarry Smith 3185fa19ca70SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 3186fa19ca70SBarry Smith 3187fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetGridSequence() 3188fa19ca70SBarry Smith 3189fa19ca70SBarry Smith @*/ 3190fa19ca70SBarry Smith PetscErrorCode SNESGetGridSequence(SNES snes,PetscInt *steps) 3191fa19ca70SBarry Smith { 3192fa19ca70SBarry Smith PetscFunctionBegin; 3193fa19ca70SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3194fa19ca70SBarry Smith *steps = snes->gridsequence; 3195fa19ca70SBarry Smith PetscFunctionReturn(0); 3196fa19ca70SBarry Smith } 3197fa19ca70SBarry Smith 3198a8054027SBarry Smith /*@ 3199a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 3200a8054027SBarry Smith 32013f9fe445SBarry Smith Not Collective 3202a8054027SBarry Smith 3203a8054027SBarry Smith Input Parameter: 3204a8054027SBarry Smith . snes - the SNES context 3205a8054027SBarry Smith 3206a8054027SBarry Smith Output Parameter: 3207a8054027SBarry 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 32083b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3209a8054027SBarry Smith 3210a8054027SBarry Smith Options Database Keys: 3211a8054027SBarry Smith . -snes_lag_preconditioner <lag> 3212a8054027SBarry Smith 3213a8054027SBarry Smith Notes: 3214a8054027SBarry Smith The default is 1 3215a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3216a8054027SBarry Smith 3217a8054027SBarry Smith Level: intermediate 3218a8054027SBarry Smith 3219a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 3220a8054027SBarry Smith 3221a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 3222a8054027SBarry Smith 3223a8054027SBarry Smith @*/ 32247087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 3225a8054027SBarry Smith { 3226a8054027SBarry Smith PetscFunctionBegin; 32270700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3228a8054027SBarry Smith *lag = snes->lagpreconditioner; 3229a8054027SBarry Smith PetscFunctionReturn(0); 3230a8054027SBarry Smith } 3231a8054027SBarry Smith 3232e35cf81dSBarry Smith /*@ 3233e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 3234e35cf81dSBarry Smith often the preconditioner is rebuilt. 3235e35cf81dSBarry Smith 32363f9fe445SBarry Smith Logically Collective on SNES 3237e35cf81dSBarry Smith 3238e35cf81dSBarry Smith Input Parameters: 3239e35cf81dSBarry Smith + snes - the SNES context 3240e35cf81dSBarry 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 3241fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 3242e35cf81dSBarry Smith 3243e35cf81dSBarry Smith Options Database Keys: 3244e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 3245e35cf81dSBarry Smith 3246e35cf81dSBarry Smith Notes: 3247e35cf81dSBarry Smith The default is 1 3248e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3249fe3ffe1eSBarry 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 3250fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 3251e35cf81dSBarry Smith 3252e35cf81dSBarry Smith Level: intermediate 3253e35cf81dSBarry Smith 3254e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 3255e35cf81dSBarry Smith 3256e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 3257e35cf81dSBarry Smith 3258e35cf81dSBarry Smith @*/ 32597087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 3260e35cf81dSBarry Smith { 3261e35cf81dSBarry Smith PetscFunctionBegin; 32620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3263e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3264e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3265c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 3266e35cf81dSBarry Smith snes->lagjacobian = lag; 3267e35cf81dSBarry Smith PetscFunctionReturn(0); 3268e35cf81dSBarry Smith } 3269e35cf81dSBarry Smith 3270e35cf81dSBarry Smith /*@ 3271e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 3272e35cf81dSBarry Smith 32733f9fe445SBarry Smith Not Collective 3274e35cf81dSBarry Smith 3275e35cf81dSBarry Smith Input Parameter: 3276e35cf81dSBarry Smith . snes - the SNES context 3277e35cf81dSBarry Smith 3278e35cf81dSBarry Smith Output Parameter: 3279e35cf81dSBarry 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 3280e35cf81dSBarry Smith the Jacobian is built etc. 3281e35cf81dSBarry Smith 3282e35cf81dSBarry Smith Options Database Keys: 3283e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 3284e35cf81dSBarry Smith 3285e35cf81dSBarry Smith Notes: 3286e35cf81dSBarry Smith The default is 1 3287e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3288e35cf81dSBarry Smith 3289e35cf81dSBarry Smith Level: intermediate 3290e35cf81dSBarry Smith 3291e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 3292e35cf81dSBarry Smith 3293e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 3294e35cf81dSBarry Smith 3295e35cf81dSBarry Smith @*/ 32967087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 3297e35cf81dSBarry Smith { 3298e35cf81dSBarry Smith PetscFunctionBegin; 32990700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3300e35cf81dSBarry Smith *lag = snes->lagjacobian; 3301e35cf81dSBarry Smith PetscFunctionReturn(0); 3302e35cf81dSBarry Smith } 3303e35cf81dSBarry Smith 330437ec4e1aSPeter Brune /*@ 330537ec4e1aSPeter Brune SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves 330637ec4e1aSPeter Brune 330737ec4e1aSPeter Brune Logically collective on SNES 330837ec4e1aSPeter Brune 330937ec4e1aSPeter Brune Input Parameter: 331037ec4e1aSPeter Brune + snes - the SNES context 33119d7e2deaSPeter Brune - flg - jacobian lagging persists if true 331237ec4e1aSPeter Brune 331337ec4e1aSPeter Brune Options Database Keys: 331437ec4e1aSPeter Brune . -snes_lag_jacobian_persists <flg> 331537ec4e1aSPeter Brune 331695452b02SPatrick Sanan Notes: 331795452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 331837ec4e1aSPeter Brune several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 331937ec4e1aSPeter Brune timesteps may present huge efficiency gains. 332037ec4e1aSPeter Brune 332137ec4e1aSPeter Brune Level: developer 332237ec4e1aSPeter Brune 3323be95d8f1SBarry Smith .keywords: SNES, nonlinear, lag 332437ec4e1aSPeter Brune 3325be95d8f1SBarry Smith .seealso: SNESSetLagPreconditionerPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC() 332637ec4e1aSPeter Brune 332737ec4e1aSPeter Brune @*/ 332837ec4e1aSPeter Brune PetscErrorCode SNESSetLagJacobianPersists(SNES snes,PetscBool flg) 332937ec4e1aSPeter Brune { 333037ec4e1aSPeter Brune PetscFunctionBegin; 333137ec4e1aSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 333237ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes,flg,2); 333337ec4e1aSPeter Brune snes->lagjac_persist = flg; 333437ec4e1aSPeter Brune PetscFunctionReturn(0); 333537ec4e1aSPeter Brune } 333637ec4e1aSPeter Brune 333737ec4e1aSPeter Brune /*@ 333837ec4e1aSPeter Brune SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple solves 333937ec4e1aSPeter Brune 334037ec4e1aSPeter Brune Logically Collective on SNES 334137ec4e1aSPeter Brune 334237ec4e1aSPeter Brune Input Parameter: 334337ec4e1aSPeter Brune + snes - the SNES context 33449d7e2deaSPeter Brune - flg - preconditioner lagging persists if true 334537ec4e1aSPeter Brune 334637ec4e1aSPeter Brune Options Database Keys: 334737ec4e1aSPeter Brune . -snes_lag_jacobian_persists <flg> 334837ec4e1aSPeter Brune 334995452b02SPatrick Sanan Notes: 335095452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 335137ec4e1aSPeter Brune by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 335237ec4e1aSPeter Brune several timesteps may present huge efficiency gains. 335337ec4e1aSPeter Brune 335437ec4e1aSPeter Brune Level: developer 335537ec4e1aSPeter Brune 3356be95d8f1SBarry Smith .keywords: SNES, nonlinear, lag 335737ec4e1aSPeter Brune 3358be95d8f1SBarry Smith .seealso: SNESSetLagJacobianPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC() 335937ec4e1aSPeter Brune 336037ec4e1aSPeter Brune @*/ 336137ec4e1aSPeter Brune PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg) 336237ec4e1aSPeter Brune { 336337ec4e1aSPeter Brune PetscFunctionBegin; 336437ec4e1aSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 336537ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes,flg,2); 336637ec4e1aSPeter Brune snes->lagpre_persist = flg; 336737ec4e1aSPeter Brune PetscFunctionReturn(0); 336837ec4e1aSPeter Brune } 336937ec4e1aSPeter Brune 33709b94acceSBarry Smith /*@ 3371be5caee7SBarry Smith SNESSetForceIteration - force SNESSolve() to take at least one iteration regardless of the initial residual norm 3372be5caee7SBarry Smith 3373be5caee7SBarry Smith Logically Collective on SNES 3374be5caee7SBarry Smith 3375be5caee7SBarry Smith Input Parameters: 3376be5caee7SBarry Smith + snes - the SNES context 3377be5caee7SBarry Smith - force - PETSC_TRUE require at least one iteration 3378be5caee7SBarry Smith 3379be5caee7SBarry Smith Options Database Keys: 3380be5caee7SBarry Smith . -snes_force_iteration <force> - Sets forcing an iteration 3381be5caee7SBarry Smith 3382be5caee7SBarry Smith Notes: 3383be5caee7SBarry Smith This is used sometimes with TS to prevent TS from detecting a false steady state solution 3384be5caee7SBarry Smith 3385be5caee7SBarry Smith Level: intermediate 3386be5caee7SBarry Smith 3387be5caee7SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 3388be5caee7SBarry Smith 3389be5caee7SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance() 3390be5caee7SBarry Smith @*/ 3391be5caee7SBarry Smith PetscErrorCode SNESSetForceIteration(SNES snes,PetscBool force) 3392be5caee7SBarry Smith { 3393be5caee7SBarry Smith PetscFunctionBegin; 3394be5caee7SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3395be5caee7SBarry Smith snes->forceiteration = force; 3396be5caee7SBarry Smith PetscFunctionReturn(0); 3397be5caee7SBarry Smith } 3398be5caee7SBarry Smith 339985216dc7SFande Kong /*@ 340085216dc7SFande Kong SNESGetForceIteration - Whether or not to force SNESSolve() take at least one iteration regardless of the initial residual norm 340185216dc7SFande Kong 340285216dc7SFande Kong Logically Collective on SNES 340385216dc7SFande Kong 340485216dc7SFande Kong Input Parameters: 340585216dc7SFande Kong . snes - the SNES context 340685216dc7SFande Kong 340785216dc7SFande Kong Output Parameter: 340885216dc7SFande Kong . force - PETSC_TRUE requires at least one iteration. 340985216dc7SFande Kong 341085216dc7SFande Kong .keywords: SNES, nonlinear, set, convergence, tolerances 341185216dc7SFande Kong 341206dd6b0eSSatish Balay Level: intermediate 341306dd6b0eSSatish Balay 341485216dc7SFande Kong .seealso: SNESSetForceIteration(), SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance() 341585216dc7SFande Kong @*/ 341685216dc7SFande Kong PetscErrorCode SNESGetForceIteration(SNES snes,PetscBool *force) 341785216dc7SFande Kong { 341885216dc7SFande Kong PetscFunctionBegin; 341985216dc7SFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 342085216dc7SFande Kong *force = snes->forceiteration; 342185216dc7SFande Kong PetscFunctionReturn(0); 342285216dc7SFande Kong } 3423be5caee7SBarry Smith 3424be5caee7SBarry Smith /*@ 3425d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 34269b94acceSBarry Smith 34273f9fe445SBarry Smith Logically Collective on SNES 3428c7afd0dbSLois Curfman McInnes 34299b94acceSBarry Smith Input Parameters: 3430c7afd0dbSLois Curfman McInnes + snes - the SNES context 343170441072SBarry Smith . abstol - absolute convergence tolerance 343233174efeSLois Curfman McInnes . rtol - relative convergence tolerance 34335358d0d4SBarry Smith . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 343433174efeSLois Curfman McInnes . maxit - maximum number of iterations 3435e71169deSBarry Smith - maxf - maximum number of function evaluations (-1 indicates no limit) 3436fee21e36SBarry Smith 343733174efeSLois Curfman McInnes Options Database Keys: 343870441072SBarry Smith + -snes_atol <abstol> - Sets abstol 3439c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 3440c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 3441c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 3442c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 34439b94acceSBarry Smith 3444d7a720efSLois Curfman McInnes Notes: 34459b94acceSBarry Smith The default maximum number of iterations is 50. 34469b94acceSBarry Smith The default maximum number of function evaluations is 1000. 34479b94acceSBarry Smith 344836851e7fSLois Curfman McInnes Level: intermediate 344936851e7fSLois Curfman McInnes 345033174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 34519b94acceSBarry Smith 3452be5caee7SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance(), SNESSetForceIteration() 34539b94acceSBarry Smith @*/ 34547087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 34559b94acceSBarry Smith { 34563a40ed3dSBarry Smith PetscFunctionBegin; 34570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3458c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 3459c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 3460c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 3461c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 3462c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 3463c5eb9154SBarry Smith 3464ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 346557622a8eSBarry Smith if (abstol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol); 3466ab54825eSJed Brown snes->abstol = abstol; 3467ab54825eSJed Brown } 3468ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 346957622a8eSBarry 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); 3470ab54825eSJed Brown snes->rtol = rtol; 3471ab54825eSJed Brown } 3472ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 347357622a8eSBarry Smith if (stol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol); 3474c60f73f4SPeter Brune snes->stol = stol; 3475ab54825eSJed Brown } 3476ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 3477ce94432eSBarry Smith if (maxit < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 3478ab54825eSJed Brown snes->max_its = maxit; 3479ab54825eSJed Brown } 3480ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 3481e71169deSBarry Smith if (maxf < -1) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be -1 or nonnegative",maxf); 3482ab54825eSJed Brown snes->max_funcs = maxf; 3483ab54825eSJed Brown } 348488976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 34853a40ed3dSBarry Smith PetscFunctionReturn(0); 34869b94acceSBarry Smith } 34879b94acceSBarry Smith 3488e4d06f11SPatrick Farrell /*@ 3489e4d06f11SPatrick Farrell SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test. 3490e4d06f11SPatrick Farrell 3491e4d06f11SPatrick Farrell Logically Collective on SNES 3492e4d06f11SPatrick Farrell 3493e4d06f11SPatrick Farrell Input Parameters: 3494e4d06f11SPatrick Farrell + snes - the SNES context 3495e4d06f11SPatrick Farrell - divtol - the divergence tolerance. Use -1 to deactivate the test. 3496e4d06f11SPatrick Farrell 3497e4d06f11SPatrick Farrell Options Database Keys: 3498e4d06f11SPatrick Farrell + -snes_divergence_tolerance <divtol> - Sets divtol 3499e4d06f11SPatrick Farrell 3500e4d06f11SPatrick Farrell Notes: 3501e4d06f11SPatrick Farrell The default divergence tolerance is 1e4. 3502e4d06f11SPatrick Farrell 3503e4d06f11SPatrick Farrell Level: intermediate 3504e4d06f11SPatrick Farrell 3505e4d06f11SPatrick Farrell .keywords: SNES, nonlinear, set, divergence, tolerance 3506e4d06f11SPatrick Farrell 3507e4d06f11SPatrick Farrell .seealso: SNESSetTolerances(), SNESGetDivergenceTolerance 3508e4d06f11SPatrick Farrell @*/ 3509e4d06f11SPatrick Farrell PetscErrorCode SNESSetDivergenceTolerance(SNES snes,PetscReal divtol) 3510e4d06f11SPatrick Farrell { 3511e4d06f11SPatrick Farrell PetscFunctionBegin; 3512e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3513e4d06f11SPatrick Farrell PetscValidLogicalCollectiveReal(snes,divtol,2); 3514e4d06f11SPatrick Farrell 3515e4d06f11SPatrick Farrell if (divtol != PETSC_DEFAULT) { 3516e4d06f11SPatrick Farrell snes->divtol = divtol; 3517e4d06f11SPatrick Farrell } 3518e4d06f11SPatrick Farrell else { 3519e4d06f11SPatrick Farrell snes->divtol = 1.0e4; 3520e4d06f11SPatrick Farrell } 3521e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3522e4d06f11SPatrick Farrell } 3523e4d06f11SPatrick Farrell 35249b94acceSBarry Smith /*@ 352533174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 352633174efeSLois Curfman McInnes 3527c7afd0dbSLois Curfman McInnes Not Collective 3528c7afd0dbSLois Curfman McInnes 352933174efeSLois Curfman McInnes Input Parameters: 3530c7afd0dbSLois Curfman McInnes + snes - the SNES context 353185385478SLisandro Dalcin . atol - absolute convergence tolerance 353233174efeSLois Curfman McInnes . rtol - relative convergence tolerance 353333174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 353433174efeSLois Curfman McInnes of the change in the solution between steps 353533174efeSLois Curfman McInnes . maxit - maximum number of iterations 3536c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 3537fee21e36SBarry Smith 353833174efeSLois Curfman McInnes Notes: 35390298fd71SBarry Smith The user can specify NULL for any parameter that is not needed. 354033174efeSLois Curfman McInnes 354136851e7fSLois Curfman McInnes Level: intermediate 354236851e7fSLois Curfman McInnes 354333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 354433174efeSLois Curfman McInnes 354533174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 354633174efeSLois Curfman McInnes @*/ 35477087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 354833174efeSLois Curfman McInnes { 35493a40ed3dSBarry Smith PetscFunctionBegin; 35500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 355185385478SLisandro Dalcin if (atol) *atol = snes->abstol; 355233174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 3553c60f73f4SPeter Brune if (stol) *stol = snes->stol; 355433174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 355533174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 35563a40ed3dSBarry Smith PetscFunctionReturn(0); 355733174efeSLois Curfman McInnes } 355833174efeSLois Curfman McInnes 3559e4d06f11SPatrick Farrell /*@ 3560e4d06f11SPatrick Farrell SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test. 3561e4d06f11SPatrick Farrell 3562e4d06f11SPatrick Farrell Not Collective 3563e4d06f11SPatrick Farrell 3564e4d06f11SPatrick Farrell Input Parameters: 3565e4d06f11SPatrick Farrell + snes - the SNES context 3566e4d06f11SPatrick Farrell - divtol - divergence tolerance 3567e4d06f11SPatrick Farrell 3568e4d06f11SPatrick Farrell Level: intermediate 3569e4d06f11SPatrick Farrell 3570e4d06f11SPatrick Farrell .keywords: SNES, nonlinear, get, divergence, tolerance 3571e4d06f11SPatrick Farrell 3572e4d06f11SPatrick Farrell .seealso: SNESSetDivergenceTolerance() 3573e4d06f11SPatrick Farrell @*/ 3574e4d06f11SPatrick Farrell PetscErrorCode SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol) 3575e4d06f11SPatrick Farrell { 3576e4d06f11SPatrick Farrell PetscFunctionBegin; 3577e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3578e4d06f11SPatrick Farrell if (divtol) *divtol = snes->divtol; 3579e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3580e4d06f11SPatrick Farrell } 3581e4d06f11SPatrick Farrell 358233174efeSLois Curfman McInnes /*@ 35839b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 35849b94acceSBarry Smith 35853f9fe445SBarry Smith Logically Collective on SNES 3586fee21e36SBarry Smith 3587c7afd0dbSLois Curfman McInnes Input Parameters: 3588c7afd0dbSLois Curfman McInnes + snes - the SNES context 3589c7afd0dbSLois Curfman McInnes - tol - tolerance 3590c7afd0dbSLois Curfman McInnes 35919b94acceSBarry Smith Options Database Key: 3592c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 35939b94acceSBarry Smith 359436851e7fSLois Curfman McInnes Level: intermediate 359536851e7fSLois Curfman McInnes 35969b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 35979b94acceSBarry Smith 35982492ecdbSBarry Smith .seealso: SNESSetTolerances() 35999b94acceSBarry Smith @*/ 36007087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 36019b94acceSBarry Smith { 36023a40ed3dSBarry Smith PetscFunctionBegin; 36030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3604c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 36059b94acceSBarry Smith snes->deltatol = tol; 36063a40ed3dSBarry Smith PetscFunctionReturn(0); 36079b94acceSBarry Smith } 36089b94acceSBarry Smith 3609df9fa365SBarry Smith /* 3610df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 3611df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 3612df9fa365SBarry Smith macros instead of functions 3613df9fa365SBarry Smith */ 3614d96771aaSLisandro Dalcin PetscErrorCode SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx) 3615ce1608b8SBarry Smith { 3616dfbe8321SBarry Smith PetscErrorCode ierr; 3617ce1608b8SBarry Smith 3618ce1608b8SBarry Smith PetscFunctionBegin; 36190700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3620d96771aaSLisandro Dalcin ierr = KSPMonitorLGResidualNorm((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 3621ce1608b8SBarry Smith PetscFunctionReturn(0); 3622ce1608b8SBarry Smith } 3623ce1608b8SBarry Smith 3624d96771aaSLisandro Dalcin PetscErrorCode SNESMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *lgctx) 3625df9fa365SBarry Smith { 3626dfbe8321SBarry Smith PetscErrorCode ierr; 3627df9fa365SBarry Smith 3628df9fa365SBarry Smith PetscFunctionBegin; 3629d96771aaSLisandro Dalcin ierr = KSPMonitorLGResidualNormCreate(comm,host,label,x,y,m,n,lgctx);CHKERRQ(ierr); 3630df9fa365SBarry Smith PetscFunctionReturn(0); 3631df9fa365SBarry Smith } 3632df9fa365SBarry Smith 36336ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 36346ba87a44SLisandro Dalcin 36357087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 3636b271bb04SBarry Smith { 3637b271bb04SBarry Smith PetscDrawLG lg; 3638b271bb04SBarry Smith PetscErrorCode ierr; 3639b271bb04SBarry Smith PetscReal x,y,per; 3640b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 3641b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 3642b271bb04SBarry Smith PetscDraw draw; 3643b271bb04SBarry Smith 3644459f5d12SBarry Smith PetscFunctionBegin; 36454d4332d5SBarry Smith PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4); 3646b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 3647b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3648b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3649b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 3650b271bb04SBarry Smith x = (PetscReal)n; 365177b4d14cSPeter Brune if (rnorm > 0.0) y = PetscLog10Real(rnorm); 365294c9c6d3SKarl Rupp else y = -15.0; 3653b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 36546934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3655b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 36566934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3657b271bb04SBarry Smith } 3658b271bb04SBarry Smith 3659b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 3660b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3661b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3662b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 3663b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 3664b271bb04SBarry Smith x = (PetscReal)n; 3665b271bb04SBarry Smith y = 100.0*per; 3666b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 36676934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3668b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 36696934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3670b271bb04SBarry Smith } 3671b271bb04SBarry Smith 3672b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 3673b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3674b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3675b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 3676b271bb04SBarry Smith x = (PetscReal)n; 3677b271bb04SBarry Smith y = (prev - rnorm)/prev; 3678b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 36796934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3680b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 36816934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3682b271bb04SBarry Smith } 3683b271bb04SBarry Smith 3684b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 3685b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3686b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3687b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 3688b271bb04SBarry Smith x = (PetscReal)n; 3689b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 3690b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 3691b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3692b271bb04SBarry Smith } 36936934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3694b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 36956934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3696b271bb04SBarry Smith } 3697b271bb04SBarry Smith prev = rnorm; 3698b271bb04SBarry Smith PetscFunctionReturn(0); 3699b271bb04SBarry Smith } 3700b271bb04SBarry Smith 3701228d79bcSJed Brown /*@ 3702228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 3703228d79bcSJed Brown 3704228d79bcSJed Brown Collective on SNES 3705228d79bcSJed Brown 3706228d79bcSJed Brown Input Parameters: 3707228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 3708228d79bcSJed Brown . iter - iteration number 3709228d79bcSJed Brown - rnorm - relative norm of the residual 3710228d79bcSJed Brown 3711228d79bcSJed Brown Notes: 3712228d79bcSJed Brown This routine is called by the SNES implementations. 3713228d79bcSJed Brown It does not typically need to be called by the user. 3714228d79bcSJed Brown 3715228d79bcSJed Brown Level: developer 3716228d79bcSJed Brown 3717228d79bcSJed Brown .seealso: SNESMonitorSet() 3718228d79bcSJed Brown @*/ 37197a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 37207a03ce2fSLisandro Dalcin { 37217a03ce2fSLisandro Dalcin PetscErrorCode ierr; 37227a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 37237a03ce2fSLisandro Dalcin 37247a03ce2fSLisandro Dalcin PetscFunctionBegin; 37255edff71fSBarry Smith ierr = VecLockPush(snes->vec_sol);CHKERRQ(ierr); 37267a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 37277a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 37287a03ce2fSLisandro Dalcin } 37295edff71fSBarry Smith ierr = VecLockPop(snes->vec_sol);CHKERRQ(ierr); 37307a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 37317a03ce2fSLisandro Dalcin } 37327a03ce2fSLisandro Dalcin 37339b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 37349b94acceSBarry Smith 3735bf388a1fSBarry Smith /*MC 3736bf388a1fSBarry Smith SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver 3737bf388a1fSBarry Smith 3738bf388a1fSBarry Smith Synopsis: 3739aaa7dc30SBarry Smith #include <petscsnes.h> 3740bf388a1fSBarry Smith $ PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3741bf388a1fSBarry Smith 3742bf388a1fSBarry Smith + snes - the SNES context 3743bf388a1fSBarry Smith . its - iteration number 3744bf388a1fSBarry Smith . norm - 2-norm function value (may be estimated) 3745bf388a1fSBarry Smith - mctx - [optional] monitoring context 3746bf388a1fSBarry Smith 3747878cb397SSatish Balay Level: advanced 3748878cb397SSatish Balay 3749bf388a1fSBarry Smith .seealso: SNESMonitorSet(), SNESMonitorGet() 3750bf388a1fSBarry Smith M*/ 3751bf388a1fSBarry Smith 37529b94acceSBarry Smith /*@C 3753a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 37549b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 37559b94acceSBarry Smith progress. 37569b94acceSBarry Smith 37573f9fe445SBarry Smith Logically Collective on SNES 3758fee21e36SBarry Smith 3759c7afd0dbSLois Curfman McInnes Input Parameters: 3760c7afd0dbSLois Curfman McInnes + snes - the SNES context 37616e4dcb14SBarry Smith . f - the monitor function, see SNESMonitorFunction for the calling sequence 3762b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 37630298fd71SBarry Smith monitor routine (use NULL if no context is desired) 3764b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 37650298fd71SBarry Smith (may be NULL) 37669b94acceSBarry Smith 37679665c990SLois Curfman McInnes Options Database Keys: 3768a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 37694619e776SBarry Smith . -snes_monitor_lg_residualnorm - sets line graph monitor, 3770a6570f20SBarry Smith uses SNESMonitorLGCreate() 3771cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 3772c7afd0dbSLois Curfman McInnes been hardwired into a code by 3773a6570f20SBarry Smith calls to SNESMonitorSet(), but 3774c7afd0dbSLois Curfman McInnes does not cancel those set via 3775c7afd0dbSLois Curfman McInnes the options database. 37769665c990SLois Curfman McInnes 3777639f9d9dSBarry Smith Notes: 37786bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3779a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 37806bc08f3fSLois Curfman McInnes order in which they were set. 3781639f9d9dSBarry Smith 378295452b02SPatrick Sanan Fortran Notes: 378395452b02SPatrick Sanan Only a single monitor function can be set for each SNES object 3784025f1a04SBarry Smith 378536851e7fSLois Curfman McInnes Level: intermediate 378636851e7fSLois Curfman McInnes 37879b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 37889b94acceSBarry Smith 3789bf388a1fSBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction 37909b94acceSBarry Smith @*/ 37916e4dcb14SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 37929b94acceSBarry Smith { 3793b90d0a6eSBarry Smith PetscInt i; 3794649052a6SBarry Smith PetscErrorCode ierr; 379578064530SBarry Smith PetscBool identical; 3796b90d0a6eSBarry Smith 37973a40ed3dSBarry Smith PetscFunctionBegin; 37980700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3799b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 380078064530SBarry Smith ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical);CHKERRQ(ierr); 380178064530SBarry Smith if (identical) PetscFunctionReturn(0); 3802649052a6SBarry Smith } 380378064530SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 38046e4dcb14SBarry Smith snes->monitor[snes->numbermonitors] = f; 3805b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3806639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 38073a40ed3dSBarry Smith PetscFunctionReturn(0); 38089b94acceSBarry Smith } 38099b94acceSBarry Smith 3810a278d85bSSatish Balay /*@ 3811a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 38125cd90555SBarry Smith 38133f9fe445SBarry Smith Logically Collective on SNES 3814c7afd0dbSLois Curfman McInnes 38155cd90555SBarry Smith Input Parameters: 38165cd90555SBarry Smith . snes - the SNES context 38175cd90555SBarry Smith 38181a480d89SAdministrator Options Database Key: 3819a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3820a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3821c7afd0dbSLois Curfman McInnes set via the options database 38225cd90555SBarry Smith 38235cd90555SBarry Smith Notes: 38245cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 38255cd90555SBarry Smith 382636851e7fSLois Curfman McInnes Level: intermediate 382736851e7fSLois Curfman McInnes 38285cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 38295cd90555SBarry Smith 3830a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 38315cd90555SBarry Smith @*/ 38327087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 38335cd90555SBarry Smith { 3834d952e501SBarry Smith PetscErrorCode ierr; 3835d952e501SBarry Smith PetscInt i; 3836d952e501SBarry Smith 38375cd90555SBarry Smith PetscFunctionBegin; 38380700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3839d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 3840d952e501SBarry Smith if (snes->monitordestroy[i]) { 38413c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3842d952e501SBarry Smith } 3843d952e501SBarry Smith } 38445cd90555SBarry Smith snes->numbermonitors = 0; 38455cd90555SBarry Smith PetscFunctionReturn(0); 38465cd90555SBarry Smith } 38475cd90555SBarry Smith 3848bf388a1fSBarry Smith /*MC 3849bf388a1fSBarry Smith SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 3850bf388a1fSBarry Smith 3851bf388a1fSBarry Smith Synopsis: 3852aaa7dc30SBarry Smith #include <petscsnes.h> 3853bf388a1fSBarry Smith $ PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3854bf388a1fSBarry Smith 3855bf388a1fSBarry Smith + snes - the SNES context 3856bf388a1fSBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3857bf388a1fSBarry Smith . cctx - [optional] convergence context 3858bf388a1fSBarry Smith . reason - reason for convergence/divergence 3859bf388a1fSBarry Smith . xnorm - 2-norm of current iterate 3860bf388a1fSBarry Smith . gnorm - 2-norm of current step 3861bf388a1fSBarry Smith - f - 2-norm of function 3862bf388a1fSBarry Smith 3863878cb397SSatish Balay Level: intermediate 3864bf388a1fSBarry Smith 3865bf388a1fSBarry Smith .seealso: SNESSetConvergenceTest(), SNESGetConvergenceTest() 3866bf388a1fSBarry Smith M*/ 3867bf388a1fSBarry Smith 38689b94acceSBarry Smith /*@C 38699b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 38709b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 38719b94acceSBarry Smith 38723f9fe445SBarry Smith Logically Collective on SNES 3873fee21e36SBarry Smith 3874c7afd0dbSLois Curfman McInnes Input Parameters: 3875c7afd0dbSLois Curfman McInnes + snes - the SNES context 3876bf388a1fSBarry Smith . SNESConvergenceTestFunction - routine to test for convergence 38770298fd71SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be NULL) 38780298fd71SBarry Smith - destroy - [optional] destructor for the context (may be NULL; NULL_FUNCTION in Fortran) 38799b94acceSBarry Smith 388036851e7fSLois Curfman McInnes Level: advanced 388136851e7fSLois Curfman McInnes 38829b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 38839b94acceSBarry Smith 3884e2a6519dSDmitry Karpeev .seealso: SNESConvergedDefault(), SNESConvergedSkip(), SNESConvergenceTestFunction 38859b94acceSBarry Smith @*/ 3886bf388a1fSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 38879b94acceSBarry Smith { 38887f7931b9SBarry Smith PetscErrorCode ierr; 38897f7931b9SBarry Smith 38903a40ed3dSBarry Smith PetscFunctionBegin; 38910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3892e2a6519dSDmitry Karpeev if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 38937f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 38947f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 38957f7931b9SBarry Smith } 3896bf388a1fSBarry Smith snes->ops->converged = SNESConvergenceTestFunction; 38977f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 389885385478SLisandro Dalcin snes->cnvP = cctx; 38993a40ed3dSBarry Smith PetscFunctionReturn(0); 39009b94acceSBarry Smith } 39019b94acceSBarry Smith 390252baeb72SSatish Balay /*@ 3903184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3904184914b5SBarry Smith 3905184914b5SBarry Smith Not Collective 3906184914b5SBarry Smith 3907184914b5SBarry Smith Input Parameter: 3908184914b5SBarry Smith . snes - the SNES context 3909184914b5SBarry Smith 3910184914b5SBarry Smith Output Parameter: 39114d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3912184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 3913184914b5SBarry Smith 39146a4d7782SBarry Smith Options Database: 39156a4d7782SBarry Smith . -snes_converged_reason - prints the reason to standard out 39166a4d7782SBarry Smith 3917184914b5SBarry Smith Level: intermediate 3918184914b5SBarry Smith 391995452b02SPatrick Sanan Notes: 392095452b02SPatrick Sanan Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING. 3921184914b5SBarry Smith 3922184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 3923184914b5SBarry Smith 392433866048SMatthew G. Knepley .seealso: SNESSetConvergenceTest(), SNESSetConvergedReason(), SNESConvergedReason 3925184914b5SBarry Smith @*/ 39267087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3927184914b5SBarry Smith { 3928184914b5SBarry Smith PetscFunctionBegin; 39290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 39304482741eSBarry Smith PetscValidPointer(reason,2); 3931184914b5SBarry Smith *reason = snes->reason; 3932184914b5SBarry Smith PetscFunctionReturn(0); 3933184914b5SBarry Smith } 3934184914b5SBarry Smith 393533866048SMatthew G. Knepley /*@ 393633866048SMatthew G. Knepley SNESSetConvergedReason - Sets the reason the SNES iteration was stopped. 393733866048SMatthew G. Knepley 393833866048SMatthew G. Knepley Not Collective 393933866048SMatthew G. Knepley 394033866048SMatthew G. Knepley Input Parameters: 394133866048SMatthew G. Knepley + snes - the SNES context 394233866048SMatthew G. Knepley - reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 394333866048SMatthew G. Knepley manual pages for the individual convergence tests for complete lists 394433866048SMatthew G. Knepley 394533866048SMatthew G. Knepley Level: intermediate 394633866048SMatthew G. Knepley 394733866048SMatthew G. Knepley .keywords: SNES, nonlinear, set, convergence, test 394833866048SMatthew G. Knepley .seealso: SNESGetConvergedReason(), SNESSetConvergenceTest(), SNESConvergedReason 394933866048SMatthew G. Knepley @*/ 395033866048SMatthew G. Knepley PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason) 395133866048SMatthew G. Knepley { 395233866048SMatthew G. Knepley PetscFunctionBegin; 395333866048SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 395433866048SMatthew G. Knepley snes->reason = reason; 395533866048SMatthew G. Knepley PetscFunctionReturn(0); 395633866048SMatthew G. Knepley } 395733866048SMatthew G. Knepley 3958c9005455SLois Curfman McInnes /*@ 3959c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3960c9005455SLois Curfman McInnes 39613f9fe445SBarry Smith Logically Collective on SNES 3962fee21e36SBarry Smith 3963c7afd0dbSLois Curfman McInnes Input Parameters: 3964c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 39658c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3966cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3967758f92a0SBarry Smith . na - size of a and its 396864731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3969758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3970c7afd0dbSLois Curfman McInnes 3971308dcc3eSBarry Smith Notes: 39720298fd71SBarry Smith If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3973308dcc3eSBarry Smith default array of length 10000 is allocated. 3974308dcc3eSBarry Smith 3975c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3976c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3977c9005455SLois Curfman McInnes during the section of code that is being timed. 3978c9005455SLois Curfman McInnes 397936851e7fSLois Curfman McInnes Level: intermediate 398036851e7fSLois Curfman McInnes 3981c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3982758f92a0SBarry Smith 398308405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3984758f92a0SBarry Smith 3985c9005455SLois Curfman McInnes @*/ 39867087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3987c9005455SLois Curfman McInnes { 3988308dcc3eSBarry Smith PetscErrorCode ierr; 3989308dcc3eSBarry Smith 39903a40ed3dSBarry Smith PetscFunctionBegin; 39910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 39927a1ec6d4SBarry Smith if (a) PetscValidScalarPointer(a,2); 3993a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 39947a1ec6d4SBarry Smith if (!a) { 3995308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 39967fdeb8b9SBarry Smith ierr = PetscCalloc1(na,&a);CHKERRQ(ierr); 39977fdeb8b9SBarry Smith ierr = PetscCalloc1(na,&its);CHKERRQ(ierr); 3998f5af7f23SKarl Rupp 3999308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 4000308dcc3eSBarry Smith } 4001c9005455SLois Curfman McInnes snes->conv_hist = a; 4002758f92a0SBarry Smith snes->conv_hist_its = its; 4003758f92a0SBarry Smith snes->conv_hist_max = na; 4004a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 4005758f92a0SBarry Smith snes->conv_hist_reset = reset; 4006758f92a0SBarry Smith PetscFunctionReturn(0); 4007758f92a0SBarry Smith } 4008758f92a0SBarry Smith 4009308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4010c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 4011c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 401299e0435eSBarry Smith 40138cc058d9SJed Brown PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 4014308dcc3eSBarry Smith { 4015308dcc3eSBarry Smith mxArray *mat; 4016308dcc3eSBarry Smith PetscInt i; 4017308dcc3eSBarry Smith PetscReal *ar; 4018308dcc3eSBarry Smith 4019308dcc3eSBarry Smith PetscFunctionBegin; 4020308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 4021308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 4022f5af7f23SKarl Rupp for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 4023308dcc3eSBarry Smith PetscFunctionReturn(mat); 4024308dcc3eSBarry Smith } 4025308dcc3eSBarry Smith #endif 4026308dcc3eSBarry Smith 40270c4c9dddSBarry Smith /*@C 4028758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 4029758f92a0SBarry Smith 40303f9fe445SBarry Smith Not Collective 4031758f92a0SBarry Smith 4032758f92a0SBarry Smith Input Parameter: 4033758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 4034758f92a0SBarry Smith 4035758f92a0SBarry Smith Output Parameters: 4036758f92a0SBarry Smith . a - array to hold history 4037758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 4038758f92a0SBarry Smith negative if not converged) for each solve. 4039758f92a0SBarry Smith - na - size of a and its 4040758f92a0SBarry Smith 4041758f92a0SBarry Smith Notes: 4042758f92a0SBarry Smith The calling sequence for this routine in Fortran is 4043758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 4044758f92a0SBarry Smith 4045758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 4046758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 4047758f92a0SBarry Smith during the section of code that is being timed. 4048758f92a0SBarry Smith 4049758f92a0SBarry Smith Level: intermediate 4050758f92a0SBarry Smith 4051758f92a0SBarry Smith .keywords: SNES, get, convergence, history 4052758f92a0SBarry Smith 4053758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 4054758f92a0SBarry Smith 4055758f92a0SBarry Smith @*/ 40567087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 4057758f92a0SBarry Smith { 4058758f92a0SBarry Smith PetscFunctionBegin; 40590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4060758f92a0SBarry Smith if (a) *a = snes->conv_hist; 4061758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 4062758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 40633a40ed3dSBarry Smith PetscFunctionReturn(0); 4064c9005455SLois Curfman McInnes } 4065c9005455SLois Curfman McInnes 4066ac226902SBarry Smith /*@C 406776b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 4068eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 40697e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 407076b2cf59SMatthew Knepley 40713f9fe445SBarry Smith Logically Collective on SNES 407276b2cf59SMatthew Knepley 407376b2cf59SMatthew Knepley Input Parameters: 407476b2cf59SMatthew Knepley . snes - The nonlinear solver context 407576b2cf59SMatthew Knepley . func - The function 407676b2cf59SMatthew Knepley 407776b2cf59SMatthew Knepley Calling sequence of func: 4078b5d30489SBarry Smith . func (SNES snes, PetscInt step); 407976b2cf59SMatthew Knepley 408076b2cf59SMatthew Knepley . step - The current step of the iteration 408176b2cf59SMatthew Knepley 4082fe97e370SBarry Smith Level: advanced 4083fe97e370SBarry Smith 4084fe97e370SBarry 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() 4085fe97e370SBarry Smith This is not used by most users. 408676b2cf59SMatthew Knepley 408776b2cf59SMatthew Knepley .keywords: SNES, update 4088b5d30489SBarry Smith 40898d359177SBarry Smith .seealso SNESSetJacobian(), SNESSolve() 409076b2cf59SMatthew Knepley @*/ 40917087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 409276b2cf59SMatthew Knepley { 409376b2cf59SMatthew Knepley PetscFunctionBegin; 40940700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 4095e7788613SBarry Smith snes->ops->update = func; 409676b2cf59SMatthew Knepley PetscFunctionReturn(0); 409776b2cf59SMatthew Knepley } 409876b2cf59SMatthew Knepley 40999b94acceSBarry Smith /* 41009b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 41019b94acceSBarry Smith positive parameter delta. 41029b94acceSBarry Smith 41039b94acceSBarry Smith Input Parameters: 4104c7afd0dbSLois Curfman McInnes + snes - the SNES context 41059b94acceSBarry Smith . y - approximate solution of linear system 41069b94acceSBarry Smith . fnorm - 2-norm of current function 4107c7afd0dbSLois Curfman McInnes - delta - trust region size 41089b94acceSBarry Smith 41099b94acceSBarry Smith Output Parameters: 4110c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 41119b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 41129b94acceSBarry Smith region, and exceeds zero otherwise. 4113c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 41149b94acceSBarry Smith 41159b94acceSBarry Smith Note: 411604d7464bSBarry Smith For non-trust region methods such as SNESNEWTONLS, the parameter delta 41179b94acceSBarry Smith is set to be the maximum allowable step size. 41189b94acceSBarry Smith 41199b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 41209b94acceSBarry Smith */ 4121dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 41229b94acceSBarry Smith { 4123064f8208SBarry Smith PetscReal nrm; 4124ea709b57SSatish Balay PetscScalar cnorm; 4125dfbe8321SBarry Smith PetscErrorCode ierr; 41263a40ed3dSBarry Smith 41273a40ed3dSBarry Smith PetscFunctionBegin; 41280700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41290700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 4130c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 4131184914b5SBarry Smith 4132064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 4133064f8208SBarry Smith if (nrm > *delta) { 4134064f8208SBarry Smith nrm = *delta/nrm; 4135064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 4136064f8208SBarry Smith cnorm = nrm; 41372dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 41389b94acceSBarry Smith *ynorm = *delta; 41399b94acceSBarry Smith } else { 41409b94acceSBarry Smith *gpnorm = 0.0; 4141064f8208SBarry Smith *ynorm = nrm; 41429b94acceSBarry Smith } 41433a40ed3dSBarry Smith PetscFunctionReturn(0); 41449b94acceSBarry Smith } 41459b94acceSBarry Smith 41462a359c20SBarry Smith /*@ 41472a359c20SBarry Smith SNESReasonView - Displays the reason a SNES solve converged or diverged to a viewer 41482a359c20SBarry Smith 41492a359c20SBarry Smith Collective on SNES 41502a359c20SBarry Smith 41512a359c20SBarry Smith Parameter: 41522a359c20SBarry Smith + snes - iterative context obtained from SNESCreate() 41532a359c20SBarry Smith - viewer - the viewer to display the reason 41542a359c20SBarry Smith 41552a359c20SBarry Smith 41562a359c20SBarry Smith Options Database Keys: 41572a359c20SBarry Smith . -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 41582a359c20SBarry Smith 41592a359c20SBarry Smith Level: beginner 41602a359c20SBarry Smith 41612a359c20SBarry Smith .keywords: SNES, solve, linear system 41622a359c20SBarry Smith 41632a359c20SBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault() 41642a359c20SBarry Smith 41652a359c20SBarry Smith @*/ 41662a359c20SBarry Smith PetscErrorCode SNESReasonView(SNES snes,PetscViewer viewer) 41672a359c20SBarry Smith { 416875cca76cSMatthew G. Knepley PetscViewerFormat format; 41692a359c20SBarry Smith PetscBool isAscii; 417075cca76cSMatthew G. Knepley PetscErrorCode ierr; 41712a359c20SBarry Smith 41722a359c20SBarry Smith PetscFunctionBegin; 41732a359c20SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);CHKERRQ(ierr); 41742a359c20SBarry Smith if (isAscii) { 417575cca76cSMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 41762a359c20SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 417775cca76cSMatthew G. Knepley if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 417875cca76cSMatthew G. Knepley DM dm; 417975cca76cSMatthew G. Knepley Vec u; 418075cca76cSMatthew G. Knepley PetscDS prob; 418175cca76cSMatthew G. Knepley PetscInt Nf, f; 418275cca76cSMatthew G. Knepley PetscErrorCode (**exactFuncs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 418375cca76cSMatthew G. Knepley PetscReal error; 418475cca76cSMatthew G. Knepley 418575cca76cSMatthew G. Knepley ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 418675cca76cSMatthew G. Knepley ierr = SNESGetSolution(snes, &u);CHKERRQ(ierr); 418775cca76cSMatthew G. Knepley ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 418875cca76cSMatthew G. Knepley ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 418975cca76cSMatthew G. Knepley ierr = PetscMalloc1(Nf, &exactFuncs);CHKERRQ(ierr); 419075cca76cSMatthew G. Knepley for (f = 0; f < Nf; ++f) {ierr = PetscDSGetExactSolution(prob, f, &exactFuncs[f]);CHKERRQ(ierr);} 419175cca76cSMatthew G. Knepley ierr = DMComputeL2Diff(dm, 0.0, exactFuncs, NULL, u, &error);CHKERRQ(ierr); 419275cca76cSMatthew G. Knepley ierr = PetscFree(exactFuncs);CHKERRQ(ierr); 419375cca76cSMatthew G. Knepley if (error < 1.0e-11) {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n");CHKERRQ(ierr);} 419475cca76cSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", error);CHKERRQ(ierr);} 419575cca76cSMatthew G. Knepley } 41962a359c20SBarry Smith if (snes->reason > 0) { 41972a359c20SBarry Smith if (((PetscObject) snes)->prefix) { 41982a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 41992a359c20SBarry Smith } else { 42002a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 42012a359c20SBarry Smith } 42022a359c20SBarry Smith } else { 42032a359c20SBarry Smith if (((PetscObject) snes)->prefix) { 42042a359c20SBarry 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); 42052a359c20SBarry Smith } else { 42062a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 42072a359c20SBarry Smith } 42082a359c20SBarry Smith } 42092a359c20SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 42102a359c20SBarry Smith } 42112a359c20SBarry Smith PetscFunctionReturn(0); 42122a359c20SBarry Smith } 42132a359c20SBarry Smith 42142a359c20SBarry Smith /*@C 42152a359c20SBarry Smith SNESReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed. 42162a359c20SBarry Smith 42172a359c20SBarry Smith Collective on SNES 42182a359c20SBarry Smith 42192a359c20SBarry Smith Input Parameters: 42202a359c20SBarry Smith . snes - the SNES object 42212a359c20SBarry Smith 42222a359c20SBarry Smith Level: intermediate 42232a359c20SBarry Smith 42242a359c20SBarry Smith @*/ 42252a359c20SBarry Smith PetscErrorCode SNESReasonViewFromOptions(SNES snes) 42262a359c20SBarry Smith { 42272a359c20SBarry Smith PetscErrorCode ierr; 42282a359c20SBarry Smith PetscViewer viewer; 42292a359c20SBarry Smith PetscBool flg; 42302a359c20SBarry Smith static PetscBool incall = PETSC_FALSE; 42312a359c20SBarry Smith PetscViewerFormat format; 42322a359c20SBarry Smith 42332a359c20SBarry Smith PetscFunctionBegin; 42342a359c20SBarry Smith if (incall) PetscFunctionReturn(0); 42352a359c20SBarry Smith incall = PETSC_TRUE; 42362a359c20SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg);CHKERRQ(ierr); 42372a359c20SBarry Smith if (flg) { 42382a359c20SBarry Smith ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 42392a359c20SBarry Smith ierr = SNESReasonView(snes,viewer);CHKERRQ(ierr); 42402a359c20SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 42412a359c20SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 42422a359c20SBarry Smith } 42432a359c20SBarry Smith incall = PETSC_FALSE; 42442a359c20SBarry Smith PetscFunctionReturn(0); 42452a359c20SBarry Smith } 42462a359c20SBarry Smith 4247487a658cSBarry Smith /*@ 4248f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 4249f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 42509b94acceSBarry Smith 4251c7afd0dbSLois Curfman McInnes Collective on SNES 4252c7afd0dbSLois Curfman McInnes 4253b2002411SLois Curfman McInnes Input Parameters: 4254c7afd0dbSLois Curfman McInnes + snes - the SNES context 42550298fd71SBarry Smith . b - the constant part of the equation F(x) = b, or NULL to use zero. 425685385478SLisandro Dalcin - x - the solution vector. 42579b94acceSBarry Smith 4258b2002411SLois Curfman McInnes Notes: 42598ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 42608ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 42618ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 42628ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 42638ddd3da0SLois Curfman McInnes 426436851e7fSLois Curfman McInnes Level: beginner 426536851e7fSLois Curfman McInnes 42669b94acceSBarry Smith .keywords: SNES, nonlinear, solve 42679b94acceSBarry Smith 4268c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 42699b94acceSBarry Smith @*/ 42707087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 42719b94acceSBarry Smith { 4272dfbe8321SBarry Smith PetscErrorCode ierr; 4273ace3abfcSBarry Smith PetscBool flg; 4274efd51863SBarry Smith PetscInt grid; 42750298fd71SBarry Smith Vec xcreated = NULL; 4276caa4e7f2SJed Brown DM dm; 4277052efed2SBarry Smith 42783a40ed3dSBarry Smith PetscFunctionBegin; 42790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4280a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 4281a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 42820700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 428385385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 428485385478SLisandro Dalcin 428534b4d3a8SMatthew G. Knepley /* High level operations using the nonlinear solver */ 428606fc46c8SMatthew G. Knepley { 428706fc46c8SMatthew G. Knepley PetscViewer viewer; 428806fc46c8SMatthew G. Knepley PetscViewerFormat format; 42897c88af5aSMatthew G. Knepley PetscInt num; 429006fc46c8SMatthew G. Knepley PetscBool flg; 429106fc46c8SMatthew G. Knepley static PetscBool incall = PETSC_FALSE; 429206fc46c8SMatthew G. Knepley 429306fc46c8SMatthew G. Knepley if (!incall) { 429434b4d3a8SMatthew G. Knepley /* Estimate the convergence rate of the discretization */ 429506fc46c8SMatthew G. Knepley ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) snes), ((PetscObject) snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg);CHKERRQ(ierr); 429606fc46c8SMatthew G. Knepley if (flg) { 429706fc46c8SMatthew G. Knepley PetscConvEst conv; 429846079b62SMatthew G. Knepley DM dm; 429946079b62SMatthew G. Knepley PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 430046079b62SMatthew G. Knepley PetscInt Nf; 430106fc46c8SMatthew G. Knepley 430206fc46c8SMatthew G. Knepley incall = PETSC_TRUE; 430346079b62SMatthew G. Knepley ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 430446079b62SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 430546079b62SMatthew G. Knepley ierr = PetscMalloc1(Nf, &alpha);CHKERRQ(ierr); 430606fc46c8SMatthew G. Knepley ierr = PetscConvEstCreate(PetscObjectComm((PetscObject) snes), &conv);CHKERRQ(ierr); 430706fc46c8SMatthew G. Knepley ierr = PetscConvEstSetSolver(conv, snes);CHKERRQ(ierr); 430806fc46c8SMatthew G. Knepley ierr = PetscConvEstSetFromOptions(conv);CHKERRQ(ierr); 43090955ed61SMatthew G. Knepley ierr = PetscConvEstSetUp(conv);CHKERRQ(ierr); 431046079b62SMatthew G. Knepley ierr = PetscConvEstGetConvRate(conv, alpha);CHKERRQ(ierr); 431106fc46c8SMatthew G. Knepley ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr); 431206fc46c8SMatthew G. Knepley ierr = PetscConvEstRateView(conv, alpha, viewer);CHKERRQ(ierr); 431306fc46c8SMatthew G. Knepley ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 431406fc46c8SMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 431506fc46c8SMatthew G. Knepley ierr = PetscConvEstDestroy(&conv);CHKERRQ(ierr); 431646079b62SMatthew G. Knepley ierr = PetscFree(alpha);CHKERRQ(ierr); 431706fc46c8SMatthew G. Knepley incall = PETSC_FALSE; 431806fc46c8SMatthew G. Knepley } 431934b4d3a8SMatthew G. Knepley /* Adaptively refine the initial grid */ 4320b2588ea6SMatthew G. Knepley num = 1; 4321b2588ea6SMatthew G. Knepley ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_initial", &num, &flg);CHKERRQ(ierr); 432234b4d3a8SMatthew G. Knepley if (flg) { 432334b4d3a8SMatthew G. Knepley DMAdaptor adaptor; 432434b4d3a8SMatthew G. Knepley 432534b4d3a8SMatthew G. Knepley incall = PETSC_TRUE; 432634b4d3a8SMatthew G. Knepley ierr = DMAdaptorCreate(PETSC_COMM_WORLD, &adaptor);CHKERRQ(ierr); 432734b4d3a8SMatthew G. Knepley ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr); 4328b2588ea6SMatthew G. Knepley ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr); 432934b4d3a8SMatthew G. Knepley ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr); 433034b4d3a8SMatthew G. Knepley ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr); 433134b4d3a8SMatthew G. Knepley ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x);CHKERRQ(ierr); 433234b4d3a8SMatthew G. Knepley ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr); 433334b4d3a8SMatthew G. Knepley incall = PETSC_FALSE; 433434b4d3a8SMatthew G. Knepley } 43357c88af5aSMatthew G. Knepley /* Use grid sequencing to adapt */ 43367c88af5aSMatthew G. Knepley num = 0; 43377c88af5aSMatthew G. Knepley ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_sequence", &num, NULL);CHKERRQ(ierr); 43387c88af5aSMatthew G. Knepley if (num) { 43397c88af5aSMatthew G. Knepley DMAdaptor adaptor; 43407c88af5aSMatthew G. Knepley 43417c88af5aSMatthew G. Knepley incall = PETSC_TRUE; 43427c88af5aSMatthew G. Knepley ierr = DMAdaptorCreate(PETSC_COMM_WORLD, &adaptor);CHKERRQ(ierr); 43437c88af5aSMatthew G. Knepley ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr); 43447c88af5aSMatthew G. Knepley ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr); 43457c88af5aSMatthew G. Knepley ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr); 43467c88af5aSMatthew G. Knepley ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr); 43477c88af5aSMatthew G. Knepley ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x);CHKERRQ(ierr); 43487c88af5aSMatthew G. Knepley ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr); 43497c88af5aSMatthew G. Knepley incall = PETSC_FALSE; 43507c88af5aSMatthew G. Knepley } 435106fc46c8SMatthew G. Knepley } 435206fc46c8SMatthew G. Knepley } 4353caa4e7f2SJed Brown if (!x) { 4354caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4355caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 4356a69afd8bSBarry Smith x = xcreated; 4357a69afd8bSBarry Smith } 4358ce1779c8SBarry Smith ierr = SNESViewFromOptions(snes,NULL,"-snes_view_pre");CHKERRQ(ierr); 4359f05ece33SBarry Smith 4360ce94432eSBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);} 4361efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 4362efd51863SBarry Smith 436385385478SLisandro Dalcin /* set solution vector */ 4364efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 43656bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 436685385478SLisandro Dalcin snes->vec_sol = x; 4367caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4368caa4e7f2SJed Brown 4369caa4e7f2SJed Brown /* set affine vector if provided */ 437085385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 43716bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 437285385478SLisandro Dalcin snes->vec_rhs = b; 437385385478SLisandro Dalcin 4374154060b5SMatthew G. Knepley if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 4375154060b5SMatthew 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"); 4376154060b5SMatthew G. Knepley if (!snes->vec_sol_update /* && snes->vec_sol */) { 4377154060b5SMatthew G. Knepley ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 4378154060b5SMatthew G. Knepley ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);CHKERRQ(ierr); 4379154060b5SMatthew G. Knepley } 4380154060b5SMatthew G. Knepley ierr = DMShellSetGlobalVector(dm,snes->vec_sol);CHKERRQ(ierr); 438170e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 43823f149594SLisandro Dalcin 43837eee914bSBarry Smith if (!grid) { 43847eee914bSBarry Smith if (snes->ops->computeinitialguess) { 4385d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 4386d25893d9SBarry Smith } 4387dd568438SSatish Balay } 4388d25893d9SBarry Smith 4389abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 4390971e163fSPeter Brune if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;} 4391d5e45103SBarry Smith 43923f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 43934936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 439485385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 439517186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 4396422a814eSBarry Smith snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 43973f149594SLisandro Dalcin 439837ec4e1aSPeter Brune if (snes->lagjac_persist) snes->jac_iter += snes->iter; 439937ec4e1aSPeter Brune if (snes->lagpre_persist) snes->pre_iter += snes->iter; 440037ec4e1aSPeter Brune 440127b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg);CHKERRQ(ierr); 4402da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 44032a359c20SBarry Smith ierr = SNESReasonViewFromOptions(snes);CHKERRQ(ierr); 44045968eb51SBarry Smith 4405ce94432eSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 44069c8e83a9SBarry Smith if (snes->reason < 0) break; 4407efd51863SBarry Smith if (grid < snes->gridsequence) { 4408efd51863SBarry Smith DM fine; 4409efd51863SBarry Smith Vec xnew; 4410efd51863SBarry Smith Mat interp; 4411efd51863SBarry Smith 4412ce94432eSBarry Smith ierr = DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);CHKERRQ(ierr); 4413ce94432eSBarry Smith if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 44140298fd71SBarry Smith ierr = DMCreateInterpolation(snes->dm,fine,&interp,NULL);CHKERRQ(ierr); 4415efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 4416efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 4417c833c3b5SJed Brown ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 4418efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 4419efd51863SBarry Smith x = xnew; 4420efd51863SBarry Smith 4421efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 4422efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 4423352f405dSMatthew G. Knepley ierr = SNESResetFromOptions(snes);CHKERRQ(ierr); 4424efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 4425ce94432eSBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr); 4426efd51863SBarry Smith } 4427efd51863SBarry Smith } 4428ce1779c8SBarry Smith ierr = SNESViewFromOptions(snes,NULL,"-snes_view");CHKERRQ(ierr); 4429685405a1SBarry Smith ierr = VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution");CHKERRQ(ierr); 44303f7e2da0SPeter Brune 4431a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 4432e04113cfSBarry Smith ierr = PetscObjectSAWsBlock((PetscObject)snes);CHKERRQ(ierr); 44333a40ed3dSBarry Smith PetscFunctionReturn(0); 44349b94acceSBarry Smith } 44359b94acceSBarry Smith 44369b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 44379b94acceSBarry Smith 443882bf6240SBarry Smith /*@C 44394b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 44409b94acceSBarry Smith 4441fee21e36SBarry Smith Collective on SNES 4442fee21e36SBarry Smith 4443c7afd0dbSLois Curfman McInnes Input Parameters: 4444c7afd0dbSLois Curfman McInnes + snes - the SNES context 4445454a90a3SBarry Smith - type - a known method 4446c7afd0dbSLois Curfman McInnes 4447c7afd0dbSLois Curfman McInnes Options Database Key: 4448454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 444904d7464bSBarry Smith of available methods (for instance, newtonls or newtontr) 4450ae12b187SLois Curfman McInnes 44519b94acceSBarry Smith Notes: 4452e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 445304d7464bSBarry Smith + SNESNEWTONLS - Newton's method with line search 4454c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 445504d7464bSBarry Smith . SNESNEWTONTR - Newton's method with trust region 4456c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 44579b94acceSBarry Smith 4458ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 4459ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 4460ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 4461ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 4462ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 4463ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 4464ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 4465ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 4466ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 4467b0a32e0cSBarry Smith appropriate method. 446836851e7fSLois Curfman McInnes 446995452b02SPatrick Sanan Developer Notes: 447095452b02SPatrick Sanan SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates 44718f6c3df8SBarry Smith the constructor in that list and calls it to create the spexific object. 44728f6c3df8SBarry Smith 447336851e7fSLois Curfman McInnes Level: intermediate 4474a703fe33SLois Curfman McInnes 4475454a90a3SBarry Smith .keywords: SNES, set, type 4476435da068SBarry Smith 44778f6c3df8SBarry Smith .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions() 4478435da068SBarry Smith 44799b94acceSBarry Smith @*/ 448019fd82e9SBarry Smith PetscErrorCode SNESSetType(SNES snes,SNESType type) 44819b94acceSBarry Smith { 4482dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 4483ace3abfcSBarry Smith PetscBool match; 44843a40ed3dSBarry Smith 44853a40ed3dSBarry Smith PetscFunctionBegin; 44860700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 44874482741eSBarry Smith PetscValidCharPointer(type,2); 448882bf6240SBarry Smith 4489251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 44900f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 449192ff6ae8SBarry Smith 44921c9cd337SJed Brown ierr = PetscFunctionListFind(SNESList,type,&r);CHKERRQ(ierr); 4493e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 449475396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 4495b5c23020SJed Brown if (snes->ops->destroy) { 4496b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 44970298fd71SBarry Smith snes->ops->destroy = NULL; 4498b5c23020SJed Brown } 449975396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 450075396ef9SLisandro Dalcin snes->ops->setup = 0; 450175396ef9SLisandro Dalcin snes->ops->solve = 0; 450275396ef9SLisandro Dalcin snes->ops->view = 0; 450375396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 450475396ef9SLisandro Dalcin snes->ops->destroy = 0; 450575396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 450675396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 4507f5af7f23SKarl Rupp 4508454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 450903bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 45103a40ed3dSBarry Smith PetscFunctionReturn(0); 45119b94acceSBarry Smith } 45129b94acceSBarry Smith 45139b94acceSBarry Smith /*@C 45149a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 45159b94acceSBarry Smith 4516c7afd0dbSLois Curfman McInnes Not Collective 4517c7afd0dbSLois Curfman McInnes 45189b94acceSBarry Smith Input Parameter: 45194b0e389bSBarry Smith . snes - nonlinear solver context 45209b94acceSBarry Smith 45219b94acceSBarry Smith Output Parameter: 45223a7fca6bSBarry Smith . type - SNES method (a character string) 45239b94acceSBarry Smith 452436851e7fSLois Curfman McInnes Level: intermediate 452536851e7fSLois Curfman McInnes 4526454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 45279b94acceSBarry Smith @*/ 452819fd82e9SBarry Smith PetscErrorCode SNESGetType(SNES snes,SNESType *type) 45299b94acceSBarry Smith { 45303a40ed3dSBarry Smith PetscFunctionBegin; 45310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 45324482741eSBarry Smith PetscValidPointer(type,2); 45337adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 45343a40ed3dSBarry Smith PetscFunctionReturn(0); 45359b94acceSBarry Smith } 45369b94acceSBarry Smith 45373cd8a7caSMatthew G. Knepley /*@ 45383cd8a7caSMatthew G. Knepley SNESSetSolution - Sets the solution vector for use by the SNES routines. 45393cd8a7caSMatthew G. Knepley 45403cd8a7caSMatthew G. Knepley Logically Collective on SNES and Vec 45413cd8a7caSMatthew G. Knepley 45423cd8a7caSMatthew G. Knepley Input Parameters: 45433cd8a7caSMatthew G. Knepley + snes - the SNES context obtained from SNESCreate() 45443cd8a7caSMatthew G. Knepley - u - the solution vector 45453cd8a7caSMatthew G. Knepley 45463cd8a7caSMatthew G. Knepley Level: beginner 45473cd8a7caSMatthew G. Knepley 45483cd8a7caSMatthew G. Knepley .keywords: SNES, set, solution 45493cd8a7caSMatthew G. Knepley @*/ 45503cd8a7caSMatthew G. Knepley PetscErrorCode SNESSetSolution(SNES snes, Vec u) 45513cd8a7caSMatthew G. Knepley { 45523cd8a7caSMatthew G. Knepley DM dm; 45533cd8a7caSMatthew G. Knepley PetscErrorCode ierr; 45543cd8a7caSMatthew G. Knepley 45553cd8a7caSMatthew G. Knepley PetscFunctionBegin; 45563cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 45573cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 45583cd8a7caSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) u);CHKERRQ(ierr); 45593cd8a7caSMatthew G. Knepley ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 45603cd8a7caSMatthew G. Knepley 45613cd8a7caSMatthew G. Knepley snes->vec_sol = u; 45623cd8a7caSMatthew G. Knepley 45633cd8a7caSMatthew G. Knepley ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 45643cd8a7caSMatthew G. Knepley ierr = DMShellSetGlobalVector(dm, u);CHKERRQ(ierr); 45653cd8a7caSMatthew G. Knepley PetscFunctionReturn(0); 45663cd8a7caSMatthew G. Knepley } 45673cd8a7caSMatthew G. Knepley 456852baeb72SSatish Balay /*@ 45699b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 4570c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 45719b94acceSBarry Smith 4572c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4573c7afd0dbSLois Curfman McInnes 45749b94acceSBarry Smith Input Parameter: 45759b94acceSBarry Smith . snes - the SNES context 45769b94acceSBarry Smith 45779b94acceSBarry Smith Output Parameter: 45789b94acceSBarry Smith . x - the solution 45799b94acceSBarry Smith 458070e92668SMatthew Knepley Level: intermediate 458136851e7fSLois Curfman McInnes 45829b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 45839b94acceSBarry Smith 458485385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 45859b94acceSBarry Smith @*/ 45867087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 45879b94acceSBarry Smith { 45883a40ed3dSBarry Smith PetscFunctionBegin; 45890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 45904482741eSBarry Smith PetscValidPointer(x,2); 459185385478SLisandro Dalcin *x = snes->vec_sol; 459270e92668SMatthew Knepley PetscFunctionReturn(0); 459370e92668SMatthew Knepley } 459470e92668SMatthew Knepley 459552baeb72SSatish Balay /*@ 45969b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 45979b94acceSBarry Smith stored. 45989b94acceSBarry Smith 4599c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4600c7afd0dbSLois Curfman McInnes 46019b94acceSBarry Smith Input Parameter: 46029b94acceSBarry Smith . snes - the SNES context 46039b94acceSBarry Smith 46049b94acceSBarry Smith Output Parameter: 46059b94acceSBarry Smith . x - the solution update 46069b94acceSBarry Smith 460736851e7fSLois Curfman McInnes Level: advanced 460836851e7fSLois Curfman McInnes 46099b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 46109b94acceSBarry Smith 461185385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 46129b94acceSBarry Smith @*/ 46137087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 46149b94acceSBarry Smith { 46153a40ed3dSBarry Smith PetscFunctionBegin; 46160700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 46174482741eSBarry Smith PetscValidPointer(x,2); 461885385478SLisandro Dalcin *x = snes->vec_sol_update; 46193a40ed3dSBarry Smith PetscFunctionReturn(0); 46209b94acceSBarry Smith } 46219b94acceSBarry Smith 46229b94acceSBarry Smith /*@C 46233638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 46249b94acceSBarry Smith 4625a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 4626c7afd0dbSLois Curfman McInnes 46279b94acceSBarry Smith Input Parameter: 46289b94acceSBarry Smith . snes - the SNES context 46299b94acceSBarry Smith 46309b94acceSBarry Smith Output Parameter: 46310298fd71SBarry Smith + r - the vector that is used to store residuals (or NULL if you don't want it) 4632f8b49ee9SBarry Smith . f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details 46330298fd71SBarry Smith - ctx - the function context (or NULL if you don't want it) 46349b94acceSBarry Smith 463536851e7fSLois Curfman McInnes Level: advanced 463636851e7fSLois Curfman McInnes 463704edfde5SBarry Smith Notes: The vector r DOES NOT, in general contain the current value of the SNES nonlinear function 463804edfde5SBarry Smith 4639a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 46409b94acceSBarry Smith 4641bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction 46429b94acceSBarry Smith @*/ 4643f8b49ee9SBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx) 46449b94acceSBarry Smith { 4645a63bb30eSJed Brown PetscErrorCode ierr; 46466cab3a1bSJed Brown DM dm; 4647a63bb30eSJed Brown 46483a40ed3dSBarry Smith PetscFunctionBegin; 46490700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4650a63bb30eSJed Brown if (r) { 4651a63bb30eSJed Brown if (!snes->vec_func) { 4652a63bb30eSJed Brown if (snes->vec_rhs) { 4653a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 4654a63bb30eSJed Brown } else if (snes->vec_sol) { 4655a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 4656a63bb30eSJed Brown } else if (snes->dm) { 4657a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 4658a63bb30eSJed Brown } 4659a63bb30eSJed Brown } 4660a63bb30eSJed Brown *r = snes->vec_func; 4661a63bb30eSJed Brown } 46626cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4663f8b49ee9SBarry Smith ierr = DMSNESGetFunction(dm,f,ctx);CHKERRQ(ierr); 46643a40ed3dSBarry Smith PetscFunctionReturn(0); 46659b94acceSBarry Smith } 46669b94acceSBarry Smith 4667c79ef259SPeter Brune /*@C 4668be95d8f1SBarry Smith SNESGetNGS - Returns the NGS function and context. 4669c79ef259SPeter Brune 4670c79ef259SPeter Brune Input Parameter: 4671c79ef259SPeter Brune . snes - the SNES context 4672c79ef259SPeter Brune 4673c79ef259SPeter Brune Output Parameter: 4674be95d8f1SBarry Smith + f - the function (or NULL) see SNESNGSFunction for details 46750298fd71SBarry Smith - ctx - the function context (or NULL) 4676c79ef259SPeter Brune 4677c79ef259SPeter Brune Level: advanced 4678c79ef259SPeter Brune 4679c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 4680c79ef259SPeter Brune 4681be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetFunction() 4682c79ef259SPeter Brune @*/ 4683c79ef259SPeter Brune 4684be95d8f1SBarry Smith PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx) 4685646217ecSPeter Brune { 46866cab3a1bSJed Brown PetscErrorCode ierr; 46876cab3a1bSJed Brown DM dm; 46886cab3a1bSJed Brown 4689646217ecSPeter Brune PetscFunctionBegin; 4690646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 46916cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4692be95d8f1SBarry Smith ierr = DMSNESGetNGS(dm,f,ctx);CHKERRQ(ierr); 4693646217ecSPeter Brune PetscFunctionReturn(0); 4694646217ecSPeter Brune } 4695646217ecSPeter Brune 46963c7409f5SSatish Balay /*@C 46973c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 4698d850072dSLois Curfman McInnes SNES options in the database. 46993c7409f5SSatish Balay 47003f9fe445SBarry Smith Logically Collective on SNES 4701fee21e36SBarry Smith 4702c7afd0dbSLois Curfman McInnes Input Parameter: 4703c7afd0dbSLois Curfman McInnes + snes - the SNES context 4704c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4705c7afd0dbSLois Curfman McInnes 4706d850072dSLois Curfman McInnes Notes: 4707a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4708c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4709d850072dSLois Curfman McInnes 471036851e7fSLois Curfman McInnes Level: advanced 471136851e7fSLois Curfman McInnes 47123c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 4713a86d99e1SLois Curfman McInnes 4714a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 47153c7409f5SSatish Balay @*/ 47167087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 47173c7409f5SSatish Balay { 4718dfbe8321SBarry Smith PetscErrorCode ierr; 47193c7409f5SSatish Balay 47203a40ed3dSBarry Smith PetscFunctionBegin; 47210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4722639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 47231cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 472435f5d045SPeter Brune if (snes->linesearch) { 47257601faf0SJed Brown ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 472608b6c495SPeter Brune ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 472735f5d045SPeter Brune } 472835f5d045SPeter Brune ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 47293a40ed3dSBarry Smith PetscFunctionReturn(0); 47303c7409f5SSatish Balay } 47313c7409f5SSatish Balay 47323c7409f5SSatish Balay /*@C 4733f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 4734d850072dSLois Curfman McInnes SNES options in the database. 47353c7409f5SSatish Balay 47363f9fe445SBarry Smith Logically Collective on SNES 4737fee21e36SBarry Smith 4738c7afd0dbSLois Curfman McInnes Input Parameters: 4739c7afd0dbSLois Curfman McInnes + snes - the SNES context 4740c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4741c7afd0dbSLois Curfman McInnes 4742d850072dSLois Curfman McInnes Notes: 4743a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4744c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4745d850072dSLois Curfman McInnes 474636851e7fSLois Curfman McInnes Level: advanced 474736851e7fSLois Curfman McInnes 47483c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 4749a86d99e1SLois Curfman McInnes 4750a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 47513c7409f5SSatish Balay @*/ 47527087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 47533c7409f5SSatish Balay { 4754dfbe8321SBarry Smith PetscErrorCode ierr; 47553c7409f5SSatish Balay 47563a40ed3dSBarry Smith PetscFunctionBegin; 47570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4758639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 47591cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 476035f5d045SPeter Brune if (snes->linesearch) { 47617601faf0SJed Brown ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 476208b6c495SPeter Brune ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 476335f5d045SPeter Brune } 476435f5d045SPeter Brune ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 47653a40ed3dSBarry Smith PetscFunctionReturn(0); 47663c7409f5SSatish Balay } 47673c7409f5SSatish Balay 47689ab63eb5SSatish Balay /*@C 47693c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 47703c7409f5SSatish Balay SNES options in the database. 47713c7409f5SSatish Balay 4772c7afd0dbSLois Curfman McInnes Not Collective 4773c7afd0dbSLois Curfman McInnes 47743c7409f5SSatish Balay Input Parameter: 47753c7409f5SSatish Balay . snes - the SNES context 47763c7409f5SSatish Balay 47773c7409f5SSatish Balay Output Parameter: 47783c7409f5SSatish Balay . prefix - pointer to the prefix string used 47793c7409f5SSatish Balay 478095452b02SPatrick Sanan Notes: 478195452b02SPatrick Sanan On the fortran side, the user should pass in a string 'prefix' of 47829ab63eb5SSatish Balay sufficient length to hold the prefix. 47839ab63eb5SSatish Balay 478436851e7fSLois Curfman McInnes Level: advanced 478536851e7fSLois Curfman McInnes 47863c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 4787a86d99e1SLois Curfman McInnes 4788a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 47893c7409f5SSatish Balay @*/ 47907087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 47913c7409f5SSatish Balay { 4792dfbe8321SBarry Smith PetscErrorCode ierr; 47933c7409f5SSatish Balay 47943a40ed3dSBarry Smith PetscFunctionBegin; 47950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4796639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 47973a40ed3dSBarry Smith PetscFunctionReturn(0); 47983c7409f5SSatish Balay } 47993c7409f5SSatish Balay 4800b2002411SLois Curfman McInnes 48013cea93caSBarry Smith /*@C 48021c84c290SBarry Smith SNESRegister - Adds a method to the nonlinear solver package. 48031c84c290SBarry Smith 48041c84c290SBarry Smith Not collective 48051c84c290SBarry Smith 48061c84c290SBarry Smith Input Parameters: 48071c84c290SBarry Smith + name_solver - name of a new user-defined solver 48081c84c290SBarry Smith - routine_create - routine to create method context 48091c84c290SBarry Smith 48101c84c290SBarry Smith Notes: 48111c84c290SBarry Smith SNESRegister() may be called multiple times to add several user-defined solvers. 48121c84c290SBarry Smith 48131c84c290SBarry Smith Sample usage: 48141c84c290SBarry Smith .vb 4815bdf89e91SBarry Smith SNESRegister("my_solver",MySolverCreate); 48161c84c290SBarry Smith .ve 48171c84c290SBarry Smith 48181c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 48191c84c290SBarry Smith $ SNESSetType(snes,"my_solver") 48201c84c290SBarry Smith or at runtime via the option 48211c84c290SBarry Smith $ -snes_type my_solver 48221c84c290SBarry Smith 48231c84c290SBarry Smith Level: advanced 48241c84c290SBarry Smith 48251c84c290SBarry Smith Note: If your function is not being put into a shared library then use SNESRegister() instead 48261c84c290SBarry Smith 48271c84c290SBarry Smith .keywords: SNES, nonlinear, register 48281c84c290SBarry Smith 48291c84c290SBarry Smith .seealso: SNESRegisterAll(), SNESRegisterDestroy() 48303cea93caSBarry Smith 48317f6c08e0SMatthew Knepley Level: advanced 48323cea93caSBarry Smith @*/ 4833bdf89e91SBarry Smith PetscErrorCode SNESRegister(const char sname[],PetscErrorCode (*function)(SNES)) 4834b2002411SLois Curfman McInnes { 4835dfbe8321SBarry Smith PetscErrorCode ierr; 4836b2002411SLois Curfman McInnes 4837b2002411SLois Curfman McInnes PetscFunctionBegin; 48381d36bdfdSBarry Smith ierr = SNESInitializePackage();CHKERRQ(ierr); 4839a240a19fSJed Brown ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr); 4840b2002411SLois Curfman McInnes PetscFunctionReturn(0); 4841b2002411SLois Curfman McInnes } 4842da9b6338SBarry Smith 48437087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 4844da9b6338SBarry Smith { 4845dfbe8321SBarry Smith PetscErrorCode ierr; 484677431f27SBarry Smith PetscInt N,i,j; 4847da9b6338SBarry Smith Vec u,uh,fh; 4848da9b6338SBarry Smith PetscScalar value; 4849da9b6338SBarry Smith PetscReal norm; 4850da9b6338SBarry Smith 4851da9b6338SBarry Smith PetscFunctionBegin; 4852da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 4853da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 4854da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 4855da9b6338SBarry Smith 4856da9b6338SBarry Smith /* currently only works for sequential */ 485722d28d08SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");CHKERRQ(ierr); 4858da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 4859da9b6338SBarry Smith for (i=0; i<N; i++) { 4860da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 486177431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 4862da9b6338SBarry Smith for (j=-10; j<11; j++) { 48638b49ba18SBarry Smith value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0); 4864da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 48653ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 4866da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 486777431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 4868da9b6338SBarry Smith value = -value; 4869da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 4870da9b6338SBarry Smith } 4871da9b6338SBarry Smith } 48726bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 48736bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 4874da9b6338SBarry Smith PetscFunctionReturn(0); 4875da9b6338SBarry Smith } 487671f87433Sdalcinl 487771f87433Sdalcinl /*@ 4878fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 487971f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 488071f87433Sdalcinl Newton method. 488171f87433Sdalcinl 48823f9fe445SBarry Smith Logically Collective on SNES 488371f87433Sdalcinl 488471f87433Sdalcinl Input Parameters: 488571f87433Sdalcinl + snes - SNES context 488671f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 488771f87433Sdalcinl 488864ba62caSBarry Smith Options Database: 488964ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 489064ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 489164ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 489264ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 489364ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 489464ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 489564ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 489664ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 489764ba62caSBarry Smith 489871f87433Sdalcinl Notes: 489971f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 490071f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 490171f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 490271f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 490371f87433Sdalcinl solver. 490471f87433Sdalcinl 490571f87433Sdalcinl Level: advanced 490671f87433Sdalcinl 490771f87433Sdalcinl Reference: 490871f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 490971f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 491071f87433Sdalcinl 491171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 491271f87433Sdalcinl 4913fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 491471f87433Sdalcinl @*/ 49157087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 491671f87433Sdalcinl { 491771f87433Sdalcinl PetscFunctionBegin; 49180700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4919acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 492071f87433Sdalcinl snes->ksp_ewconv = flag; 492171f87433Sdalcinl PetscFunctionReturn(0); 492271f87433Sdalcinl } 492371f87433Sdalcinl 492471f87433Sdalcinl /*@ 4925fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 492671f87433Sdalcinl for computing relative tolerance for linear solvers within an 492771f87433Sdalcinl inexact Newton method. 492871f87433Sdalcinl 492971f87433Sdalcinl Not Collective 493071f87433Sdalcinl 493171f87433Sdalcinl Input Parameter: 493271f87433Sdalcinl . snes - SNES context 493371f87433Sdalcinl 493471f87433Sdalcinl Output Parameter: 493571f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 493671f87433Sdalcinl 493771f87433Sdalcinl Notes: 493871f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 493971f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 494071f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 494171f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 494271f87433Sdalcinl solver. 494371f87433Sdalcinl 494471f87433Sdalcinl Level: advanced 494571f87433Sdalcinl 494671f87433Sdalcinl Reference: 494771f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 494871f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 494971f87433Sdalcinl 495071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 495171f87433Sdalcinl 4952fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 495371f87433Sdalcinl @*/ 49547087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 495571f87433Sdalcinl { 495671f87433Sdalcinl PetscFunctionBegin; 49570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 495871f87433Sdalcinl PetscValidPointer(flag,2); 495971f87433Sdalcinl *flag = snes->ksp_ewconv; 496071f87433Sdalcinl PetscFunctionReturn(0); 496171f87433Sdalcinl } 496271f87433Sdalcinl 496371f87433Sdalcinl /*@ 4964fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 496571f87433Sdalcinl convergence criteria for the linear solvers within an inexact 496671f87433Sdalcinl Newton method. 496771f87433Sdalcinl 49683f9fe445SBarry Smith Logically Collective on SNES 496971f87433Sdalcinl 497071f87433Sdalcinl Input Parameters: 497171f87433Sdalcinl + snes - SNES context 497271f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 497371f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 497471f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 497571f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 497671f87433Sdalcinl (0 <= gamma2 <= 1) 497771f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 497871f87433Sdalcinl . alpha2 - power for safeguard 497971f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 498071f87433Sdalcinl 498171f87433Sdalcinl Note: 498271f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 498371f87433Sdalcinl 498471f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 498571f87433Sdalcinl 498671f87433Sdalcinl Level: advanced 498771f87433Sdalcinl 498871f87433Sdalcinl Reference: 498971f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 499071f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 499171f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 499271f87433Sdalcinl 499371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 499471f87433Sdalcinl 4995fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 499671f87433Sdalcinl @*/ 4997f5af7f23SKarl Rupp PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 499871f87433Sdalcinl { 4999fa9f3622SBarry Smith SNESKSPEW *kctx; 50005fd66863SKarl Rupp 500171f87433Sdalcinl PetscFunctionBegin; 50020700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5003fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 5004e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 5005c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 5006c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 5007c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 5008c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 5009c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 5010c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 5011c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 501271f87433Sdalcinl 501371f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 501471f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 501571f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 501671f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 501771f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 501871f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 501971f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 502071f87433Sdalcinl 5021f23aa3ddSBarry 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); 502257622a8eSBarry 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); 502357622a8eSBarry 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); 502457622a8eSBarry 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); 502557622a8eSBarry 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); 502657622a8eSBarry 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); 502771f87433Sdalcinl PetscFunctionReturn(0); 502871f87433Sdalcinl } 502971f87433Sdalcinl 503071f87433Sdalcinl /*@ 5031fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 503271f87433Sdalcinl convergence criteria for the linear solvers within an inexact 503371f87433Sdalcinl Newton method. 503471f87433Sdalcinl 503571f87433Sdalcinl Not Collective 503671f87433Sdalcinl 503771f87433Sdalcinl Input Parameters: 503871f87433Sdalcinl snes - SNES context 503971f87433Sdalcinl 504071f87433Sdalcinl Output Parameters: 504171f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 504271f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 504371f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 5044bf388a1fSBarry Smith . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 504571f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 504671f87433Sdalcinl . alpha2 - power for safeguard 504771f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 504871f87433Sdalcinl 504971f87433Sdalcinl Level: advanced 505071f87433Sdalcinl 505171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 505271f87433Sdalcinl 5053fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 505471f87433Sdalcinl @*/ 5055bf388a1fSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 505671f87433Sdalcinl { 5057fa9f3622SBarry Smith SNESKSPEW *kctx; 50585fd66863SKarl Rupp 505971f87433Sdalcinl PetscFunctionBegin; 50600700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5061fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 5062e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 506371f87433Sdalcinl if (version) *version = kctx->version; 506471f87433Sdalcinl if (rtol_0) *rtol_0 = kctx->rtol_0; 506571f87433Sdalcinl if (rtol_max) *rtol_max = kctx->rtol_max; 506671f87433Sdalcinl if (gamma) *gamma = kctx->gamma; 506771f87433Sdalcinl if (alpha) *alpha = kctx->alpha; 506871f87433Sdalcinl if (alpha2) *alpha2 = kctx->alpha2; 506971f87433Sdalcinl if (threshold) *threshold = kctx->threshold; 507071f87433Sdalcinl PetscFunctionReturn(0); 507171f87433Sdalcinl } 507271f87433Sdalcinl 5073d5378b5fSDmitry Karpeev PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 507471f87433Sdalcinl { 507571f87433Sdalcinl PetscErrorCode ierr; 5076fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 507771f87433Sdalcinl PetscReal rtol = PETSC_DEFAULT,stol; 507871f87433Sdalcinl 507971f87433Sdalcinl PetscFunctionBegin; 5080d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 508130058271SDmitry Karpeev if (!snes->iter) { 508230058271SDmitry Karpeev rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 508330058271SDmitry Karpeev ierr = VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);CHKERRQ(ierr); 508430058271SDmitry Karpeev } 5085f5af7f23SKarl Rupp else { 508671f87433Sdalcinl if (kctx->version == 1) { 508771f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 508871f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 508985ec1a3cSBarry Smith stol = PetscPowReal(kctx->rtol_last,kctx->alpha2); 509071f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 509171f87433Sdalcinl } else if (kctx->version == 2) { 509285ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 509385ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha); 509471f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 509571f87433Sdalcinl } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 509685ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 509771f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 509885ec1a3cSBarry Smith stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha); 509971f87433Sdalcinl stol = PetscMax(rtol,stol); 510071f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 510171f87433Sdalcinl /* safeguard: avoid oversolving */ 510230058271SDmitry Karpeev stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm; 510371f87433Sdalcinl stol = PetscMax(rtol,stol); 510471f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 5105e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 510671f87433Sdalcinl } 510771f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 510871f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 510971f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 511057622a8eSBarry Smith ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);CHKERRQ(ierr); 511171f87433Sdalcinl PetscFunctionReturn(0); 511271f87433Sdalcinl } 511371f87433Sdalcinl 5114d5378b5fSDmitry Karpeev PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 511571f87433Sdalcinl { 511671f87433Sdalcinl PetscErrorCode ierr; 5117fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 511871f87433Sdalcinl PCSide pcside; 511971f87433Sdalcinl Vec lres; 512071f87433Sdalcinl 512171f87433Sdalcinl PetscFunctionBegin; 5122d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 512371f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 512471dbe336SPeter Brune kctx->norm_last = snes->norm; 512571f87433Sdalcinl if (kctx->version == 1) { 51264f00ce20SMatthew G. Knepley PC pc; 51274f00ce20SMatthew G. Knepley PetscBool isNone; 51284f00ce20SMatthew G. Knepley 51294f00ce20SMatthew G. Knepley ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); 51304f00ce20SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);CHKERRQ(ierr); 5131b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 51324f00ce20SMatthew G. Knepley if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 513371f87433Sdalcinl /* KSP residual is true linear residual */ 513471f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 513571f87433Sdalcinl } else { 513671f87433Sdalcinl /* KSP residual is preconditioned residual */ 513771f87433Sdalcinl /* compute true linear residual norm */ 513871f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 513971f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 514071f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 514171f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 51426bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 514371f87433Sdalcinl } 514471f87433Sdalcinl } 514571f87433Sdalcinl PetscFunctionReturn(0); 514671f87433Sdalcinl } 514771f87433Sdalcinl 5148d4211eb9SBarry Smith /*@ 5149d4211eb9SBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 5150d4211eb9SBarry Smith 5151d4211eb9SBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 5152d4211eb9SBarry Smith 5153d4211eb9SBarry Smith Input Parameter: 5154d4211eb9SBarry Smith . snes - the SNES context 5155d4211eb9SBarry Smith 5156d4211eb9SBarry Smith Output Parameter: 5157d4211eb9SBarry Smith . ksp - the KSP context 5158d4211eb9SBarry Smith 5159d4211eb9SBarry Smith Notes: 5160d4211eb9SBarry Smith The user can then directly manipulate the KSP context to set various 5161d4211eb9SBarry Smith options, etc. Likewise, the user can then extract and manipulate the 5162d4211eb9SBarry Smith PC contexts as well. 5163d4211eb9SBarry Smith 5164d4211eb9SBarry Smith Level: beginner 5165d4211eb9SBarry Smith 5166d4211eb9SBarry Smith .keywords: SNES, nonlinear, get, KSP, context 5167d4211eb9SBarry Smith 5168d4211eb9SBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 5169d4211eb9SBarry Smith @*/ 5170d4211eb9SBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 517171f87433Sdalcinl { 517271f87433Sdalcinl PetscErrorCode ierr; 517371f87433Sdalcinl 517471f87433Sdalcinl PetscFunctionBegin; 5175d4211eb9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5176d4211eb9SBarry Smith PetscValidPointer(ksp,2); 5177d4211eb9SBarry Smith 5178d4211eb9SBarry Smith if (!snes->ksp) { 5179a5c2985bSBarry Smith PetscBool monitor = PETSC_FALSE; 5180a5c2985bSBarry Smith 5181d4211eb9SBarry Smith ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr); 5182d4211eb9SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 51833bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);CHKERRQ(ierr); 5184d4211eb9SBarry Smith 5185d5378b5fSDmitry Karpeev ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);CHKERRQ(ierr); 5186d5378b5fSDmitry Karpeev ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);CHKERRQ(ierr); 5187a5c2985bSBarry Smith 5188c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes",&monitor,NULL);CHKERRQ(ierr); 5189a5c2985bSBarry Smith if (monitor) { 5190a5c2985bSBarry Smith ierr = KSPMonitorSet(snes->ksp,KSPMonitorSNES,snes,NULL);CHKERRQ(ierr); 5191a5c2985bSBarry Smith } 5192e5f7ee39SBarry Smith monitor = PETSC_FALSE; 5193c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes_lg",&monitor,NULL);CHKERRQ(ierr); 5194e5f7ee39SBarry Smith if (monitor) { 5195e5f7ee39SBarry Smith PetscObject *objs; 51968b0b5a47SLisandro Dalcin ierr = KSPMonitorSNESLGResidualNormCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,600,&objs);CHKERRQ(ierr); 5197e5f7ee39SBarry Smith objs[0] = (PetscObject) snes; 5198e5f7ee39SBarry Smith ierr = KSPMonitorSet(snes->ksp,(PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*))KSPMonitorSNESLGResidualNorm,objs,(PetscErrorCode (*)(void**))KSPMonitorSNESLGResidualNormDestroy);CHKERRQ(ierr); 5199e5f7ee39SBarry Smith } 5200d4211eb9SBarry Smith } 5201d4211eb9SBarry Smith *ksp = snes->ksp; 520271f87433Sdalcinl PetscFunctionReturn(0); 520371f87433Sdalcinl } 52046c699258SBarry Smith 5205d4211eb9SBarry Smith 5206af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 52076c699258SBarry Smith /*@ 52082a808120SBarry Smith SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners 52096c699258SBarry Smith 52103f9fe445SBarry Smith Logically Collective on SNES 52116c699258SBarry Smith 52126c699258SBarry Smith Input Parameters: 52132a808120SBarry Smith + snes - the nonlinear solver context 52142a808120SBarry Smith - dm - the dm, cannot be NULL 52156c699258SBarry Smith 5216e03a659cSJed Brown Notes: 5217e03a659cSJed Brown A DM can only be used for solving one problem at a time because information about the problem is stored on the DM, 5218e03a659cSJed Brown even when not using interfaces like DMSNESSetFunction(). Use DMClone() to get a distinct DM when solving different 5219e03a659cSJed Brown problems using the same function space. 5220e03a659cSJed Brown 52216c699258SBarry Smith Level: intermediate 52226c699258SBarry Smith 52234c2026ceSFande Kong .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 52246c699258SBarry Smith @*/ 52257087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 52266c699258SBarry Smith { 52276c699258SBarry Smith PetscErrorCode ierr; 5228345fed2cSBarry Smith KSP ksp; 5229942e3340SBarry Smith DMSNES sdm; 52306c699258SBarry Smith 52316c699258SBarry Smith PetscFunctionBegin; 52320700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 52332a808120SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,2); 52342a808120SBarry Smith ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 5235942e3340SBarry Smith if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 523651f4b3c7SToby Isaac if (snes->dm->dmsnes && !dm->dmsnes) { 5237942e3340SBarry Smith ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr); 5238942e3340SBarry Smith ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr); 5239f5af7f23SKarl Rupp if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 52406cab3a1bSJed Brown } 5241dc822a44SJed Brown ierr = DMCoarsenHookRemove(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 52426bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 52436cab3a1bSJed Brown } 52446c699258SBarry Smith snes->dm = dm; 5245116d1032SJed Brown snes->dmAuto = PETSC_FALSE; 5246f5af7f23SKarl Rupp 5247345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 5248345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 5249f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 5250efd4aadfSBarry Smith if (snes->npc) { 5251efd4aadfSBarry Smith ierr = SNESSetDM(snes->npc, snes->dm);CHKERRQ(ierr); 5252efd4aadfSBarry Smith ierr = SNESSetNPCSide(snes,snes->npcside);CHKERRQ(ierr); 52532c155ee1SBarry Smith } 52546c699258SBarry Smith PetscFunctionReturn(0); 52556c699258SBarry Smith } 52566c699258SBarry Smith 52576c699258SBarry Smith /*@ 52586c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 52596c699258SBarry Smith 52603f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 52616c699258SBarry Smith 52626c699258SBarry Smith Input Parameter: 52636c699258SBarry Smith . snes - the preconditioner context 52646c699258SBarry Smith 52656c699258SBarry Smith Output Parameter: 52666c699258SBarry Smith . dm - the dm 52676c699258SBarry Smith 52686c699258SBarry Smith Level: intermediate 52696c699258SBarry Smith 52704c2026ceSFande Kong .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 52716c699258SBarry Smith @*/ 52727087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 52736c699258SBarry Smith { 52746cab3a1bSJed Brown PetscErrorCode ierr; 52756cab3a1bSJed Brown 52766c699258SBarry Smith PetscFunctionBegin; 52770700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 52786cab3a1bSJed Brown if (!snes->dm) { 5279ce94432eSBarry Smith ierr = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr); 5280116d1032SJed Brown snes->dmAuto = PETSC_TRUE; 52816cab3a1bSJed Brown } 52826c699258SBarry Smith *dm = snes->dm; 52836c699258SBarry Smith PetscFunctionReturn(0); 52846c699258SBarry Smith } 52850807856dSBarry Smith 528631823bd8SMatthew G Knepley /*@ 5287be95d8f1SBarry Smith SNESSetNPC - Sets the nonlinear preconditioner to be used. 528831823bd8SMatthew G Knepley 528931823bd8SMatthew G Knepley Collective on SNES 529031823bd8SMatthew G Knepley 529131823bd8SMatthew G Knepley Input Parameters: 529231823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 529331823bd8SMatthew G Knepley - pc - the preconditioner object 529431823bd8SMatthew G Knepley 529531823bd8SMatthew G Knepley Notes: 5296be95d8f1SBarry Smith Use SNESGetNPC() to retrieve the preconditioner context (for example, 529731823bd8SMatthew G Knepley to configure it using the API). 529831823bd8SMatthew G Knepley 529931823bd8SMatthew G Knepley Level: developer 530031823bd8SMatthew G Knepley 530131823bd8SMatthew G Knepley .keywords: SNES, set, precondition 53023ad1a0b9SPatrick Farrell .seealso: SNESGetNPC(), SNESHasNPC() 530331823bd8SMatthew G Knepley @*/ 5304be95d8f1SBarry Smith PetscErrorCode SNESSetNPC(SNES snes, SNES pc) 530531823bd8SMatthew G Knepley { 530631823bd8SMatthew G Knepley PetscErrorCode ierr; 530731823bd8SMatthew G Knepley 530831823bd8SMatthew G Knepley PetscFunctionBegin; 530931823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 531031823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 531131823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 531231823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 5313efd4aadfSBarry Smith ierr = SNESDestroy(&snes->npc);CHKERRQ(ierr); 5314efd4aadfSBarry Smith snes->npc = pc; 5315efd4aadfSBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc);CHKERRQ(ierr); 531631823bd8SMatthew G Knepley PetscFunctionReturn(0); 531731823bd8SMatthew G Knepley } 531831823bd8SMatthew G Knepley 531931823bd8SMatthew G Knepley /*@ 5320be95d8f1SBarry Smith SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver. 532131823bd8SMatthew G Knepley 532231823bd8SMatthew G Knepley Not Collective 532331823bd8SMatthew G Knepley 532431823bd8SMatthew G Knepley Input Parameter: 532531823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 532631823bd8SMatthew G Knepley 532731823bd8SMatthew G Knepley Output Parameter: 532831823bd8SMatthew G Knepley . pc - preconditioner context 532931823bd8SMatthew G Knepley 533095452b02SPatrick Sanan Notes: 533195452b02SPatrick Sanan If a SNES was previously set with SNESSetNPC() then that SNES is returned. 5332be95d8f1SBarry Smith 533331823bd8SMatthew G Knepley Level: developer 533431823bd8SMatthew G Knepley 533531823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 53363ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESHasNPC() 533731823bd8SMatthew G Knepley @*/ 5338be95d8f1SBarry Smith PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) 533931823bd8SMatthew G Knepley { 534031823bd8SMatthew G Knepley PetscErrorCode ierr; 5341a64e098fSPeter Brune const char *optionsprefix; 534231823bd8SMatthew G Knepley 534331823bd8SMatthew G Knepley PetscFunctionBegin; 534431823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 534531823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 5346efd4aadfSBarry Smith if (!snes->npc) { 5347efd4aadfSBarry Smith ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc);CHKERRQ(ierr); 5348efd4aadfSBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1);CHKERRQ(ierr); 5349efd4aadfSBarry Smith ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr); 5350a64e098fSPeter Brune ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 5351efd4aadfSBarry Smith ierr = SNESSetOptionsPrefix(snes->npc,optionsprefix);CHKERRQ(ierr); 5352efd4aadfSBarry Smith ierr = SNESAppendOptionsPrefix(snes->npc,"npc_");CHKERRQ(ierr); 5353efd4aadfSBarry Smith ierr = SNESSetCountersReset(snes->npc,PETSC_FALSE);CHKERRQ(ierr); 535431823bd8SMatthew G Knepley } 5355efd4aadfSBarry Smith *pc = snes->npc; 535631823bd8SMatthew G Knepley PetscFunctionReturn(0); 535731823bd8SMatthew G Knepley } 535831823bd8SMatthew G Knepley 53593ad1a0b9SPatrick Farrell /*@ 53603ad1a0b9SPatrick Farrell SNESHasNPC - Returns whether a nonlinear preconditioner exists 53613ad1a0b9SPatrick Farrell 53623ad1a0b9SPatrick Farrell Not Collective 53633ad1a0b9SPatrick Farrell 53643ad1a0b9SPatrick Farrell Input Parameter: 53653ad1a0b9SPatrick Farrell . snes - iterative context obtained from SNESCreate() 53663ad1a0b9SPatrick Farrell 53673ad1a0b9SPatrick Farrell Output Parameter: 53683ad1a0b9SPatrick Farrell . has_npc - whether the SNES has an NPC or not 53693ad1a0b9SPatrick Farrell 53703ad1a0b9SPatrick Farrell Level: developer 53713ad1a0b9SPatrick Farrell 53723ad1a0b9SPatrick Farrell .keywords: SNES, has, preconditioner 53733ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESGetNPC() 53743ad1a0b9SPatrick Farrell @*/ 53753ad1a0b9SPatrick Farrell PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 53763ad1a0b9SPatrick Farrell { 53773ad1a0b9SPatrick Farrell PetscFunctionBegin; 53783ad1a0b9SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5379efd4aadfSBarry Smith *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE); 53803ad1a0b9SPatrick Farrell PetscFunctionReturn(0); 53813ad1a0b9SPatrick Farrell } 53823ad1a0b9SPatrick Farrell 5383c40d0f55SPeter Brune /*@ 5384be95d8f1SBarry Smith SNESSetNPCSide - Sets the preconditioning side. 5385c40d0f55SPeter Brune 5386c40d0f55SPeter Brune Logically Collective on SNES 5387c40d0f55SPeter Brune 5388c40d0f55SPeter Brune Input Parameter: 5389c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5390c40d0f55SPeter Brune 5391c40d0f55SPeter Brune Output Parameter: 5392c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5393c40d0f55SPeter Brune .vb 53942d547940SBarry Smith PC_LEFT - left preconditioning 53952d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5396c40d0f55SPeter Brune .ve 5397c40d0f55SPeter Brune 5398c40d0f55SPeter Brune Options Database Keys: 5399c40d0f55SPeter Brune . -snes_pc_side <right,left> 5400c40d0f55SPeter Brune 540195452b02SPatrick Sanan Notes: 540295452b02SPatrick Sanan SNESNRICHARDSON and SNESNCG only support left preconditioning. 54032d547940SBarry Smith 5404c40d0f55SPeter Brune Level: intermediate 5405c40d0f55SPeter Brune 5406c40d0f55SPeter Brune .keywords: SNES, set, right, left, side, preconditioner, flag 5407c40d0f55SPeter Brune 5408be95d8f1SBarry Smith .seealso: SNESGetNPCSide(), KSPSetPCSide() 5409c40d0f55SPeter Brune @*/ 5410be95d8f1SBarry Smith PetscErrorCode SNESSetNPCSide(SNES snes,PCSide side) 5411c40d0f55SPeter Brune { 5412c40d0f55SPeter Brune PetscFunctionBegin; 5413c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5414c40d0f55SPeter Brune PetscValidLogicalCollectiveEnum(snes,side,2); 5415efd4aadfSBarry Smith snes->npcside= side; 5416c40d0f55SPeter Brune PetscFunctionReturn(0); 5417c40d0f55SPeter Brune } 5418c40d0f55SPeter Brune 5419c40d0f55SPeter Brune /*@ 5420be95d8f1SBarry Smith SNESGetNPCSide - Gets the preconditioning side. 5421c40d0f55SPeter Brune 5422c40d0f55SPeter Brune Not Collective 5423c40d0f55SPeter Brune 5424c40d0f55SPeter Brune Input Parameter: 5425c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5426c40d0f55SPeter Brune 5427c40d0f55SPeter Brune Output Parameter: 5428c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5429c40d0f55SPeter Brune .vb 54302d547940SBarry Smith PC_LEFT - left preconditioning 54312d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5432c40d0f55SPeter Brune .ve 5433c40d0f55SPeter Brune 5434c40d0f55SPeter Brune Level: intermediate 5435c40d0f55SPeter Brune 5436c40d0f55SPeter Brune .keywords: SNES, get, right, left, side, preconditioner, flag 5437c40d0f55SPeter Brune 5438be95d8f1SBarry Smith .seealso: SNESSetNPCSide(), KSPGetPCSide() 5439c40d0f55SPeter Brune @*/ 5440be95d8f1SBarry Smith PetscErrorCode SNESGetNPCSide(SNES snes,PCSide *side) 5441c40d0f55SPeter Brune { 5442c40d0f55SPeter Brune PetscFunctionBegin; 5443c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5444c40d0f55SPeter Brune PetscValidPointer(side,2); 5445efd4aadfSBarry Smith *side = snes->npcside; 5446c40d0f55SPeter Brune PetscFunctionReturn(0); 5447c40d0f55SPeter Brune } 5448c40d0f55SPeter Brune 54499e764e56SPeter Brune /*@ 54507601faf0SJed Brown SNESSetLineSearch - Sets the linesearch on the SNES instance. 54519e764e56SPeter Brune 54529e764e56SPeter Brune Collective on SNES 54539e764e56SPeter Brune 54549e764e56SPeter Brune Input Parameters: 54559e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 54569e764e56SPeter Brune - linesearch - the linesearch object 54579e764e56SPeter Brune 54589e764e56SPeter Brune Notes: 54597601faf0SJed Brown Use SNESGetLineSearch() to retrieve the preconditioner context (for example, 54609e764e56SPeter Brune to configure it using the API). 54619e764e56SPeter Brune 54629e764e56SPeter Brune Level: developer 54639e764e56SPeter Brune 54649e764e56SPeter Brune .keywords: SNES, set, linesearch 54657601faf0SJed Brown .seealso: SNESGetLineSearch() 54669e764e56SPeter Brune @*/ 54677601faf0SJed Brown PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 54689e764e56SPeter Brune { 54699e764e56SPeter Brune PetscErrorCode ierr; 54709e764e56SPeter Brune 54719e764e56SPeter Brune PetscFunctionBegin; 54729e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5473f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 54749e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 54759e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 5476f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 5477f5af7f23SKarl Rupp 54789e764e56SPeter Brune snes->linesearch = linesearch; 5479f5af7f23SKarl Rupp 54803bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 54819e764e56SPeter Brune PetscFunctionReturn(0); 54829e764e56SPeter Brune } 54839e764e56SPeter Brune 5484a34ceb2aSJed Brown /*@ 54857601faf0SJed Brown SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 54868141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 54879e764e56SPeter Brune 54889e764e56SPeter Brune Not Collective 54899e764e56SPeter Brune 54909e764e56SPeter Brune Input Parameter: 54919e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 54929e764e56SPeter Brune 54939e764e56SPeter Brune Output Parameter: 54949e764e56SPeter Brune . linesearch - linesearch context 54959e764e56SPeter Brune 5496162e0bf5SPeter Brune Level: beginner 54979e764e56SPeter Brune 54989e764e56SPeter Brune .keywords: SNES, get, linesearch 5499162e0bf5SPeter Brune .seealso: SNESSetLineSearch(), SNESLineSearchCreate() 55009e764e56SPeter Brune @*/ 55017601faf0SJed Brown PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 55029e764e56SPeter Brune { 55039e764e56SPeter Brune PetscErrorCode ierr; 55049e764e56SPeter Brune const char *optionsprefix; 55059e764e56SPeter Brune 55069e764e56SPeter Brune PetscFunctionBegin; 55079e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 55089e764e56SPeter Brune PetscValidPointer(linesearch, 2); 55099e764e56SPeter Brune if (!snes->linesearch) { 55109e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 551182f516ccSBarry Smith ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr); 5512f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 5513b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 55149e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 55153bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 55169e764e56SPeter Brune } 55179e764e56SPeter Brune *linesearch = snes->linesearch; 55189e764e56SPeter Brune PetscFunctionReturn(0); 55199e764e56SPeter Brune } 55209e764e56SPeter Brune 552169b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 5522c6db04a5SJed Brown #include <mex.h> 552369b4f73cSBarry Smith 55248f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 55258f6e6473SBarry Smith 55260807856dSBarry Smith /* 5527bf388a1fSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with SNESSetFunctionMatlab(). 55280807856dSBarry Smith 55290807856dSBarry Smith Collective on SNES 55300807856dSBarry Smith 55310807856dSBarry Smith Input Parameters: 55320807856dSBarry Smith + snes - the SNES context 55330807856dSBarry Smith - x - input vector 55340807856dSBarry Smith 55350807856dSBarry Smith Output Parameter: 55360807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 55370807856dSBarry Smith 55380807856dSBarry Smith Notes: 55390807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 55400807856dSBarry Smith implementations, so most users would not generally call this routine 55410807856dSBarry Smith themselves. 55420807856dSBarry Smith 55430807856dSBarry Smith Level: developer 55440807856dSBarry Smith 55450807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 55460807856dSBarry Smith 55470807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 554861b2408cSBarry Smith */ 55497087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 55500807856dSBarry Smith { 5551e650e774SBarry Smith PetscErrorCode ierr; 55528f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 55538f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 55548f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 555591621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 5556e650e774SBarry Smith 55570807856dSBarry Smith PetscFunctionBegin; 55580807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 55590807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 55600807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 55610807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 55620807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 55630807856dSBarry Smith 55640807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 5565e650e774SBarry Smith 556691621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 5567e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 5568e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 556991621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 557091621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 557191621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 55728f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 55738f6e6473SBarry Smith prhs[4] = sctx->ctx; 5574b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 5575e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5576e650e774SBarry Smith mxDestroyArray(prhs[0]); 5577e650e774SBarry Smith mxDestroyArray(prhs[1]); 5578e650e774SBarry Smith mxDestroyArray(prhs[2]); 55798f6e6473SBarry Smith mxDestroyArray(prhs[3]); 5580e650e774SBarry Smith mxDestroyArray(plhs[0]); 55810807856dSBarry Smith PetscFunctionReturn(0); 55820807856dSBarry Smith } 55830807856dSBarry Smith 558461b2408cSBarry Smith /* 55850807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 55860807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 5587e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 55880807856dSBarry Smith 55890807856dSBarry Smith Logically Collective on SNES 55900807856dSBarry Smith 55910807856dSBarry Smith Input Parameters: 55920807856dSBarry Smith + snes - the SNES context 55930807856dSBarry Smith . r - vector to store function value 5594f8b49ee9SBarry Smith - f - function evaluation routine 55950807856dSBarry Smith 55960807856dSBarry Smith Notes: 55970807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 55980807856dSBarry Smith $ f'(x) x = -f(x), 55990807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 56000807856dSBarry Smith 56010807856dSBarry Smith Level: beginner 56020807856dSBarry Smith 5603c5b75c40SBarry Smith Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5604c5b75c40SBarry Smith 56050807856dSBarry Smith .keywords: SNES, nonlinear, set, function 56060807856dSBarry Smith 56070807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 560861b2408cSBarry Smith */ 5609f8b49ee9SBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *f,mxArray *ctx) 56100807856dSBarry Smith { 56110807856dSBarry Smith PetscErrorCode ierr; 56128f6e6473SBarry Smith SNESMatlabContext *sctx; 56130807856dSBarry Smith 56140807856dSBarry Smith PetscFunctionBegin; 56158f6e6473SBarry Smith /* currently sctx is memory bleed */ 5616854ce69bSBarry Smith ierr = PetscNew(&sctx);CHKERRQ(ierr); 5617f8b49ee9SBarry Smith ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr); 56188f6e6473SBarry Smith /* 56198f6e6473SBarry Smith This should work, but it doesn't 56208f6e6473SBarry Smith sctx->ctx = ctx; 56218f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 56228f6e6473SBarry Smith */ 56238f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 56248f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 56250807856dSBarry Smith PetscFunctionReturn(0); 56260807856dSBarry Smith } 562769b4f73cSBarry Smith 562861b2408cSBarry Smith /* 5629bf388a1fSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with SNESSetJacobianMatlab(). 563061b2408cSBarry Smith 563161b2408cSBarry Smith Collective on SNES 563261b2408cSBarry Smith 563361b2408cSBarry Smith Input Parameters: 563461b2408cSBarry Smith + snes - the SNES context 563561b2408cSBarry Smith . x - input vector 563661b2408cSBarry Smith . A, B - the matrices 563761b2408cSBarry Smith - ctx - user context 563861b2408cSBarry Smith 563961b2408cSBarry Smith Level: developer 564061b2408cSBarry Smith 564161b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 564261b2408cSBarry Smith 564361b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 564461b2408cSBarry Smith @*/ 5645f3229a78SSatish Balay PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat A,Mat B,void *ctx) 564661b2408cSBarry Smith { 564761b2408cSBarry Smith PetscErrorCode ierr; 564861b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 564961b2408cSBarry Smith int nlhs = 2,nrhs = 6; 565061b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 565161b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 565261b2408cSBarry Smith 565361b2408cSBarry Smith PetscFunctionBegin; 565461b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 565561b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 565661b2408cSBarry Smith 565761b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 565861b2408cSBarry Smith 565961b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 566061b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 566161b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 566261b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 566361b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 566461b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 566561b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 566661b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 566761b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 566861b2408cSBarry Smith prhs[5] = sctx->ctx; 5669b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 567061b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 567161b2408cSBarry Smith mxDestroyArray(prhs[0]); 567261b2408cSBarry Smith mxDestroyArray(prhs[1]); 567361b2408cSBarry Smith mxDestroyArray(prhs[2]); 567461b2408cSBarry Smith mxDestroyArray(prhs[3]); 567561b2408cSBarry Smith mxDestroyArray(prhs[4]); 567661b2408cSBarry Smith mxDestroyArray(plhs[0]); 567761b2408cSBarry Smith mxDestroyArray(plhs[1]); 567861b2408cSBarry Smith PetscFunctionReturn(0); 567961b2408cSBarry Smith } 568061b2408cSBarry Smith 568161b2408cSBarry Smith /* 568261b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 568361b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 5684e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 568561b2408cSBarry Smith 568661b2408cSBarry Smith Logically Collective on SNES 568761b2408cSBarry Smith 568861b2408cSBarry Smith Input Parameters: 568961b2408cSBarry Smith + snes - the SNES context 569061b2408cSBarry Smith . A,B - Jacobian matrices 5691f8b49ee9SBarry Smith . J - function evaluation routine 569261b2408cSBarry Smith - ctx - user context 569361b2408cSBarry Smith 569461b2408cSBarry Smith Level: developer 569561b2408cSBarry Smith 5696c5b75c40SBarry Smith Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5697c5b75c40SBarry Smith 569861b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 569961b2408cSBarry Smith 5700f8b49ee9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction(), J 570161b2408cSBarry Smith */ 5702f8b49ee9SBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *J,mxArray *ctx) 570361b2408cSBarry Smith { 570461b2408cSBarry Smith PetscErrorCode ierr; 570561b2408cSBarry Smith SNESMatlabContext *sctx; 570661b2408cSBarry Smith 570761b2408cSBarry Smith PetscFunctionBegin; 570861b2408cSBarry Smith /* currently sctx is memory bleed */ 5709854ce69bSBarry Smith ierr = PetscNew(&sctx);CHKERRQ(ierr); 5710f8b49ee9SBarry Smith ierr = PetscStrallocpy(J,&sctx->funcname);CHKERRQ(ierr); 571161b2408cSBarry Smith /* 571261b2408cSBarry Smith This should work, but it doesn't 571361b2408cSBarry Smith sctx->ctx = ctx; 571461b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 571561b2408cSBarry Smith */ 571661b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 571761b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 571861b2408cSBarry Smith PetscFunctionReturn(0); 571961b2408cSBarry Smith } 572069b4f73cSBarry Smith 5721f9eb7ae2SShri Abhyankar /* 5722f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 5723f9eb7ae2SShri Abhyankar 5724f9eb7ae2SShri Abhyankar Collective on SNES 5725f9eb7ae2SShri Abhyankar 5726f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 5727f9eb7ae2SShri Abhyankar @*/ 57287087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 5729f9eb7ae2SShri Abhyankar { 5730f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 573148f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 5732f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 5733f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 5734f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 5735f9eb7ae2SShri Abhyankar Vec x = snes->vec_sol; 5736f9eb7ae2SShri Abhyankar 5737f9eb7ae2SShri Abhyankar PetscFunctionBegin; 5738f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5739f9eb7ae2SShri Abhyankar 5740f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 5741f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 5742f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 5743f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 5744f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 5745f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 5746f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 5747f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 5748f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 5749f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5750f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 5751f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 5752f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 5753f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 5754f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 5755f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 5756f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 5757f9eb7ae2SShri Abhyankar } 5758f9eb7ae2SShri Abhyankar 5759f9eb7ae2SShri Abhyankar /* 5760e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 5761f9eb7ae2SShri Abhyankar 5762f9eb7ae2SShri Abhyankar Level: developer 5763f9eb7ae2SShri Abhyankar 5764c5b75c40SBarry Smith Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5765c5b75c40SBarry Smith 5766f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 5767f9eb7ae2SShri Abhyankar 5768f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 5769f9eb7ae2SShri Abhyankar */ 57706e4dcb14SBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *f,mxArray *ctx) 5771f9eb7ae2SShri Abhyankar { 5772f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 5773f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 5774f9eb7ae2SShri Abhyankar 5775f9eb7ae2SShri Abhyankar PetscFunctionBegin; 5776f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 5777854ce69bSBarry Smith ierr = PetscNew(&sctx);CHKERRQ(ierr); 57786e4dcb14SBarry Smith ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr); 5779f9eb7ae2SShri Abhyankar /* 5780f9eb7ae2SShri Abhyankar This should work, but it doesn't 5781f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 5782f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 5783f9eb7ae2SShri Abhyankar */ 5784f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 57850298fd71SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,NULL);CHKERRQ(ierr); 5786f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 5787f9eb7ae2SShri Abhyankar } 5788f9eb7ae2SShri Abhyankar 578969b4f73cSBarry Smith #endif 5790