19b94acceSBarry Smith 2af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/ 307475bc1SBarry Smith #include <petscdmshell.h> 4d96771aaSLisandro Dalcin #include <petscdraw.h> 5a01aa210SMatthew G. Knepley #include <petscds.h> 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 227*8404b7f3SBarry 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; 286*8404b7f3SBarry Smith DM dm; 287*8404b7f3SBarry Smith PetscErrorCode (*cJ)(SNES,Vec,Mat,Mat,void*); 288*8404b7f3SBarry 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 } 328*8404b7f3SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 329*8404b7f3SBarry Smith ierr = DMSNESGetJacobian(dm,&cJ,&ctx);CHKERRQ(ierr); 330*8404b7f3SBarry Smith if (cJ == SNESComputeJacobianDefault) { 331*8404b7f3SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is built using finite differences one column at a time\n");CHKERRQ(ierr); 332*8404b7f3SBarry Smith } else if (cJ == SNESComputeJacobianDefaultColor) { 333*8404b7f3SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is built using finite differences with coloring\n");CHKERRQ(ierr); 334*8404b7f3SBarry 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); 36272a02f06SBarry Smith ierr = PetscStrcpy(str,"SNES: ");CHKERRQ(ierr); 36372a02f06SBarry Smith ierr = PetscStrcat(str,((PetscObject)snes)->type_name);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) { 39272a02f06SBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 3937601faf0SJed Brown ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr); 39472a02f06SBarry Smith ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr); 39572a02f06SBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 39619bcc07fSBarry Smith } 397efd4aadfSBarry Smith if (snes->npc && snes->usesnpc) { 3984a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 399efd4aadfSBarry Smith ierr = SNESView(snes->npc, viewer);CHKERRQ(ierr); 4004a0c5b0cSMatthew G Knepley 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); 408b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 40994b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 410b0a32e0cSBarry Smith 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 4487087cfbeSBarry Smith extern 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; 562caa4e7f2SJed Brown Mat Asave = A,Bsave = B; 5630298fd71SBarry Smith Vec X,Xnamed = NULL; 564dfe15315SJed Brown DM dmsave; 5654e269d77SPeter Brune void *ctxsave; 566d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 567caa4e7f2SJed Brown 568caa4e7f2SJed Brown PetscFunctionBegin; 569dfe15315SJed Brown dmsave = snes->dm; 570dfe15315SJed Brown ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr); 571dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 572dfe15315SJed Brown else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ 573dfe15315SJed Brown ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 574dfe15315SJed Brown X = Xnamed; 5750298fd71SBarry Smith ierr = SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave);CHKERRQ(ierr); 5764e269d77SPeter Brune /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */ 5778d359177SBarry Smith if (jac == SNESComputeJacobianDefaultColor) { 5788d359177SBarry Smith ierr = SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr); 579dfe15315SJed Brown } 5804e269d77SPeter Brune } 5814e269d77SPeter Brune /* put the previous context back */ 5824e269d77SPeter Brune 583d1e9a80fSBarry Smith ierr = SNESComputeJacobian(snes,X,A,B);CHKERRQ(ierr); 5848d359177SBarry Smith if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) { 5850298fd71SBarry Smith ierr = SNESSetJacobian(snes,NULL,NULL,jac,ctxsave);CHKERRQ(ierr); 5864e269d77SPeter Brune } 5874e269d77SPeter Brune 588ce94432eSBarry Smith if (A != Asave || B != Bsave) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"No support for changing matrices at this time"); 589dfe15315SJed Brown if (Xnamed) { 590dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 591dfe15315SJed Brown } 592dfe15315SJed Brown snes->dm = dmsave; 593caa4e7f2SJed Brown PetscFunctionReturn(0); 594caa4e7f2SJed Brown } 595caa4e7f2SJed Brown 5966cab3a1bSJed Brown /*@ 5976cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 5986cab3a1bSJed Brown 5996cab3a1bSJed Brown Collective 6006cab3a1bSJed Brown 6016cab3a1bSJed Brown Input Arguments: 6026cab3a1bSJed Brown . snes - snes to configure 6036cab3a1bSJed Brown 6046cab3a1bSJed Brown Level: developer 6056cab3a1bSJed Brown 6066cab3a1bSJed Brown .seealso: SNESSetUp() 6076cab3a1bSJed Brown @*/ 6086cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 6096cab3a1bSJed Brown { 6106cab3a1bSJed Brown PetscErrorCode ierr; 6116cab3a1bSJed Brown DM dm; 612942e3340SBarry Smith DMSNES sdm; 6136cab3a1bSJed Brown 6146cab3a1bSJed Brown PetscFunctionBegin; 6156cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 616942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 617ce94432eSBarry Smith if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"DMSNES not properly configured"); 618f5af7f23SKarl Rupp else if (!snes->jacobian && snes->mf) { 6196cab3a1bSJed Brown Mat J; 6206cab3a1bSJed Brown void *functx; 6216cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 6226cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 6236cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 6240298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 6253232da50SPeter Brune ierr = SNESSetJacobian(snes,J,J,0,0);CHKERRQ(ierr); 6266cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 627caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 6286cab3a1bSJed Brown Mat J,B; 6296cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 6306cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 6316cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 632b412c318SBarry Smith ierr = DMCreateMatrix(snes->dm,&B);CHKERRQ(ierr); 63306f20277SJed Brown /* sdm->computejacobian was already set to reach here */ 6340298fd71SBarry Smith ierr = SNESSetJacobian(snes,J,B,NULL,NULL);CHKERRQ(ierr); 6356cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 6366cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 637caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 6381ba9b98eSMatthew G. Knepley PetscDS prob; 6396cab3a1bSJed Brown Mat J, B; 6401ba9b98eSMatthew G. Knepley PetscBool hasPrec = PETSC_FALSE; 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); 6480298fd71SBarry Smith ierr = SNESSetJacobian(snes, J ? J : B, B, NULL, NULL);CHKERRQ(ierr); 6491ba9b98eSMatthew G. Knepley ierr = MatDestroy(&J);CHKERRQ(ierr); 6506cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 6516cab3a1bSJed Brown } 652caa4e7f2SJed Brown { 653caa4e7f2SJed Brown KSP ksp; 654caa4e7f2SJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 655caa4e7f2SJed Brown ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr); 65616ebb321SJed Brown ierr = DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 657caa4e7f2SJed Brown } 6586cab3a1bSJed Brown PetscFunctionReturn(0); 6596cab3a1bSJed Brown } 6606cab3a1bSJed Brown 661fde5950dSBarry Smith /*@C 662fde5950dSBarry Smith SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 663fde5950dSBarry Smith 664fde5950dSBarry Smith Collective on SNES 665fde5950dSBarry Smith 666fde5950dSBarry Smith Input Parameters: 667fde5950dSBarry Smith + snes - SNES object you wish to monitor 668fde5950dSBarry Smith . name - the monitor type one is seeking 669fde5950dSBarry Smith . help - message indicating what monitoring is done 670fde5950dSBarry Smith . manual - manual page for the monitor 671fde5950dSBarry Smith . monitor - the monitor function 672fde5950dSBarry 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 673fde5950dSBarry Smith 674fde5950dSBarry Smith Level: developer 675fde5950dSBarry Smith 676fde5950dSBarry Smith .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 677fde5950dSBarry Smith PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 678fde5950dSBarry Smith PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 679fde5950dSBarry Smith PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 680fde5950dSBarry Smith PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 681fde5950dSBarry Smith PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 682fde5950dSBarry Smith PetscOptionsFList(), PetscOptionsEList() 683fde5950dSBarry Smith @*/ 684d43b4f6eSBarry Smith PetscErrorCode SNESMonitorSetFromOptions(SNES snes,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNES,PetscViewerAndFormat*)) 685fde5950dSBarry Smith { 686fde5950dSBarry Smith PetscErrorCode ierr; 687fde5950dSBarry Smith PetscViewer viewer; 688fde5950dSBarry Smith PetscViewerFormat format; 689fde5950dSBarry Smith PetscBool flg; 690fde5950dSBarry Smith 691fde5950dSBarry Smith PetscFunctionBegin; 692fde5950dSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr); 693fde5950dSBarry Smith if (flg) { 694d43b4f6eSBarry Smith PetscViewerAndFormat *vf; 695d43b4f6eSBarry Smith ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr); 696d43b4f6eSBarry Smith ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr); 697fde5950dSBarry Smith if (monitorsetup) { 698d43b4f6eSBarry Smith ierr = (*monitorsetup)(snes,vf);CHKERRQ(ierr); 699fde5950dSBarry Smith } 700d43b4f6eSBarry Smith ierr = SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr); 701fde5950dSBarry Smith } 702fde5950dSBarry Smith PetscFunctionReturn(0); 703fde5950dSBarry Smith } 704fde5950dSBarry Smith 7059b94acceSBarry Smith /*@ 70694b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 7079b94acceSBarry Smith 708c7afd0dbSLois Curfman McInnes Collective on SNES 709c7afd0dbSLois Curfman McInnes 7109b94acceSBarry Smith Input Parameter: 7119b94acceSBarry Smith . snes - the SNES context 7129b94acceSBarry Smith 71336851e7fSLois Curfman McInnes Options Database Keys: 714722329fbSBarry Smith + -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list 71582738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 71682738288SBarry Smith of the change in the solution between steps 71770441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 718b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 719e4d06f11SPatrick Farrell . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 720be5caee7SBarry Smith . -snes_force_iteration <force> - force SNESSolve() to take at least one iteration 721b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 722b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 7234839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 724ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 725a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 726e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 727b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 7282492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 72982738288SBarry Smith solver; hence iterations will continue until max_it 7301fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 73182738288SBarry Smith of convergence test 732fde5950dSBarry Smith . -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout 733fde5950dSBarry Smith . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 734fde5950dSBarry Smith . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 735fde5950dSBarry Smith . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 7364619e776SBarry Smith . -snes_monitor_lg_residualnorm - plots residual norm at each iteration 737459f5d12SBarry Smith . -snes_monitor_lg_range - plots residual norm at each iteration 738e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 739e2e60de9SPeter Brune . -snes_fd_color - use finite differences with coloring to compute Jacobian 7405968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 741fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 74282738288SBarry Smith 74382738288SBarry Smith Options Database for Eisenstat-Walker method: 744fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 7454b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 74636851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 74736851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 74836851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 74936851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 75036851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 75136851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 75282738288SBarry Smith 75311ca99fdSLois Curfman McInnes Notes: 75411ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 755a7f22e61SSatish Balay Users-Manual: ch_snes 75683e2fdc7SBarry Smith 75736851e7fSLois Curfman McInnes Level: beginner 75836851e7fSLois Curfman McInnes 7599b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 7609b94acceSBarry Smith 76169ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 7629b94acceSBarry Smith @*/ 7637087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 7649b94acceSBarry Smith { 7658afaa268SBarry Smith PetscBool flg,pcset,persist,set; 766d8f46077SPeter Brune PetscInt i,indx,lag,grids; 76704d7464bSBarry Smith const char *deft = SNESNEWTONLS; 76885385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 76985385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 770e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 77185385478SLisandro Dalcin PetscErrorCode ierr; 772c40d0f55SPeter Brune PCSide pcside; 773a64e098fSPeter Brune const char *optionsprefix; 7749b94acceSBarry Smith 7753a40ed3dSBarry Smith PetscFunctionBegin; 7760700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7770f51fdf8SToby Isaac ierr = SNESRegisterAll();CHKERRQ(ierr); 7783194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 779639ff905SBarry Smith if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name; 780a264d7a6SBarry Smith ierr = PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 781d64ed03dSBarry Smith if (flg) { 782186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 7837adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 784186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 785d64ed03dSBarry Smith } 78694ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL);CHKERRQ(ierr); 78794ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL);CHKERRQ(ierr); 788186905e3SBarry Smith 78994ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL);CHKERRQ(ierr); 790e4d06f11SPatrick Farrell ierr = PetscOptionsReal("-snes_divergence_tolerance","Stop if residual norm increases by this factor","SNESSetDivergenceTolerance",snes->divtol,&snes->divtol,NULL);CHKERRQ(ierr); 7910298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL);CHKERRQ(ierr); 7920298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL);CHKERRQ(ierr); 7930298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL);CHKERRQ(ierr); 7940298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL);CHKERRQ(ierr); 7950298fd71SBarry Smith ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL);CHKERRQ(ierr); 796be5caee7SBarry Smith ierr = PetscOptionsBool("-snes_force_iteration","Force SNESSolve() to take at least one iteration","SNESForceIteration",snes->forceiteration,&snes->forceiteration,NULL);CHKERRQ(ierr); 79785385478SLisandro Dalcin 798a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 799a8054027SBarry Smith if (flg) { 800a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 801a8054027SBarry Smith } 80237ec4e1aSPeter Brune ierr = PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr); 80337ec4e1aSPeter Brune if (flg) { 80437ec4e1aSPeter Brune ierr = SNESSetLagPreconditionerPersists(snes,persist);CHKERRQ(ierr); 80537ec4e1aSPeter Brune } 806e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 807e35cf81dSBarry Smith if (flg) { 808e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 809e35cf81dSBarry Smith } 81037ec4e1aSPeter Brune ierr = PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr); 81137ec4e1aSPeter Brune if (flg) { 81237ec4e1aSPeter Brune ierr = SNESSetLagJacobianPersists(snes,persist);CHKERRQ(ierr); 81337ec4e1aSPeter Brune } 81437ec4e1aSPeter Brune 815efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 816efd51863SBarry Smith if (flg) { 817efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 818efd51863SBarry Smith } 819a8054027SBarry Smith 82085385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 82185385478SLisandro Dalcin if (flg) { 82285385478SLisandro Dalcin switch (indx) { 8238d359177SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL);CHKERRQ(ierr); break; 824e2a6519dSDmitry Karpeev case 1: ierr = SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL);CHKERRQ(ierr); break; 82585385478SLisandro Dalcin } 82685385478SLisandro Dalcin } 82785385478SLisandro Dalcin 828365a6726SPeter Brune ierr = PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg);CHKERRQ(ierr); 829365a6726SPeter Brune if (flg) { ierr = SNESSetNormSchedule(snes,(SNESNormSchedule)indx);CHKERRQ(ierr); } 830fdacfa88SPeter Brune 83147073ea2SPeter Brune ierr = PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg);CHKERRQ(ierr); 83247073ea2SPeter Brune if (flg) { ierr = SNESSetFunctionType(snes,(SNESFunctionType)indx);CHKERRQ(ierr); } 833186905e3SBarry Smith 83485385478SLisandro Dalcin kctx = (SNESKSPEW*)snes->kspconvctx; 83585385478SLisandro Dalcin 8360298fd71SBarry Smith ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL);CHKERRQ(ierr); 837186905e3SBarry Smith 83894ae4db5SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL);CHKERRQ(ierr); 83994ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL);CHKERRQ(ierr); 84094ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL);CHKERRQ(ierr); 84194ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL);CHKERRQ(ierr); 84294ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL);CHKERRQ(ierr); 84394ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL);CHKERRQ(ierr); 84494ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL);CHKERRQ(ierr); 845186905e3SBarry Smith 84690d69ab7SBarry Smith flg = PETSC_FALSE; 8478afaa268SBarry Smith ierr = PetscOptionsBool("-snes_check_jacobian","Check each Jacobian with a differenced one","SNESUpdateCheckJacobian",flg,&flg,&set);CHKERRQ(ierr); 8488afaa268SBarry Smith if (set && flg) { 8495341784dSBarry Smith ierr = SNESSetUpdate(snes,SNESUpdateCheckJacobian);CHKERRQ(ierr); 8505341784dSBarry Smith } 8515341784dSBarry Smith 8525341784dSBarry Smith flg = PETSC_FALSE; 8538afaa268SBarry Smith ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set);CHKERRQ(ierr); 8548afaa268SBarry Smith if (set && flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 855eabae89aSBarry Smith 856fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,NULL);CHKERRQ(ierr); 857fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_short","Monitor norm of function with fewer digits","SNESMonitorDefaultShort",SNESMonitorDefaultShort,NULL);CHKERRQ(ierr); 858fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_range","Monitor range of elements of function","SNESMonitorRange",SNESMonitorRange,NULL);CHKERRQ(ierr); 859eabae89aSBarry Smith 860fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_ratio","Monitor ratios of the norm of function for consecutive steps","SNESMonitorRatio",SNESMonitorRatio,SNESMonitorRatioSetUp);CHKERRQ(ierr); 861fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorDefaultField",SNESMonitorDefaultField,NULL);CHKERRQ(ierr); 862fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution","View solution at each iteration","SNESMonitorSolution",SNESMonitorSolution,NULL);CHKERRQ(ierr); 863fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution_update","View correction at each iteration","SNESMonitorSolutionUpdate",SNESMonitorSolutionUpdate,NULL);CHKERRQ(ierr); 864fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_residual","View residual at each iteration","SNESMonitorResidual",SNESMonitorResidual,NULL);CHKERRQ(ierr); 865fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",SNESMonitorJacUpdateSpectrum,NULL);CHKERRQ(ierr); 866fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet",SNESMonitorFields,NULL);CHKERRQ(ierr); 8672db13446SMatthew G. Knepley 8685180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 8695180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 8705180491cSLisandro Dalcin 871fde5950dSBarry Smith 87290d69ab7SBarry Smith flg = PETSC_FALSE; 8730298fd71SBarry Smith ierr = PetscOptionsBool("-snes_monitor_lg_residualnorm","Plot function norm at each iteration","SNESMonitorLGResidualNorm",flg,&flg,NULL);CHKERRQ(ierr); 874459f5d12SBarry Smith if (flg) { 875d96771aaSLisandro Dalcin PetscDrawLG ctx; 876459f5d12SBarry Smith 8776ba87a44SLisandro Dalcin ierr = SNESMonitorLGCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr); 878d96771aaSLisandro Dalcin ierr = SNESMonitorSet(snes,SNESMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);CHKERRQ(ierr); 879459f5d12SBarry Smith } 88090d69ab7SBarry Smith flg = PETSC_FALSE; 8810298fd71SBarry Smith ierr = PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL);CHKERRQ(ierr); 882459f5d12SBarry Smith if (flg) { 883459f5d12SBarry Smith PetscViewer ctx; 884e24b481bSBarry Smith 8856ba87a44SLisandro Dalcin ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr); 886459f5d12SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 887459f5d12SBarry Smith } 8882e7541e6SPeter Brune 8892e7541e6SPeter Brune 890cc0c4584SMatthew G. Knepley 89190d69ab7SBarry Smith flg = PETSC_FALSE; 8928d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL);CHKERRQ(ierr); 8934b27c08aSLois Curfman McInnes if (flg) { 8946cab3a1bSJed Brown void *functx; 895b1f624c7SBarry Smith DM dm; 896b1f624c7SBarry Smith DMSNES sdm; 897b1f624c7SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 898b1f624c7SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 899b1f624c7SBarry Smith sdm->jacobianctx = NULL; 9000298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 9018d359177SBarry Smith ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx);CHKERRQ(ierr); 902ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 9039b94acceSBarry Smith } 904639f9d9dSBarry Smith 90544848bc4SPeter Brune flg = PETSC_FALSE; 9068d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL);CHKERRQ(ierr); 90797584545SPeter Brune if (flg) { 9088d359177SBarry Smith ierr = SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL);CHKERRQ(ierr); 90997584545SPeter Brune } 91097584545SPeter Brune 91197584545SPeter Brune flg = PETSC_FALSE; 9128d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL);CHKERRQ(ierr); 91344848bc4SPeter Brune if (flg) { 914c52e227fSPeter Brune DM dm; 915c52e227fSPeter Brune DMSNES sdm; 916c52e227fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 917aace71b7SPeter Brune ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 918aace71b7SPeter Brune sdm->jacobianctx = NULL; 9198d359177SBarry Smith ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr); 92044848bc4SPeter Brune ierr = PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr); 92144848bc4SPeter Brune } 92244848bc4SPeter Brune 923aa3661deSLisandro Dalcin flg = PETSC_FALSE; 924f871313dSBarry 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); 925d8f46077SPeter Brune if (flg && snes->mf_operator) { 926a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 927d8f46077SPeter Brune snes->mf = PETSC_TRUE; 928a8248277SBarry Smith } 929aa3661deSLisandro Dalcin flg = PETSC_FALSE; 930f871313dSBarry Smith ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf,&flg);CHKERRQ(ierr); 931d8f46077SPeter Brune if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 932d8f46077SPeter Brune ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,0);CHKERRQ(ierr); 933d28543b3SPeter Brune 934c40d0f55SPeter Brune flg = PETSC_FALSE; 935be95d8f1SBarry Smith ierr = SNESGetNPCSide(snes,&pcside);CHKERRQ(ierr); 936be95d8f1SBarry Smith ierr = PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr); 937be95d8f1SBarry Smith if (flg) {ierr = SNESSetNPCSide(snes,pcside);CHKERRQ(ierr);} 938c40d0f55SPeter Brune 939e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 9408a70d858SHong Zhang /* 9418a70d858SHong Zhang Publish convergence information using SAWs 9428a70d858SHong Zhang */ 9438a70d858SHong Zhang flg = PETSC_FALSE; 9448a70d858SHong Zhang ierr = PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); 9458a70d858SHong Zhang if (flg) { 9468a70d858SHong Zhang void *ctx; 9478a70d858SHong Zhang ierr = SNESMonitorSAWsCreate(snes,&ctx);CHKERRQ(ierr); 9488a70d858SHong Zhang ierr = SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy);CHKERRQ(ierr); 9498a70d858SHong Zhang } 9508a70d858SHong Zhang #endif 9518a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS) 952b90c6cbeSBarry Smith { 953b90c6cbeSBarry Smith PetscBool set; 954b90c6cbeSBarry Smith flg = PETSC_FALSE; 9558a70d858SHong Zhang ierr = PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set);CHKERRQ(ierr); 956b90c6cbeSBarry Smith if (set) { 957e04113cfSBarry Smith ierr = PetscObjectSAWsSetBlock((PetscObject)snes,flg);CHKERRQ(ierr); 958b90c6cbeSBarry Smith } 959b90c6cbeSBarry Smith } 960b90c6cbeSBarry Smith #endif 961b90c6cbeSBarry Smith 96276b2cf59SMatthew Knepley for (i = 0; i < numberofsetfromoptions; i++) { 96376b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 96476b2cf59SMatthew Knepley } 96576b2cf59SMatthew Knepley 966e7788613SBarry Smith if (snes->ops->setfromoptions) { 967e55864a3SBarry Smith ierr = (*snes->ops->setfromoptions)(PetscOptionsObject,snes);CHKERRQ(ierr); 968639f9d9dSBarry Smith } 9695d973c19SBarry Smith 9705d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 9710633abcbSJed Brown ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)snes);CHKERRQ(ierr); 972b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 9734bbc92c1SBarry Smith 9749e764e56SPeter Brune if (!snes->linesearch) { 9757601faf0SJed Brown ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 9769e764e56SPeter Brune } 977f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 9789e764e56SPeter Brune 9796991f827SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 9806991f827SBarry Smith ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr); 9816991f827SBarry Smith ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 9826991f827SBarry Smith 983be95d8f1SBarry Smith /* if someone has set the SNES NPC type, create it. */ 98451e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 985c5929fdfSBarry Smith ierr = PetscOptionsHasName(((PetscObject)snes)->options,optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 986efd4aadfSBarry Smith if (pcset && (!snes->npc)) { 987efd4aadfSBarry Smith ierr = SNESGetNPC(snes, &snes->npc);CHKERRQ(ierr); 98851e86f29SPeter Brune } 9893a40ed3dSBarry Smith PetscFunctionReturn(0); 9909b94acceSBarry Smith } 9919b94acceSBarry Smith 992bb9467b5SJed Brown /*@C 993d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 994d25893d9SBarry Smith the nonlinear solvers. 995d25893d9SBarry Smith 996d25893d9SBarry Smith Logically Collective on SNES 997d25893d9SBarry Smith 998d25893d9SBarry Smith Input Parameters: 999d25893d9SBarry Smith + snes - the SNES context 1000d25893d9SBarry Smith . compute - function to compute the context 1001d25893d9SBarry Smith - destroy - function to destroy the context 1002d25893d9SBarry Smith 1003d25893d9SBarry Smith Level: intermediate 1004d25893d9SBarry Smith 1005bb9467b5SJed Brown Notes: 1006bb9467b5SJed Brown This function is currently not available from Fortran. 1007bb9467b5SJed Brown 1008d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 1009d25893d9SBarry Smith 1010d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 1011d25893d9SBarry Smith @*/ 1012d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 1013d25893d9SBarry Smith { 1014d25893d9SBarry Smith PetscFunctionBegin; 1015d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1016d25893d9SBarry Smith snes->ops->usercompute = compute; 1017d25893d9SBarry Smith snes->ops->userdestroy = destroy; 1018d25893d9SBarry Smith PetscFunctionReturn(0); 1019d25893d9SBarry Smith } 1020a847f771SSatish Balay 1021b07ff414SBarry Smith /*@ 10229b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 10239b94acceSBarry Smith the nonlinear solvers. 10249b94acceSBarry Smith 10253f9fe445SBarry Smith Logically Collective on SNES 1026fee21e36SBarry Smith 1027c7afd0dbSLois Curfman McInnes Input Parameters: 1028c7afd0dbSLois Curfman McInnes + snes - the SNES context 1029c7afd0dbSLois Curfman McInnes - usrP - optional user context 1030c7afd0dbSLois Curfman McInnes 103136851e7fSLois Curfman McInnes Level: intermediate 103236851e7fSLois Curfman McInnes 1033daf670e6SBarry Smith Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this 1034daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1035daf670e6SBarry Smith 10369b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 10379b94acceSBarry Smith 1038ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext() 10399b94acceSBarry Smith @*/ 10407087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 10419b94acceSBarry Smith { 10421b2093e4SBarry Smith PetscErrorCode ierr; 1043b07ff414SBarry Smith KSP ksp; 10441b2093e4SBarry Smith 10453a40ed3dSBarry Smith PetscFunctionBegin; 10460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1047b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 1048b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 10499b94acceSBarry Smith snes->user = usrP; 10503a40ed3dSBarry Smith PetscFunctionReturn(0); 10519b94acceSBarry Smith } 105274679c65SBarry Smith 1053b07ff414SBarry Smith /*@ 10549b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 10559b94acceSBarry Smith nonlinear solvers. 10569b94acceSBarry Smith 1057c7afd0dbSLois Curfman McInnes Not Collective 1058c7afd0dbSLois Curfman McInnes 10599b94acceSBarry Smith Input Parameter: 10609b94acceSBarry Smith . snes - SNES context 10619b94acceSBarry Smith 10629b94acceSBarry Smith Output Parameter: 10639b94acceSBarry Smith . usrP - user context 10649b94acceSBarry Smith 1065daf670e6SBarry Smith Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this 1066daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1067daf670e6SBarry Smith 106836851e7fSLois Curfman McInnes Level: intermediate 106936851e7fSLois Curfman McInnes 10709b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 10719b94acceSBarry Smith 10729b94acceSBarry Smith .seealso: SNESSetApplicationContext() 10739b94acceSBarry Smith @*/ 1074e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 10759b94acceSBarry Smith { 10763a40ed3dSBarry Smith PetscFunctionBegin; 10770700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1078e71120c6SJed Brown *(void**)usrP = snes->user; 10793a40ed3dSBarry Smith PetscFunctionReturn(0); 10809b94acceSBarry Smith } 108174679c65SBarry Smith 10829b94acceSBarry Smith /*@ 10833565c898SBarry Smith SNESSetUseMatrixFree - indicates that SNES should use matrix free finite difference matrix vector products internally to apply 10843565c898SBarry Smith the Jacobian. 10853565c898SBarry Smith 10863565c898SBarry Smith Collective on SNES 10873565c898SBarry Smith 10883565c898SBarry Smith Input Parameters: 10893565c898SBarry Smith + snes - SNES context 10903565c898SBarry 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 10913565c898SBarry Smith - mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 10923565c898SBarry Smith 10933565c898SBarry Smith Options Database: 10943565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator 10953565c898SBarry Smith - -snes_mf_operator - use matrix free only for the mat operator 10963565c898SBarry Smith 10973565c898SBarry Smith Level: intermediate 10983565c898SBarry Smith 10993565c898SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 11003565c898SBarry Smith 11013565c898SBarry Smith .seealso: SNESGetUseMatrixFree(), MatCreateSNESMF() 11023565c898SBarry Smith @*/ 11033565c898SBarry Smith PetscErrorCode SNESSetUseMatrixFree(SNES snes,PetscBool mf_operator,PetscBool mf) 11043565c898SBarry Smith { 11053565c898SBarry Smith PetscFunctionBegin; 11063565c898SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 110788b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes,mf_operator,2); 110888b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes,mf,3); 11093565c898SBarry Smith if (mf && !mf_operator) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"If using mf must also use mf_operator"); 11103565c898SBarry Smith snes->mf = mf; 11113565c898SBarry Smith snes->mf_operator = mf_operator; 11123565c898SBarry Smith PetscFunctionReturn(0); 11133565c898SBarry Smith } 11143565c898SBarry Smith 11153565c898SBarry Smith /*@ 11163565c898SBarry Smith SNESGetUseMatrixFree - indicates if the SNES uses matrix free finite difference matrix vector products to apply 11173565c898SBarry Smith the Jacobian. 11183565c898SBarry Smith 11193565c898SBarry Smith Collective on SNES 11203565c898SBarry Smith 11213565c898SBarry Smith Input Parameter: 11223565c898SBarry Smith . snes - SNES context 11233565c898SBarry Smith 11243565c898SBarry Smith Output Parameters: 11253565c898SBarry 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 11263565c898SBarry Smith - mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 11273565c898SBarry Smith 11283565c898SBarry Smith Options Database: 11293565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator 11303565c898SBarry Smith - -snes_mf_operator - use matrix free only for the mat operator 11313565c898SBarry Smith 11323565c898SBarry Smith Level: intermediate 11333565c898SBarry Smith 11343565c898SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 11353565c898SBarry Smith 11363565c898SBarry Smith .seealso: SNESSetUseMatrixFree(), MatCreateSNESMF() 11373565c898SBarry Smith @*/ 11383565c898SBarry Smith PetscErrorCode SNESGetUseMatrixFree(SNES snes,PetscBool *mf_operator,PetscBool *mf) 11393565c898SBarry Smith { 11403565c898SBarry Smith PetscFunctionBegin; 11413565c898SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11423565c898SBarry Smith if (mf) *mf = snes->mf; 11433565c898SBarry Smith if (mf_operator) *mf_operator = snes->mf_operator; 11443565c898SBarry Smith PetscFunctionReturn(0); 11453565c898SBarry Smith } 11463565c898SBarry Smith 11473565c898SBarry Smith /*@ 1148c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 1149c8228a4eSBarry Smith at this time. 11509b94acceSBarry Smith 1151c7afd0dbSLois Curfman McInnes Not Collective 1152c7afd0dbSLois Curfman McInnes 11539b94acceSBarry Smith Input Parameter: 11549b94acceSBarry Smith . snes - SNES context 11559b94acceSBarry Smith 11569b94acceSBarry Smith Output Parameter: 11579b94acceSBarry Smith . iter - iteration number 11589b94acceSBarry Smith 1159c8228a4eSBarry Smith Notes: 1160c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 1161c8228a4eSBarry Smith 1162c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 116308405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 116408405cd6SLois Curfman McInnes .vb 116508405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 116608405cd6SLois Curfman McInnes if (!(it % 2)) { 116708405cd6SLois Curfman McInnes [compute Jacobian here] 116808405cd6SLois Curfman McInnes } 116908405cd6SLois Curfman McInnes .ve 1170c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 117108405cd6SLois Curfman McInnes recomputed every second SNES iteration. 1172c8228a4eSBarry Smith 1173c04deec6SBarry Smith After the SNES solve is complete this will return the number of nonlinear iterations used. 1174c04deec6SBarry Smith 117536851e7fSLois Curfman McInnes Level: intermediate 117636851e7fSLois Curfman McInnes 11772b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 11782b668275SBarry Smith 117971dbe336SPeter Brune .seealso: SNESGetLinearSolveIterations() 11809b94acceSBarry Smith @*/ 11817087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt *iter) 11829b94acceSBarry Smith { 11833a40ed3dSBarry Smith PetscFunctionBegin; 11840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11854482741eSBarry Smith PetscValidIntPointer(iter,2); 11869b94acceSBarry Smith *iter = snes->iter; 11873a40ed3dSBarry Smith PetscFunctionReturn(0); 11889b94acceSBarry Smith } 118974679c65SBarry Smith 1190360c497dSPeter Brune /*@ 1191360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 1192360c497dSPeter Brune 1193360c497dSPeter Brune Not Collective 1194360c497dSPeter Brune 1195360c497dSPeter Brune Input Parameter: 1196360c497dSPeter Brune . snes - SNES context 1197360c497dSPeter Brune . iter - iteration number 1198360c497dSPeter Brune 1199360c497dSPeter Brune Level: developer 1200360c497dSPeter Brune 1201360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 1202360c497dSPeter Brune 120371dbe336SPeter Brune .seealso: SNESGetLinearSolveIterations() 1204360c497dSPeter Brune @*/ 1205360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 1206360c497dSPeter Brune { 1207360c497dSPeter Brune PetscErrorCode ierr; 1208360c497dSPeter Brune 1209360c497dSPeter Brune PetscFunctionBegin; 1210360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1211e04113cfSBarry Smith ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr); 1212360c497dSPeter Brune snes->iter = iter; 1213e04113cfSBarry Smith ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr); 1214360c497dSPeter Brune PetscFunctionReturn(0); 1215360c497dSPeter Brune } 1216360c497dSPeter Brune 12179b94acceSBarry Smith /*@ 1218b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 12199b94acceSBarry Smith attempted by the nonlinear solver. 12209b94acceSBarry Smith 1221c7afd0dbSLois Curfman McInnes Not Collective 1222c7afd0dbSLois Curfman McInnes 12239b94acceSBarry Smith Input Parameter: 12249b94acceSBarry Smith . snes - SNES context 12259b94acceSBarry Smith 12269b94acceSBarry Smith Output Parameter: 12279b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 12289b94acceSBarry Smith 1229c96a6f78SLois Curfman McInnes Notes: 1230c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1231c96a6f78SLois Curfman McInnes 123236851e7fSLois Curfman McInnes Level: intermediate 123336851e7fSLois Curfman McInnes 12349b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 123558ebbce7SBarry Smith 1236e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 123758ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 12389b94acceSBarry Smith @*/ 12397087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails) 12409b94acceSBarry Smith { 12413a40ed3dSBarry Smith PetscFunctionBegin; 12420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12434482741eSBarry Smith PetscValidIntPointer(nfails,2); 124450ffb88aSMatthew Knepley *nfails = snes->numFailures; 124550ffb88aSMatthew Knepley PetscFunctionReturn(0); 124650ffb88aSMatthew Knepley } 124750ffb88aSMatthew Knepley 124850ffb88aSMatthew Knepley /*@ 1249b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 125050ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 125150ffb88aSMatthew Knepley 125250ffb88aSMatthew Knepley Not Collective 125350ffb88aSMatthew Knepley 125450ffb88aSMatthew Knepley Input Parameters: 125550ffb88aSMatthew Knepley + snes - SNES context 125650ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 125750ffb88aSMatthew Knepley 125850ffb88aSMatthew Knepley Level: intermediate 125950ffb88aSMatthew Knepley 126050ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 126158ebbce7SBarry Smith 1262e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 126358ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 126450ffb88aSMatthew Knepley @*/ 12657087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 126650ffb88aSMatthew Knepley { 126750ffb88aSMatthew Knepley PetscFunctionBegin; 12680700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 126950ffb88aSMatthew Knepley snes->maxFailures = maxFails; 127050ffb88aSMatthew Knepley PetscFunctionReturn(0); 127150ffb88aSMatthew Knepley } 127250ffb88aSMatthew Knepley 127350ffb88aSMatthew Knepley /*@ 1274b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets 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 Parameter: 128050ffb88aSMatthew Knepley . snes - SNES context 128150ffb88aSMatthew Knepley 128250ffb88aSMatthew Knepley Output Parameter: 128350ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 128450ffb88aSMatthew Knepley 128550ffb88aSMatthew Knepley Level: intermediate 128650ffb88aSMatthew Knepley 128750ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 128858ebbce7SBarry Smith 1289e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 129058ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 129158ebbce7SBarry Smith 129250ffb88aSMatthew Knepley @*/ 12937087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 129450ffb88aSMatthew Knepley { 129550ffb88aSMatthew Knepley PetscFunctionBegin; 12960700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12974482741eSBarry Smith PetscValidIntPointer(maxFails,2); 129850ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 12993a40ed3dSBarry Smith PetscFunctionReturn(0); 13009b94acceSBarry Smith } 1301a847f771SSatish Balay 13022541af92SBarry Smith /*@ 13032541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 13042541af92SBarry Smith done by SNES. 13052541af92SBarry Smith 13062541af92SBarry Smith Not Collective 13072541af92SBarry Smith 13082541af92SBarry Smith Input Parameter: 13092541af92SBarry Smith . snes - SNES context 13102541af92SBarry Smith 13112541af92SBarry Smith Output Parameter: 13122541af92SBarry Smith . nfuncs - number of evaluations 13132541af92SBarry Smith 13142541af92SBarry Smith Level: intermediate 13152541af92SBarry Smith 1316971e163fSPeter Brune Notes: Reset every time SNESSolve is called unless SNESSetCountersReset() is used. 1317971e163fSPeter Brune 13182541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 131958ebbce7SBarry Smith 1320971e163fSPeter Brune .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), SNESSetCountersReset() 13212541af92SBarry Smith @*/ 13227087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 13232541af92SBarry Smith { 13242541af92SBarry Smith PetscFunctionBegin; 13250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13262541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 13272541af92SBarry Smith *nfuncs = snes->nfuncs; 13282541af92SBarry Smith PetscFunctionReturn(0); 13292541af92SBarry Smith } 13302541af92SBarry Smith 13313d4c4710SBarry Smith /*@ 13323d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 13333d4c4710SBarry Smith linear solvers. 13343d4c4710SBarry Smith 13353d4c4710SBarry Smith Not Collective 13363d4c4710SBarry Smith 13373d4c4710SBarry Smith Input Parameter: 13383d4c4710SBarry Smith . snes - SNES context 13393d4c4710SBarry Smith 13403d4c4710SBarry Smith Output Parameter: 13413d4c4710SBarry Smith . nfails - number of failed solves 13423d4c4710SBarry Smith 13439d85da0cSMatthew G. Knepley Level: intermediate 13449d85da0cSMatthew G. Knepley 13459d85da0cSMatthew G. Knepley Options Database Keys: 13469d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 13479d85da0cSMatthew G. Knepley 13483d4c4710SBarry Smith Notes: 13493d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 13503d4c4710SBarry Smith 13513d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 135258ebbce7SBarry Smith 1353e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 13543d4c4710SBarry Smith @*/ 13557087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails) 13563d4c4710SBarry Smith { 13573d4c4710SBarry Smith PetscFunctionBegin; 13580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13593d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 13603d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 13613d4c4710SBarry Smith PetscFunctionReturn(0); 13623d4c4710SBarry Smith } 13633d4c4710SBarry Smith 13643d4c4710SBarry Smith /*@ 13653d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 13663d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 13673d4c4710SBarry Smith 13683f9fe445SBarry Smith Logically Collective on SNES 13693d4c4710SBarry Smith 13703d4c4710SBarry Smith Input Parameters: 13713d4c4710SBarry Smith + snes - SNES context 13723d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 13733d4c4710SBarry Smith 13743d4c4710SBarry Smith Level: intermediate 13753d4c4710SBarry Smith 13769d85da0cSMatthew G. Knepley Options Database Keys: 13779d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 13789d85da0cSMatthew G. Knepley 1379a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 13803d4c4710SBarry Smith 13813d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 13823d4c4710SBarry Smith 138358ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 13843d4c4710SBarry Smith @*/ 13857087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 13863d4c4710SBarry Smith { 13873d4c4710SBarry Smith PetscFunctionBegin; 13880700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1389c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 13903d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 13913d4c4710SBarry Smith PetscFunctionReturn(0); 13923d4c4710SBarry Smith } 13933d4c4710SBarry Smith 13943d4c4710SBarry Smith /*@ 13953d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 13963d4c4710SBarry Smith are allowed before SNES terminates 13973d4c4710SBarry Smith 13983d4c4710SBarry Smith Not Collective 13993d4c4710SBarry Smith 14003d4c4710SBarry Smith Input Parameter: 14013d4c4710SBarry Smith . snes - SNES context 14023d4c4710SBarry Smith 14033d4c4710SBarry Smith Output Parameter: 14043d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 14053d4c4710SBarry Smith 14063d4c4710SBarry Smith Level: intermediate 14073d4c4710SBarry Smith 14083d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 14093d4c4710SBarry Smith 14103d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 14113d4c4710SBarry Smith 1412e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 14133d4c4710SBarry Smith @*/ 14147087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 14153d4c4710SBarry Smith { 14163d4c4710SBarry Smith PetscFunctionBegin; 14170700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14183d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 14193d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 14203d4c4710SBarry Smith PetscFunctionReturn(0); 14213d4c4710SBarry Smith } 14223d4c4710SBarry Smith 1423c96a6f78SLois Curfman McInnes /*@ 1424b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1425c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1426c96a6f78SLois Curfman McInnes 1427c7afd0dbSLois Curfman McInnes Not Collective 1428c7afd0dbSLois Curfman McInnes 1429c96a6f78SLois Curfman McInnes Input Parameter: 1430c96a6f78SLois Curfman McInnes . snes - SNES context 1431c96a6f78SLois Curfman McInnes 1432c96a6f78SLois Curfman McInnes Output Parameter: 1433c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1434c96a6f78SLois Curfman McInnes 1435c96a6f78SLois Curfman McInnes Notes: 1436971e163fSPeter Brune This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used. 1437c96a6f78SLois Curfman McInnes 1438010be392SBarry 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 1439010be392SBarry Smith then call KSPGetIterationNumber() after the failed solve. 1440010be392SBarry Smith 144136851e7fSLois Curfman McInnes Level: intermediate 144236851e7fSLois Curfman McInnes 1443c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 14442b668275SBarry Smith 144571dbe336SPeter Brune .seealso: SNESGetIterationNumber(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESSetCountersReset() 1446c96a6f78SLois Curfman McInnes @*/ 14477087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt *lits) 1448c96a6f78SLois Curfman McInnes { 14493a40ed3dSBarry Smith PetscFunctionBegin; 14500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14514482741eSBarry Smith PetscValidIntPointer(lits,2); 1452c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 14533a40ed3dSBarry Smith PetscFunctionReturn(0); 1454c96a6f78SLois Curfman McInnes } 1455c96a6f78SLois Curfman McInnes 1456971e163fSPeter Brune /*@ 1457971e163fSPeter Brune SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations 1458971e163fSPeter Brune are reset every time SNESSolve() is called. 1459971e163fSPeter Brune 1460971e163fSPeter Brune Logically Collective on SNES 1461971e163fSPeter Brune 1462971e163fSPeter Brune Input Parameter: 1463971e163fSPeter Brune + snes - SNES context 1464971e163fSPeter Brune - reset - whether to reset the counters or not 1465971e163fSPeter Brune 1466971e163fSPeter Brune Notes: 1467fa19ca70SBarry Smith This defaults to PETSC_TRUE 1468971e163fSPeter Brune 1469971e163fSPeter Brune Level: developer 1470971e163fSPeter Brune 1471971e163fSPeter Brune .keywords: SNES, nonlinear, set, reset, number, linear, iterations 1472971e163fSPeter Brune 1473734794cfSBarry Smith .seealso: SNESGetNumberFunctionEvals(), SNESGetLinearSolveIterations(), SNESGetNPC() 1474971e163fSPeter Brune @*/ 1475971e163fSPeter Brune PetscErrorCode SNESSetCountersReset(SNES snes,PetscBool reset) 1476971e163fSPeter Brune { 1477971e163fSPeter Brune PetscFunctionBegin; 1478971e163fSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1479971e163fSPeter Brune PetscValidLogicalCollectiveBool(snes,reset,2); 1480971e163fSPeter Brune snes->counters_reset = reset; 1481971e163fSPeter Brune PetscFunctionReturn(0); 1482971e163fSPeter Brune } 1483971e163fSPeter Brune 148482bf6240SBarry Smith 14852999313aSBarry Smith /*@ 14862999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 14872999313aSBarry Smith 14882999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 14892999313aSBarry Smith 14902999313aSBarry Smith Input Parameters: 14912999313aSBarry Smith + snes - the SNES context 14922999313aSBarry Smith - ksp - the KSP context 14932999313aSBarry Smith 14942999313aSBarry Smith Notes: 14952999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 14962999313aSBarry Smith so this routine is rarely needed. 14972999313aSBarry Smith 14982999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 14992999313aSBarry Smith decreased by one. 15002999313aSBarry Smith 15012999313aSBarry Smith Level: developer 15022999313aSBarry Smith 15032999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 15042999313aSBarry Smith 15052999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 15062999313aSBarry Smith @*/ 15077087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 15082999313aSBarry Smith { 15092999313aSBarry Smith PetscErrorCode ierr; 15102999313aSBarry Smith 15112999313aSBarry Smith PetscFunctionBegin; 15120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15130700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 15142999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 15157dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1516906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 15172999313aSBarry Smith snes->ksp = ksp; 15182999313aSBarry Smith PetscFunctionReturn(0); 15192999313aSBarry Smith } 15202999313aSBarry Smith 15219b94acceSBarry Smith /* -----------------------------------------------------------*/ 152252baeb72SSatish Balay /*@ 15239b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 15249b94acceSBarry Smith 1525c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1526c7afd0dbSLois Curfman McInnes 1527c7afd0dbSLois Curfman McInnes Input Parameters: 1528906ed7ccSBarry Smith . comm - MPI communicator 15299b94acceSBarry Smith 15309b94acceSBarry Smith Output Parameter: 15319b94acceSBarry Smith . outsnes - the new SNES context 15329b94acceSBarry Smith 1533c7afd0dbSLois Curfman McInnes Options Database Keys: 1534c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1535c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1536c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1537c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1538c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1539c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1540c1f60f51SBarry Smith 154136851e7fSLois Curfman McInnes Level: beginner 154236851e7fSLois Curfman McInnes 1543efd4aadfSBarry Smith Developer Notes: SNES always creates a KSP object even though many SNES methods do not use it. This is 1544efd4aadfSBarry Smith unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the 1545efd4aadfSBarry Smith particular method does use KSP and regulates if the information about the KSP is printed 1546efd4aadfSBarry Smith in SNESView(). TSSetFromOptions() does call SNESSetFromOptions() which can lead to users being confused 1547efd4aadfSBarry Smith by help messages about meaningless SNES options. 1548efd4aadfSBarry Smith 1549efd4aadfSBarry Smith SNES always creates the snes->kspconvctx even though it is used by only one type. This should 1550efd4aadfSBarry Smith be fixed. 1551efd4aadfSBarry Smith 15529b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 15539b94acceSBarry Smith 1554a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1555a8054027SBarry Smith 15569b94acceSBarry Smith @*/ 15577087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 15589b94acceSBarry Smith { 1559dfbe8321SBarry Smith PetscErrorCode ierr; 15609b94acceSBarry Smith SNES snes; 1561fa9f3622SBarry Smith SNESKSPEW *kctx; 156237fcc0dbSBarry Smith 15633a40ed3dSBarry Smith PetscFunctionBegin; 1564ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 15650298fd71SBarry Smith *outsnes = NULL; 1566607a6623SBarry Smith ierr = SNESInitializePackage();CHKERRQ(ierr); 15678ba1e511SMatthew Knepley 156873107ff1SLisandro Dalcin ierr = PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 15697adad957SLisandro Dalcin 15708d359177SBarry Smith snes->ops->converged = SNESConvergedDefault; 15712c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 157288976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 15739b94acceSBarry Smith snes->max_its = 50; 15749750a799SBarry Smith snes->max_funcs = 10000; 15759b94acceSBarry Smith snes->norm = 0.0; 1576365a6726SPeter Brune snes->normschedule = SNES_NORM_ALWAYS; 15776c67d002SPeter Brune snes->functype = SNES_FUNCTION_DEFAULT; 15783a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 15793a2046daSBarry Smith snes->rtol = 1.e-5; 15803a2046daSBarry Smith #else 1581b4874afaSBarry Smith snes->rtol = 1.e-8; 15823a2046daSBarry Smith #endif 1583b4874afaSBarry Smith snes->ttol = 0.0; 15843a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 15853a2046daSBarry Smith snes->abstol = 1.e-25; 15863a2046daSBarry Smith #else 158770441072SBarry Smith snes->abstol = 1.e-50; 15883a2046daSBarry Smith #endif 15897cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE) 15907cd0ae37SLisandro Dalcin snes->stol = 1.e-5; 15917cd0ae37SLisandro Dalcin #else 1592c60f73f4SPeter Brune snes->stol = 1.e-8; 15937cd0ae37SLisandro Dalcin #endif 15943a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 15953a2046daSBarry Smith snes->deltatol = 1.e-6; 15963a2046daSBarry Smith #else 15974b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 15983a2046daSBarry Smith #endif 1599e37c518bSBarry Smith snes->divtol = 1.e4; 1600e37c518bSBarry Smith snes->rnorm0 = 0; 16019b94acceSBarry Smith snes->nfuncs = 0; 160250ffb88aSMatthew Knepley snes->numFailures = 0; 160350ffb88aSMatthew Knepley snes->maxFailures = 1; 16047a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1605e35cf81dSBarry Smith snes->lagjacobian = 1; 160637ec4e1aSPeter Brune snes->jac_iter = 0; 160737ec4e1aSPeter Brune snes->lagjac_persist = PETSC_FALSE; 1608a8054027SBarry Smith snes->lagpreconditioner = 1; 160937ec4e1aSPeter Brune snes->pre_iter = 0; 161037ec4e1aSPeter Brune snes->lagpre_persist = PETSC_FALSE; 1611639f9d9dSBarry Smith snes->numbermonitors = 0; 16129b94acceSBarry Smith snes->data = 0; 16134dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1614186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 16156f24a144SLois Curfman McInnes snes->nwork = 0; 161658c9b817SLisandro Dalcin snes->work = 0; 161758c9b817SLisandro Dalcin snes->nvwork = 0; 161858c9b817SLisandro Dalcin snes->vwork = 0; 1619758f92a0SBarry Smith snes->conv_hist_len = 0; 1620758f92a0SBarry Smith snes->conv_hist_max = 0; 16210298fd71SBarry Smith snes->conv_hist = NULL; 16220298fd71SBarry Smith snes->conv_hist_its = NULL; 1623758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1624971e163fSPeter Brune snes->counters_reset = PETSC_TRUE; 1625e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1626184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 1627efd4aadfSBarry Smith snes->npcside = PC_RIGHT; 1628c40d0f55SPeter Brune 1629d8f46077SPeter Brune snes->mf = PETSC_FALSE; 1630d8f46077SPeter Brune snes->mf_operator = PETSC_FALSE; 1631d8f46077SPeter Brune snes->mf_version = 1; 1632d8f46077SPeter Brune 16333d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 16343d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 16353d4c4710SBarry Smith 1636349187a7SBarry Smith snes->vizerotolerance = 1.e-8; 1637349187a7SBarry Smith 16384fc747eaSLawrence Mitchell /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */ 16394fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 16404fc747eaSLawrence Mitchell 16419b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 1642b00a9115SJed Brown ierr = PetscNewLog(snes,&kctx);CHKERRQ(ierr); 1643f5af7f23SKarl Rupp 16449b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 16459b94acceSBarry Smith kctx->version = 2; 16469b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 16479b94acceSBarry Smith this was too large for some test cases */ 164875567043SBarry Smith kctx->rtol_last = 0.0; 16499b94acceSBarry Smith kctx->rtol_max = .9; 16509b94acceSBarry Smith kctx->gamma = 1.0; 165162d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 165271f87433Sdalcinl kctx->alpha2 = kctx->alpha; 16539b94acceSBarry Smith kctx->threshold = .1; 165475567043SBarry Smith kctx->lresid_last = 0.0; 165575567043SBarry Smith kctx->norm_last = 0.0; 16569b94acceSBarry Smith 16579b94acceSBarry Smith *outsnes = snes; 16583a40ed3dSBarry Smith PetscFunctionReturn(0); 16599b94acceSBarry Smith } 16609b94acceSBarry Smith 166188f0584fSBarry Smith /*MC 1662411c0326SBarry Smith SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES 166388f0584fSBarry Smith 166488f0584fSBarry Smith Synopsis: 1665411c0326SBarry Smith #include "petscsnes.h" 1666411c0326SBarry Smith PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx); 166788f0584fSBarry Smith 166888f0584fSBarry Smith Input Parameters: 166988f0584fSBarry Smith + snes - the SNES context 167088f0584fSBarry Smith . x - state at which to evaluate residual 167188f0584fSBarry Smith - ctx - optional user-defined function context, passed in with SNESSetFunction() 167288f0584fSBarry Smith 167388f0584fSBarry Smith Output Parameter: 167488f0584fSBarry Smith . f - vector to put residual (function value) 167588f0584fSBarry Smith 1676878cb397SSatish Balay Level: intermediate 1677878cb397SSatish Balay 167888f0584fSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 167988f0584fSBarry Smith M*/ 168088f0584fSBarry Smith 16819b94acceSBarry Smith /*@C 16829b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 16839b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 16849b94acceSBarry Smith equations. 16859b94acceSBarry Smith 16863f9fe445SBarry Smith Logically Collective on SNES 1687fee21e36SBarry Smith 1688c7afd0dbSLois Curfman McInnes Input Parameters: 1689c7afd0dbSLois Curfman McInnes + snes - the SNES context 1690c7afd0dbSLois Curfman McInnes . r - vector to store function value 1691f8b49ee9SBarry Smith . f - function evaluation routine; see SNESFunction for calling sequence details 1692c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 16930298fd71SBarry Smith function evaluation routine (may be NULL) 16949b94acceSBarry Smith 16959b94acceSBarry Smith Notes: 16969b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 16979b94acceSBarry Smith $ f'(x) x = -f(x), 1698c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 16999b94acceSBarry Smith 170036851e7fSLois Curfman McInnes Level: beginner 170136851e7fSLois Curfman McInnes 17029b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 17039b94acceSBarry Smith 1704bf388a1fSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction 17059b94acceSBarry Smith @*/ 1706f8b49ee9SBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 17079b94acceSBarry Smith { 170885385478SLisandro Dalcin PetscErrorCode ierr; 17096cab3a1bSJed Brown DM dm; 17106cab3a1bSJed Brown 17113a40ed3dSBarry Smith PetscFunctionBegin; 17120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1713d2a683ecSLisandro Dalcin if (r) { 1714d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1715d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 171685385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 17176bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 1718f5af7f23SKarl Rupp 171985385478SLisandro Dalcin snes->vec_func = r; 1720d2a683ecSLisandro Dalcin } 17216cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1722f8b49ee9SBarry Smith ierr = DMSNESSetFunction(dm,f,ctx);CHKERRQ(ierr); 17233a40ed3dSBarry Smith PetscFunctionReturn(0); 17249b94acceSBarry Smith } 17259b94acceSBarry Smith 1726646217ecSPeter Brune 1727e4ed7901SPeter Brune /*@C 1728e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1729e4ed7901SPeter Brune function norm at the initialization of the method. In some 1730e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1731e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1732e4ed7901SPeter Brune to SNESComputeFunction in that case. 1733e4ed7901SPeter Brune 1734e4ed7901SPeter Brune Logically Collective on SNES 1735e4ed7901SPeter Brune 1736e4ed7901SPeter Brune Input Parameters: 1737e4ed7901SPeter Brune + snes - the SNES context 1738e4ed7901SPeter Brune - f - vector to store function value 1739e4ed7901SPeter Brune 1740e4ed7901SPeter Brune Notes: 1741e4ed7901SPeter Brune This should not be modified during the solution procedure. 1742e4ed7901SPeter Brune 1743e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1744e4ed7901SPeter Brune 1745e4ed7901SPeter Brune Level: developer 1746e4ed7901SPeter Brune 1747e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function 1748e4ed7901SPeter Brune 1749e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1750e4ed7901SPeter Brune @*/ 1751e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1752e4ed7901SPeter Brune { 1753e4ed7901SPeter Brune PetscErrorCode ierr; 1754e4ed7901SPeter Brune Vec vec_func; 1755e4ed7901SPeter Brune 1756e4ed7901SPeter Brune PetscFunctionBegin; 1757e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1758e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1759e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 1760efd4aadfSBarry Smith if (snes->npcside== PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) { 1761902f982fSPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1762902f982fSPeter Brune PetscFunctionReturn(0); 1763902f982fSPeter Brune } 17640298fd71SBarry Smith ierr = SNESGetFunction(snes,&vec_func,NULL,NULL);CHKERRQ(ierr); 1765e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1766f5af7f23SKarl Rupp 1767217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1768e4ed7901SPeter Brune PetscFunctionReturn(0); 1769e4ed7901SPeter Brune } 1770e4ed7901SPeter Brune 1771534ebe21SPeter Brune /*@ 1772365a6726SPeter Brune SNESSetNormSchedule - Sets the SNESNormSchedule used in covergence and monitoring 1773534ebe21SPeter Brune of the SNES method. 1774534ebe21SPeter Brune 1775534ebe21SPeter Brune Logically Collective on SNES 1776534ebe21SPeter Brune 1777534ebe21SPeter Brune Input Parameters: 1778534ebe21SPeter Brune + snes - the SNES context 1779365a6726SPeter Brune - normschedule - the frequency of norm computation 1780534ebe21SPeter Brune 1781517f1916SMatthew G. Knepley Options Database Key: 1782517f1916SMatthew G. Knepley . -snes_norm_schedule <none, always, initialonly, finalonly, initalfinalonly> 1783517f1916SMatthew G. Knepley 1784534ebe21SPeter Brune Notes: 1785365a6726SPeter Brune Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 1786534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1787534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1788be95d8f1SBarry Smith (SNESNGS) and the like do not require the norm of the function to be computed, and therfore 1789534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1790534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1791534ebe21SPeter Brune their solution. 1792534ebe21SPeter Brune 1793534ebe21SPeter Brune Level: developer 1794534ebe21SPeter Brune 1795534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1796534ebe21SPeter Brune 1797365a6726SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1798534ebe21SPeter Brune @*/ 1799365a6726SPeter Brune PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule) 1800534ebe21SPeter Brune { 1801534ebe21SPeter Brune PetscFunctionBegin; 1802534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1803365a6726SPeter Brune snes->normschedule = normschedule; 1804534ebe21SPeter Brune PetscFunctionReturn(0); 1805534ebe21SPeter Brune } 1806534ebe21SPeter Brune 1807534ebe21SPeter Brune 1808534ebe21SPeter Brune /*@ 1809365a6726SPeter Brune SNESGetNormSchedule - Gets the SNESNormSchedule used in covergence and monitoring 1810534ebe21SPeter Brune of the SNES method. 1811534ebe21SPeter Brune 1812534ebe21SPeter Brune Logically Collective on SNES 1813534ebe21SPeter Brune 1814534ebe21SPeter Brune Input Parameters: 1815534ebe21SPeter Brune + snes - the SNES context 1816365a6726SPeter Brune - normschedule - the type of the norm used 1817534ebe21SPeter Brune 1818534ebe21SPeter Brune Level: advanced 1819534ebe21SPeter Brune 1820534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1821534ebe21SPeter Brune 1822365a6726SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1823534ebe21SPeter Brune @*/ 1824365a6726SPeter Brune PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule) 1825534ebe21SPeter Brune { 1826534ebe21SPeter Brune PetscFunctionBegin; 1827534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1828365a6726SPeter Brune *normschedule = snes->normschedule; 1829534ebe21SPeter Brune PetscFunctionReturn(0); 1830534ebe21SPeter Brune } 1831534ebe21SPeter Brune 183247073ea2SPeter Brune 1833c5ce4427SMatthew G. Knepley /*@ 1834c5ce4427SMatthew G. Knepley SNESSetFunctionNorm - Sets the last computed residual norm. 1835c5ce4427SMatthew G. Knepley 1836c5ce4427SMatthew G. Knepley Logically Collective on SNES 1837c5ce4427SMatthew G. Knepley 1838c5ce4427SMatthew G. Knepley Input Parameters: 1839c5ce4427SMatthew G. Knepley + snes - the SNES context 1840c5ce4427SMatthew G. Knepley 1841c5ce4427SMatthew G. Knepley - normschedule - the frequency of norm computation 1842c5ce4427SMatthew G. Knepley 1843c5ce4427SMatthew G. Knepley Level: developer 1844c5ce4427SMatthew G. Knepley 1845c5ce4427SMatthew G. Knepley .keywords: SNES, nonlinear, set, function, norm, type 1846c5ce4427SMatthew G. Knepley .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1847c5ce4427SMatthew G. Knepley @*/ 1848c5ce4427SMatthew G. Knepley PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm) 1849c5ce4427SMatthew G. Knepley { 1850c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1851c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1852c5ce4427SMatthew G. Knepley snes->norm = norm; 1853c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 1854c5ce4427SMatthew G. Knepley } 1855c5ce4427SMatthew G. Knepley 1856c5ce4427SMatthew G. Knepley /*@ 1857c5ce4427SMatthew G. Knepley SNESGetFunctionNorm - Gets the last computed norm of the residual 1858c5ce4427SMatthew G. Knepley 1859c5ce4427SMatthew G. Knepley Not Collective 1860c5ce4427SMatthew G. Knepley 1861c5ce4427SMatthew G. Knepley Input Parameter: 1862c5ce4427SMatthew G. Knepley . snes - the SNES context 1863c5ce4427SMatthew G. Knepley 1864c5ce4427SMatthew G. Knepley Output Parameter: 1865c5ce4427SMatthew G. Knepley . norm - the last computed residual norm 1866c5ce4427SMatthew G. Knepley 1867c5ce4427SMatthew G. Knepley Level: developer 1868c5ce4427SMatthew G. Knepley 1869c5ce4427SMatthew G. Knepley .keywords: SNES, nonlinear, set, function, norm, type 1870c5ce4427SMatthew G. Knepley .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1871c5ce4427SMatthew G. Knepley @*/ 1872c5ce4427SMatthew G. Knepley PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm) 1873c5ce4427SMatthew G. Knepley { 1874c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1875c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1876c5ce4427SMatthew G. Knepley PetscValidPointer(norm, 2); 1877c5ce4427SMatthew G. Knepley *norm = snes->norm; 1878c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 1879c5ce4427SMatthew G. Knepley } 1880c5ce4427SMatthew G. Knepley 188147073ea2SPeter Brune /*@C 188247073ea2SPeter Brune SNESSetFunctionType - Sets the SNESNormSchedule used in covergence and monitoring 188347073ea2SPeter Brune of the SNES method. 188447073ea2SPeter Brune 188547073ea2SPeter Brune Logically Collective on SNES 188647073ea2SPeter Brune 188747073ea2SPeter Brune Input Parameters: 188847073ea2SPeter Brune + snes - the SNES context 188947073ea2SPeter Brune - normschedule - the frequency of norm computation 189047073ea2SPeter Brune 189147073ea2SPeter Brune Notes: 189247073ea2SPeter Brune Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 189347073ea2SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 189447073ea2SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1895be95d8f1SBarry Smith (SNESNGS) and the like do not require the norm of the function to be computed, and therfore 189647073ea2SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 189747073ea2SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 189847073ea2SPeter Brune their solution. 189947073ea2SPeter Brune 190047073ea2SPeter Brune Level: developer 190147073ea2SPeter Brune 190247073ea2SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 190347073ea2SPeter Brune 190447073ea2SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 190547073ea2SPeter Brune @*/ 190647073ea2SPeter Brune PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type) 190747073ea2SPeter Brune { 190847073ea2SPeter Brune PetscFunctionBegin; 190947073ea2SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 191047073ea2SPeter Brune snes->functype = type; 191147073ea2SPeter Brune PetscFunctionReturn(0); 191247073ea2SPeter Brune } 191347073ea2SPeter Brune 191447073ea2SPeter Brune 191547073ea2SPeter Brune /*@C 191647073ea2SPeter Brune SNESGetFunctionType - Gets the SNESNormSchedule used in covergence and monitoring 191747073ea2SPeter Brune of the SNES method. 191847073ea2SPeter Brune 191947073ea2SPeter Brune Logically Collective on SNES 192047073ea2SPeter Brune 192147073ea2SPeter Brune Input Parameters: 192247073ea2SPeter Brune + snes - the SNES context 192347073ea2SPeter Brune - normschedule - the type of the norm used 192447073ea2SPeter Brune 192547073ea2SPeter Brune Level: advanced 192647073ea2SPeter Brune 192747073ea2SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 192847073ea2SPeter Brune 192947073ea2SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 193047073ea2SPeter Brune @*/ 193147073ea2SPeter Brune PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type) 193247073ea2SPeter Brune { 193347073ea2SPeter Brune PetscFunctionBegin; 193447073ea2SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 193547073ea2SPeter Brune *type = snes->functype; 1936534ebe21SPeter Brune PetscFunctionReturn(0); 1937534ebe21SPeter Brune } 1938534ebe21SPeter Brune 1939bf388a1fSBarry Smith /*MC 1940be95d8f1SBarry Smith SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function 1941bf388a1fSBarry Smith 1942bf388a1fSBarry Smith Synopsis: 1943aaa7dc30SBarry Smith #include <petscsnes.h> 1944be95d8f1SBarry Smith $ SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx); 1945bf388a1fSBarry Smith 1946bf388a1fSBarry Smith + X - solution vector 1947bf388a1fSBarry Smith . B - RHS vector 1948bf388a1fSBarry Smith - ctx - optional user-defined Gauss-Seidel context 1949bf388a1fSBarry Smith 1950878cb397SSatish Balay Level: intermediate 1951878cb397SSatish Balay 1952be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetNGS() 1953bf388a1fSBarry Smith M*/ 1954bf388a1fSBarry Smith 1955c79ef259SPeter Brune /*@C 1956be95d8f1SBarry Smith SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for 1957c79ef259SPeter Brune use with composed nonlinear solvers. 1958c79ef259SPeter Brune 1959c79ef259SPeter Brune Input Parameters: 1960c79ef259SPeter Brune + snes - the SNES context 1961be95d8f1SBarry Smith . f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction 1962c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 19630298fd71SBarry Smith smoother evaluation routine (may be NULL) 1964c79ef259SPeter Brune 1965c79ef259SPeter Brune Notes: 1966be95d8f1SBarry Smith The NGS routines are used by the composed nonlinear solver to generate 1967c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1968c79ef259SPeter Brune 1969d28543b3SPeter Brune Level: intermediate 1970c79ef259SPeter Brune 1971d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1972c79ef259SPeter Brune 1973be95d8f1SBarry Smith .seealso: SNESGetFunction(), SNESComputeNGS() 1974c79ef259SPeter Brune @*/ 1975be95d8f1SBarry Smith PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 19766cab3a1bSJed Brown { 19776cab3a1bSJed Brown PetscErrorCode ierr; 19786cab3a1bSJed Brown DM dm; 19796cab3a1bSJed Brown 1980646217ecSPeter Brune PetscFunctionBegin; 19816cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 19826cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1983be95d8f1SBarry Smith ierr = DMSNESSetNGS(dm,f,ctx);CHKERRQ(ierr); 1984646217ecSPeter Brune PetscFunctionReturn(0); 1985646217ecSPeter Brune } 1986646217ecSPeter Brune 198782b59a81SJed Brown PETSC_EXTERN PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 19888b0a5094SBarry Smith { 19898b0a5094SBarry Smith PetscErrorCode ierr; 1990e03ab78fSPeter Brune DM dm; 1991942e3340SBarry Smith DMSNES sdm; 19926cab3a1bSJed Brown 19938b0a5094SBarry Smith PetscFunctionBegin; 1994e03ab78fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1995942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 19968b0a5094SBarry Smith /* A(x)*x - b(x) */ 199722c6f798SBarry Smith if (sdm->ops->computepfunction) { 199822c6f798SBarry Smith ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr); 199922c6f798SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard function."); 2000e03ab78fSPeter Brune 200122c6f798SBarry Smith if (sdm->ops->computepjacobian) { 2002d1e9a80fSBarry Smith ierr = (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);CHKERRQ(ierr); 200374e1e8c1SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard matrix."); 20048b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 200595eabcedSBarry Smith ierr = MatMultAdd(snes->jacobian,x,f,f);CHKERRQ(ierr); 20068b0a5094SBarry Smith PetscFunctionReturn(0); 20078b0a5094SBarry Smith } 20088b0a5094SBarry Smith 2009d1e9a80fSBarry Smith PETSC_EXTERN PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx) 20108b0a5094SBarry Smith { 20118b0a5094SBarry Smith PetscFunctionBegin; 2012e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 20138b0a5094SBarry Smith PetscFunctionReturn(0); 20148b0a5094SBarry Smith } 20158b0a5094SBarry Smith 20168b0a5094SBarry Smith /*@C 20170d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 20188b0a5094SBarry Smith 20198b0a5094SBarry Smith Logically Collective on SNES 20208b0a5094SBarry Smith 20218b0a5094SBarry Smith Input Parameters: 20228b0a5094SBarry Smith + snes - the SNES context 20238b0a5094SBarry Smith . r - vector to store function value 2024f8b49ee9SBarry Smith . b - function evaluation routine 2025e5d3d808SBarry Smith . Amat - matrix with which A(x) x - b(x) is to be computed 2026e5d3d808SBarry Smith . Pmat - matrix from which preconditioner is computed (usually the same as Amat) 2027411c0326SBarry Smith . J - function to compute matrix value, see SNESJacobianFunction for details on its calling sequence 20288b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 20290298fd71SBarry Smith function evaluation routine (may be NULL) 20308b0a5094SBarry Smith 20318b0a5094SBarry Smith Notes: 2032f450aa47SBarry 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 2033f450aa47SBarry 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. 2034f450aa47SBarry Smith 20358b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 20368b0a5094SBarry Smith 20378b0a5094SBarry 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} 20388b0a5094SBarry 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. 20398b0a5094SBarry Smith 20408b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 20418b0a5094SBarry Smith 20420d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 20430d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 20448b0a5094SBarry Smith 20458b0a5094SBarry 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 20468b0a5094SBarry 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 20478b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 20488b0a5094SBarry Smith 2049f450aa47SBarry Smith Level: intermediate 20508b0a5094SBarry Smith 20518b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 20528b0a5094SBarry Smith 2053411c0326SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard(), SNESJacobianFunction 20548b0a5094SBarry Smith @*/ 2055d1e9a80fSBarry 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) 20568b0a5094SBarry Smith { 20578b0a5094SBarry Smith PetscErrorCode ierr; 2058e03ab78fSPeter Brune DM dm; 2059e03ab78fSPeter Brune 20608b0a5094SBarry Smith PetscFunctionBegin; 20618b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2062e03ab78fSPeter Brune ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 2063f8b49ee9SBarry Smith ierr = DMSNESSetPicard(dm,b,J,ctx);CHKERRQ(ierr); 20648b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 2065e5d3d808SBarry Smith ierr = SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 20668b0a5094SBarry Smith PetscFunctionReturn(0); 20678b0a5094SBarry Smith } 20688b0a5094SBarry Smith 20697971a8bfSPeter Brune /*@C 20707971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 20717971a8bfSPeter Brune 20727971a8bfSPeter Brune Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 20737971a8bfSPeter Brune 20747971a8bfSPeter Brune Input Parameter: 20757971a8bfSPeter Brune . snes - the SNES context 20767971a8bfSPeter Brune 20777971a8bfSPeter Brune Output Parameter: 20780298fd71SBarry Smith + r - the function (or NULL) 2079f8b49ee9SBarry Smith . f - the function (or NULL); see SNESFunction for calling sequence details 2080e4357dc4SBarry Smith . Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL) 2081e4357dc4SBarry Smith . Pmat - the matrix from which the preconditioner will be constructed (or NULL) 2082f8b49ee9SBarry Smith . J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details 20830298fd71SBarry Smith - ctx - the function context (or NULL) 20847971a8bfSPeter Brune 20857971a8bfSPeter Brune Level: advanced 20867971a8bfSPeter Brune 20877971a8bfSPeter Brune .keywords: SNES, nonlinear, get, function 20887971a8bfSPeter Brune 2089e4357dc4SBarry Smith .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction 20907971a8bfSPeter Brune @*/ 2091d1e9a80fSBarry 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) 20927971a8bfSPeter Brune { 20937971a8bfSPeter Brune PetscErrorCode ierr; 20947971a8bfSPeter Brune DM dm; 20957971a8bfSPeter Brune 20967971a8bfSPeter Brune PetscFunctionBegin; 20977971a8bfSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20980298fd71SBarry Smith ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 2099e4357dc4SBarry Smith ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 21007971a8bfSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2101f8b49ee9SBarry Smith ierr = DMSNESGetPicard(dm,f,J,ctx);CHKERRQ(ierr); 21027971a8bfSPeter Brune PetscFunctionReturn(0); 21037971a8bfSPeter Brune } 21047971a8bfSPeter Brune 2105d25893d9SBarry Smith /*@C 2106d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 2107d25893d9SBarry Smith 2108d25893d9SBarry Smith Logically Collective on SNES 2109d25893d9SBarry Smith 2110d25893d9SBarry Smith Input Parameters: 2111d25893d9SBarry Smith + snes - the SNES context 2112d25893d9SBarry Smith . func - function evaluation routine 2113d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 21140298fd71SBarry Smith function evaluation routine (may be NULL) 2115d25893d9SBarry Smith 2116d25893d9SBarry Smith Calling sequence of func: 2117d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 2118d25893d9SBarry Smith 2119d25893d9SBarry Smith . f - function vector 2120d25893d9SBarry Smith - ctx - optional user-defined function context 2121d25893d9SBarry Smith 2122d25893d9SBarry Smith Level: intermediate 2123d25893d9SBarry Smith 2124d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 2125d25893d9SBarry Smith 2126d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 2127d25893d9SBarry Smith @*/ 2128d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 2129d25893d9SBarry Smith { 2130d25893d9SBarry Smith PetscFunctionBegin; 2131d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2132d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 2133d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 2134d25893d9SBarry Smith PetscFunctionReturn(0); 2135d25893d9SBarry Smith } 2136d25893d9SBarry Smith 21373ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 21381096aae1SMatthew Knepley /*@C 21391096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 21401096aae1SMatthew Knepley it assumes a zero right hand side. 21411096aae1SMatthew Knepley 21423f9fe445SBarry Smith Logically Collective on SNES 21431096aae1SMatthew Knepley 21441096aae1SMatthew Knepley Input Parameter: 21451096aae1SMatthew Knepley . snes - the SNES context 21461096aae1SMatthew Knepley 21471096aae1SMatthew Knepley Output Parameter: 21480298fd71SBarry Smith . rhs - the right hand side vector or NULL if the right hand side vector is null 21491096aae1SMatthew Knepley 21501096aae1SMatthew Knepley Level: intermediate 21511096aae1SMatthew Knepley 21521096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 21531096aae1SMatthew Knepley 215485385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 21551096aae1SMatthew Knepley @*/ 21567087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 21571096aae1SMatthew Knepley { 21581096aae1SMatthew Knepley PetscFunctionBegin; 21590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21601096aae1SMatthew Knepley PetscValidPointer(rhs,2); 216185385478SLisandro Dalcin *rhs = snes->vec_rhs; 21621096aae1SMatthew Knepley PetscFunctionReturn(0); 21631096aae1SMatthew Knepley } 21641096aae1SMatthew Knepley 21659b94acceSBarry Smith /*@ 2166bf388a1fSBarry Smith SNESComputeFunction - Calls the function that has been set with SNESSetFunction(). 21679b94acceSBarry Smith 2168c7afd0dbSLois Curfman McInnes Collective on SNES 2169c7afd0dbSLois Curfman McInnes 21709b94acceSBarry Smith Input Parameters: 2171c7afd0dbSLois Curfman McInnes + snes - the SNES context 2172c7afd0dbSLois Curfman McInnes - x - input vector 21739b94acceSBarry Smith 21749b94acceSBarry Smith Output Parameter: 21753638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 21769b94acceSBarry Smith 21771bffabb2SLois Curfman McInnes Notes: 217836851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 217936851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 218036851e7fSLois Curfman McInnes themselves. 218136851e7fSLois Curfman McInnes 218236851e7fSLois Curfman McInnes Level: developer 218336851e7fSLois Curfman McInnes 21849b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 21859b94acceSBarry Smith 2186a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 21879b94acceSBarry Smith @*/ 21887087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 21899b94acceSBarry Smith { 2190dfbe8321SBarry Smith PetscErrorCode ierr; 21916cab3a1bSJed Brown DM dm; 2192942e3340SBarry Smith DMSNES sdm; 21939b94acceSBarry Smith 21943a40ed3dSBarry Smith PetscFunctionBegin; 21950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21960700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 21970700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2198c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 2199c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 220062796dfbSBarry Smith ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr); 2201184914b5SBarry Smith 22026cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2203942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 220432f3f7c2SPeter Brune if (sdm->ops->computefunction) { 220594db00ebSBarry Smith if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2206ccf3c845SPeter Brune ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 220794db00ebSBarry Smith } 22085edff71fSBarry Smith ierr = VecLockPush(x);CHKERRQ(ierr); 2209d64ed03dSBarry Smith PetscStackPush("SNES user function"); 221022c6f798SBarry Smith ierr = (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 2211d64ed03dSBarry Smith PetscStackPop; 22125edff71fSBarry Smith ierr = VecLockPop(x);CHKERRQ(ierr); 221394db00ebSBarry Smith if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2214ccf3c845SPeter Brune ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 221594db00ebSBarry Smith } 2216c90fad12SPeter Brune } else if (snes->vec_rhs) { 2217c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 2218644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 221985385478SLisandro Dalcin if (snes->vec_rhs) { 222085385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 22213ab0aad5SBarry Smith } 2222ae3c334cSLois Curfman McInnes snes->nfuncs++; 2223422a814eSBarry Smith /* 2224422a814eSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2225422a814eSBarry Smith propagate the value to all processes 2226422a814eSBarry Smith */ 2227422a814eSBarry Smith if (snes->domainerror) { 2228422a814eSBarry Smith ierr = VecSetInf(y);CHKERRQ(ierr); 2229422a814eSBarry Smith } 22303a40ed3dSBarry Smith PetscFunctionReturn(0); 22319b94acceSBarry Smith } 22329b94acceSBarry Smith 2233c79ef259SPeter Brune /*@ 2234be95d8f1SBarry Smith SNESComputeNGS - Calls the Gauss-Seidel function that has been set with SNESSetNGS(). 2235c79ef259SPeter Brune 2236c79ef259SPeter Brune Collective on SNES 2237c79ef259SPeter Brune 2238c79ef259SPeter Brune Input Parameters: 2239c79ef259SPeter Brune + snes - the SNES context 2240c79ef259SPeter Brune . x - input vector 2241c79ef259SPeter Brune - b - rhs vector 2242c79ef259SPeter Brune 2243c79ef259SPeter Brune Output Parameter: 2244c79ef259SPeter Brune . x - new solution vector 2245c79ef259SPeter Brune 2246c79ef259SPeter Brune Notes: 2247be95d8f1SBarry Smith SNESComputeNGS() is typically used within composed nonlinear solver 2248c79ef259SPeter Brune implementations, so most users would not generally call this routine 2249c79ef259SPeter Brune themselves. 2250c79ef259SPeter Brune 2251c79ef259SPeter Brune Level: developer 2252c79ef259SPeter Brune 2253c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 2254c79ef259SPeter Brune 2255be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESComputeFunction() 2256c79ef259SPeter Brune @*/ 2257be95d8f1SBarry Smith PetscErrorCode SNESComputeNGS(SNES snes,Vec b,Vec x) 2258646217ecSPeter Brune { 2259646217ecSPeter Brune PetscErrorCode ierr; 22606cab3a1bSJed Brown DM dm; 2261942e3340SBarry Smith DMSNES sdm; 2262646217ecSPeter Brune 2263646217ecSPeter Brune PetscFunctionBegin; 2264646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2265646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2266646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 2267646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 2268646217ecSPeter Brune if (b) PetscCheckSameComm(snes,1,b,3); 226962796dfbSBarry Smith if (b) {ierr = VecValidValues(b,2,PETSC_TRUE);CHKERRQ(ierr);} 2270be95d8f1SBarry Smith ierr = PetscLogEventBegin(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr); 22716cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2272942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 227322c6f798SBarry Smith if (sdm->ops->computegs) { 22745edff71fSBarry Smith if (b) {ierr = VecLockPush(b);CHKERRQ(ierr);} 2275be95d8f1SBarry Smith PetscStackPush("SNES user NGS"); 227622c6f798SBarry Smith ierr = (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 2277646217ecSPeter Brune PetscStackPop; 22785edff71fSBarry Smith if (b) {ierr = VecLockPop(b);CHKERRQ(ierr);} 2279be95d8f1SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 2280be95d8f1SBarry Smith ierr = PetscLogEventEnd(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr); 2281646217ecSPeter Brune PetscFunctionReturn(0); 2282646217ecSPeter Brune } 2283646217ecSPeter Brune 228462fef451SLois Curfman McInnes /*@ 2285bf388a1fSBarry Smith SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian(). 228662fef451SLois Curfman McInnes 2287c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 2288c7afd0dbSLois Curfman McInnes 228962fef451SLois Curfman McInnes Input Parameters: 2290c7afd0dbSLois Curfman McInnes + snes - the SNES context 2291c7afd0dbSLois Curfman McInnes - x - input vector 229262fef451SLois Curfman McInnes 229362fef451SLois Curfman McInnes Output Parameters: 2294c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 2295d1e9a80fSBarry Smith - B - optional preconditioning matrix 2296fee21e36SBarry Smith 2297e35cf81dSBarry Smith Options Database Keys: 2298e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 2299693365a8SJed Brown . -snes_lag_jacobian <lag> 2300693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2301693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2302693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 23034c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 230494d6a431SBarry Smith . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2305c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 2306c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2307c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2308c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 23094c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 2310c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 2311c01495d3SJed Brown 2312e35cf81dSBarry Smith 231362fef451SLois Curfman McInnes Notes: 231462fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 231562fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 231662fef451SLois Curfman McInnes 231736851e7fSLois Curfman McInnes Level: developer 231836851e7fSLois Curfman McInnes 231962fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 232062fef451SLois Curfman McInnes 2321e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 232262fef451SLois Curfman McInnes @*/ 2323d1e9a80fSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B) 23249b94acceSBarry Smith { 2325dfbe8321SBarry Smith PetscErrorCode ierr; 2326ace3abfcSBarry Smith PetscBool flag; 23276cab3a1bSJed Brown DM dm; 2328942e3340SBarry Smith DMSNES sdm; 2329e0e3a89bSBarry Smith KSP ksp; 23303a40ed3dSBarry Smith 23313a40ed3dSBarry Smith PetscFunctionBegin; 23320700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23330700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2334c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 233562796dfbSBarry Smith ierr = VecValidValues(X,2,PETSC_TRUE);CHKERRQ(ierr); 23366cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2337942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 23383232da50SPeter Brune 2339ce94432eSBarry Smith if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 2340ebd3b9afSBarry Smith 2341ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2342ebd3b9afSBarry Smith 2343fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2344fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2345f5af7f23SKarl Rupp 2346fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 2347fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 2348e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 234994ab13aaSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2350ebd3b9afSBarry Smith if (flag) { 235194ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 235294ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2353ebd3b9afSBarry Smith } 2354e35cf81dSBarry Smith PetscFunctionReturn(0); 235537ec4e1aSPeter Brune } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 2356e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 235794ab13aaSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2358ebd3b9afSBarry Smith if (flag) { 235994ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 236094ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2361ebd3b9afSBarry Smith } 2362e35cf81dSBarry Smith PetscFunctionReturn(0); 2363e35cf81dSBarry Smith } 2364efd4aadfSBarry Smith if (snes->npc && snes->npcside== PC_LEFT) { 236594ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 236694ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2367d728fb7dSPeter Brune PetscFunctionReturn(0); 2368d728fb7dSPeter Brune } 2369e35cf81dSBarry Smith 237094ab13aaSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 23715edff71fSBarry Smith ierr = VecLockPush(X);CHKERRQ(ierr); 2372d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 2373d1e9a80fSBarry Smith ierr = (*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx);CHKERRQ(ierr); 2374d64ed03dSBarry Smith PetscStackPop; 23755edff71fSBarry Smith ierr = VecLockPop(X);CHKERRQ(ierr); 237694ab13aaSBarry Smith ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 2377a8054027SBarry Smith 2378e0e3a89bSBarry Smith /* the next line ensures that snes->ksp exists */ 2379e0e3a89bSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 23803b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 23813b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 2382d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 23833b4f5425SBarry Smith snes->lagpreconditioner = -1; 23843b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 2385a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2386d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 238737ec4e1aSPeter Brune } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 2388a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2389d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 2390d1e9a80fSBarry Smith } else { 2391d1e9a80fSBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner\n");CHKERRQ(ierr); 2392d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 2393a8054027SBarry Smith } 2394a8054027SBarry Smith 23956d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 239694ab13aaSBarry Smith /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 239794ab13aaSBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2398693365a8SJed Brown { 2399693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 240027b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag);CHKERRQ(ierr); 240127b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr); 240227b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr); 240327b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator);CHKERRQ(ierr); 2404693365a8SJed Brown if (flag || flag_draw || flag_contour) { 24050298fd71SBarry Smith Mat Bexp_mine = NULL,Bexp,FDexp; 2406693365a8SJed Brown PetscViewer vdraw,vstdout; 24076b3a5b13SJed Brown PetscBool flg; 2408693365a8SJed Brown if (flag_operator) { 240994ab13aaSBarry Smith ierr = MatComputeExplicitOperator(A,&Bexp_mine);CHKERRQ(ierr); 2410693365a8SJed Brown Bexp = Bexp_mine; 2411693365a8SJed Brown } else { 2412693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 241394ab13aaSBarry Smith ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 241494ab13aaSBarry Smith if (flg) Bexp = B; 2415693365a8SJed Brown else { 2416693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 241794ab13aaSBarry Smith ierr = MatComputeExplicitOperator(B,&Bexp_mine);CHKERRQ(ierr); 2418693365a8SJed Brown Bexp = Bexp_mine; 2419693365a8SJed Brown } 2420693365a8SJed Brown } 2421693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2422d1e9a80fSBarry Smith ierr = SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL);CHKERRQ(ierr); 2423ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 2424693365a8SJed Brown if (flag_draw || flag_contour) { 2425ce94432eSBarry Smith ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2426693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 24270298fd71SBarry Smith } else vdraw = NULL; 2428693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");CHKERRQ(ierr); 2429693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2430693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2431693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2432693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2433693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2434693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2435693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2436693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2437693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2438693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2439693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2440693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2441693365a8SJed Brown } 2442693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2443693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2444693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2445693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2446693365a8SJed Brown } 2447693365a8SJed Brown } 24484c30e9fbSJed Brown { 24496719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 24506719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 245127b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag);CHKERRQ(ierr); 245227b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display);CHKERRQ(ierr); 245327b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr); 245427b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr); 245527b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold);CHKERRQ(ierr); 245627b0f280SBarry Smith if (flag_threshold) { 2457c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);CHKERRQ(ierr); 2458c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);CHKERRQ(ierr); 245927b0f280SBarry Smith } 24606719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 24614c30e9fbSJed Brown Mat Bfd; 24624c30e9fbSJed Brown PetscViewer vdraw,vstdout; 2463335efc43SPeter Brune MatColoring coloring; 24644c30e9fbSJed Brown ISColoring iscoloring; 24654c30e9fbSJed Brown MatFDColoring matfdcoloring; 24664c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 24674c30e9fbSJed Brown void *funcctx; 24686719d8e4SJed Brown PetscReal norm1,norm2,normmax; 24694c30e9fbSJed Brown 247094ab13aaSBarry Smith ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 2471335efc43SPeter Brune ierr = MatColoringCreate(Bfd,&coloring);CHKERRQ(ierr); 2472335efc43SPeter Brune ierr = MatColoringSetType(coloring,MATCOLORINGSL);CHKERRQ(ierr); 2473335efc43SPeter Brune ierr = MatColoringSetFromOptions(coloring);CHKERRQ(ierr); 2474335efc43SPeter Brune ierr = MatColoringApply(coloring,&iscoloring);CHKERRQ(ierr); 2475335efc43SPeter Brune ierr = MatColoringDestroy(&coloring);CHKERRQ(ierr); 24764c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 2477f86b9fbaSHong Zhang ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2478f86b9fbaSHong Zhang ierr = MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring);CHKERRQ(ierr); 24794c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 24804c30e9fbSJed Brown 24814c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 24820298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,&func,&funcctx);CHKERRQ(ierr); 24834c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr); 24844c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 24854c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 24864c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2487d1e9a80fSBarry Smith ierr = MatFDColoringApply(Bfd,matfdcoloring,X,snes);CHKERRQ(ierr); 24884c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 24894c30e9fbSJed Brown 2490ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 24914c30e9fbSJed Brown if (flag_draw || flag_contour) { 2492ce94432eSBarry Smith ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 24934c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 24940298fd71SBarry Smith } else vdraw = NULL; 24954c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 249694ab13aaSBarry Smith if (flag_display) {ierr = MatView(B,vstdout);CHKERRQ(ierr);} 249794ab13aaSBarry Smith if (vdraw) {ierr = MatView(B,vdraw);CHKERRQ(ierr);} 24984c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 24996719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 25004c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 250194ab13aaSBarry Smith ierr = MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 25024c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 25036719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 25044c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 250557622a8eSBarry 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); 25066719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 25074c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 25084c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 25094c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 25104c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 25114c30e9fbSJed Brown } 25124c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 25136719d8e4SJed Brown 25146719d8e4SJed Brown if (flag_threshold) { 25156719d8e4SJed Brown PetscInt bs,rstart,rend,i; 251694ab13aaSBarry Smith ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr); 251794ab13aaSBarry Smith ierr = MatGetOwnershipRange(B,&rstart,&rend);CHKERRQ(ierr); 25186719d8e4SJed Brown for (i=rstart; i<rend; i++) { 25196719d8e4SJed Brown const PetscScalar *ba,*ca; 25206719d8e4SJed Brown const PetscInt *bj,*cj; 25216719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 25226719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 252394ab13aaSBarry Smith ierr = MatGetRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 25246719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 252594ab13aaSBarry Smith if (bn != cn) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 25266719d8e4SJed Brown for (j=0; j<bn; j++) { 25276719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 25286719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 25296719d8e4SJed Brown maxentrycol = bj[j]; 25306719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 25316719d8e4SJed Brown } 25326719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 25336719d8e4SJed Brown maxdiffcol = bj[j]; 25346719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 25356719d8e4SJed Brown } 25366719d8e4SJed Brown if (rdiff > maxrdiff) { 25376719d8e4SJed Brown maxrdiffcol = bj[j]; 25386719d8e4SJed Brown maxrdiff = rdiff; 25396719d8e4SJed Brown } 25406719d8e4SJed Brown } 25416719d8e4SJed Brown if (maxrdiff > 1) { 254257622a8eSBarry 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); 25436719d8e4SJed Brown for (j=0; j<bn; j++) { 25446719d8e4SJed Brown PetscReal rdiff; 25456719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 25466719d8e4SJed Brown if (rdiff > 1) { 254757622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]));CHKERRQ(ierr); 25486719d8e4SJed Brown } 25496719d8e4SJed Brown } 25506719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 25516719d8e4SJed Brown } 255294ab13aaSBarry Smith ierr = MatRestoreRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 25536719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 25546719d8e4SJed Brown } 25556719d8e4SJed Brown } 25564c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 25574c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 25584c30e9fbSJed Brown } 25594c30e9fbSJed Brown } 25603a40ed3dSBarry Smith PetscFunctionReturn(0); 25619b94acceSBarry Smith } 25629b94acceSBarry Smith 2563bf388a1fSBarry Smith /*MC 2564411c0326SBarry Smith SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES 2565bf388a1fSBarry Smith 2566bf388a1fSBarry Smith Synopsis: 2567411c0326SBarry Smith #include "petscsnes.h" 2568411c0326SBarry Smith PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 2569bf388a1fSBarry Smith 2570bf388a1fSBarry Smith + x - input vector 2571e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 2572e5d3d808SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 2573bf388a1fSBarry Smith - ctx - [optional] user-defined Jacobian context 2574bf388a1fSBarry Smith 2575878cb397SSatish Balay Level: intermediate 2576878cb397SSatish Balay 2577bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian() 2578bf388a1fSBarry Smith M*/ 2579bf388a1fSBarry Smith 25809b94acceSBarry Smith /*@C 25819b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2582044dda88SLois Curfman McInnes location to store the matrix. 25839b94acceSBarry Smith 25843f9fe445SBarry Smith Logically Collective on SNES and Mat 2585c7afd0dbSLois Curfman McInnes 25869b94acceSBarry Smith Input Parameters: 2587c7afd0dbSLois Curfman McInnes + snes - the SNES context 2588e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 2589e5d3d808SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 2590411c0326SBarry Smith . J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details 2591c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 25920298fd71SBarry Smith Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value) 25939b94acceSBarry Smith 25949b94acceSBarry Smith Notes: 2595e5d3d808SBarry Smith If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on 259616913363SBarry Smith each matrix. 259716913363SBarry Smith 2598895c21f2SBarry Smith If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null 2599895c21f2SBarry Smith space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 2600895c21f2SBarry Smith 26018d359177SBarry Smith If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument 2602a8a26c1eSJed Brown must be a MatFDColoring. 2603a8a26c1eSJed Brown 2604c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2605c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2606c3cc8fd1SJed Brown 260736851e7fSLois Curfman McInnes Level: beginner 260836851e7fSLois Curfman McInnes 26099b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 26109b94acceSBarry Smith 2611411c0326SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J, 2612411c0326SBarry Smith SNESSetPicard(), SNESJacobianFunction 26139b94acceSBarry Smith @*/ 2614d1e9a80fSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 26159b94acceSBarry Smith { 2616dfbe8321SBarry Smith PetscErrorCode ierr; 26176cab3a1bSJed Brown DM dm; 26183a7fca6bSBarry Smith 26193a40ed3dSBarry Smith PetscFunctionBegin; 26200700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2621e5d3d808SBarry Smith if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 2622e5d3d808SBarry Smith if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 2623e5d3d808SBarry Smith if (Amat) PetscCheckSameComm(snes,1,Amat,2); 2624e5d3d808SBarry Smith if (Pmat) PetscCheckSameComm(snes,1,Pmat,3); 26256cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2626f8b49ee9SBarry Smith ierr = DMSNESSetJacobian(dm,J,ctx);CHKERRQ(ierr); 2627e5d3d808SBarry Smith if (Amat) { 2628e5d3d808SBarry Smith ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 26296bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 2630f5af7f23SKarl Rupp 2631e5d3d808SBarry Smith snes->jacobian = Amat; 26323a7fca6bSBarry Smith } 2633e5d3d808SBarry Smith if (Pmat) { 2634e5d3d808SBarry Smith ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr); 26356bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2636f5af7f23SKarl Rupp 2637e5d3d808SBarry Smith snes->jacobian_pre = Pmat; 26383a7fca6bSBarry Smith } 26393a40ed3dSBarry Smith PetscFunctionReturn(0); 26409b94acceSBarry Smith } 264162fef451SLois Curfman McInnes 2642c2aafc4cSSatish Balay /*@C 2643b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2644b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2645b4fd4287SBarry Smith 2646c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2647c7afd0dbSLois Curfman McInnes 2648b4fd4287SBarry Smith Input Parameter: 2649b4fd4287SBarry Smith . snes - the nonlinear solver context 2650b4fd4287SBarry Smith 2651b4fd4287SBarry Smith Output Parameters: 2652e5d3d808SBarry Smith + Amat - location to stash (approximate) Jacobian matrix (or NULL) 2653e5d3d808SBarry Smith . Pmat - location to stash matrix used to compute the preconditioner (or NULL) 2654411c0326SBarry Smith . J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence 26550298fd71SBarry Smith - ctx - location to stash Jacobian ctx (or NULL) 2656fee21e36SBarry Smith 265736851e7fSLois Curfman McInnes Level: advanced 265836851e7fSLois Curfman McInnes 2659411c0326SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction() 2660b4fd4287SBarry Smith @*/ 2661d1e9a80fSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 2662b4fd4287SBarry Smith { 26636cab3a1bSJed Brown PetscErrorCode ierr; 26646cab3a1bSJed Brown DM dm; 2665942e3340SBarry Smith DMSNES sdm; 26666cab3a1bSJed Brown 26673a40ed3dSBarry Smith PetscFunctionBegin; 26680700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2669e5d3d808SBarry Smith if (Amat) *Amat = snes->jacobian; 2670e5d3d808SBarry Smith if (Pmat) *Pmat = snes->jacobian_pre; 26716cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2672942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2673f8b49ee9SBarry Smith if (J) *J = sdm->ops->computejacobian; 26746cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 26753a40ed3dSBarry Smith PetscFunctionReturn(0); 2676b4fd4287SBarry Smith } 2677b4fd4287SBarry Smith 26789b94acceSBarry Smith /*@ 26799b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2680272ac6f2SLois Curfman McInnes of a nonlinear solver. 26819b94acceSBarry Smith 2682fee21e36SBarry Smith Collective on SNES 2683fee21e36SBarry Smith 2684c7afd0dbSLois Curfman McInnes Input Parameters: 268570e92668SMatthew Knepley . snes - the SNES context 2686c7afd0dbSLois Curfman McInnes 2687272ac6f2SLois Curfman McInnes Notes: 2688272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2689272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2690272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2691272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2692272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2693272ac6f2SLois Curfman McInnes 269436851e7fSLois Curfman McInnes Level: advanced 269536851e7fSLois Curfman McInnes 26969b94acceSBarry Smith .keywords: SNES, nonlinear, setup 26979b94acceSBarry Smith 26989b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 26999b94acceSBarry Smith @*/ 27007087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 27019b94acceSBarry Smith { 2702dfbe8321SBarry Smith PetscErrorCode ierr; 27036cab3a1bSJed Brown DM dm; 2704942e3340SBarry Smith DMSNES sdm; 2705c35f09e5SBarry Smith SNESLineSearch linesearch, pclinesearch; 27066e2a1849SPeter Brune void *lsprectx,*lspostctx; 27076b2b7091SBarry Smith PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*); 27086b2b7091SBarry Smith PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*); 27096e2a1849SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 27106e2a1849SPeter Brune Vec f,fpc; 27116e2a1849SPeter Brune void *funcctx; 2712d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 27131eb13d49SPeter Brune void *jacctx,*appctx; 271432b97717SPeter Brune Mat j,jpre; 27153a40ed3dSBarry Smith 27163a40ed3dSBarry Smith PetscFunctionBegin; 27170700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 27184dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 27199b94acceSBarry Smith 27207adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 272104d7464bSBarry Smith ierr = SNESSetType(snes,SNESNEWTONLS);CHKERRQ(ierr); 272285385478SLisandro Dalcin } 272385385478SLisandro Dalcin 27240298fd71SBarry Smith ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr); 272558c9b817SLisandro Dalcin 27266cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2727942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2728ce94432eSBarry Smith if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object"); 272922c6f798SBarry Smith if (!sdm->ops->computejacobian) { 27308d359177SBarry Smith ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr); 273119f7a02aSBarry Smith } 27326cab3a1bSJed Brown if (!snes->vec_func) { 27336cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2734214df951SJed Brown } 2735efd51863SBarry Smith 273622d28d08SBarry Smith if (!snes->ksp) { 273722d28d08SBarry Smith ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr); 273822d28d08SBarry Smith } 2739b710008aSBarry Smith 274022d28d08SBarry Smith if (!snes->linesearch) { 27417601faf0SJed Brown ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 274222d28d08SBarry Smith } 2743ed07d7d7SPeter Brune ierr = SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction);CHKERRQ(ierr); 27449e764e56SPeter Brune 2745efd4aadfSBarry Smith if (snes->npc && (snes->npcside== PC_LEFT)) { 2746172a4300SPeter Brune snes->mf = PETSC_TRUE; 2747172a4300SPeter Brune snes->mf_operator = PETSC_FALSE; 2748172a4300SPeter Brune } 2749d8f46077SPeter Brune 2750efd4aadfSBarry Smith if (snes->npc) { 27516e2a1849SPeter Brune /* copy the DM over */ 27526e2a1849SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2753efd4aadfSBarry Smith ierr = SNESSetDM(snes->npc,dm);CHKERRQ(ierr); 27546e2a1849SPeter Brune 27556e2a1849SPeter Brune ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr); 27566e2a1849SPeter Brune ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr); 2757efd4aadfSBarry Smith ierr = SNESSetFunction(snes->npc,fpc,func,funcctx);CHKERRQ(ierr); 275832b97717SPeter Brune ierr = SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx);CHKERRQ(ierr); 2759efd4aadfSBarry Smith ierr = SNESSetJacobian(snes->npc,j,jpre,jac,jacctx);CHKERRQ(ierr); 27601eb13d49SPeter Brune ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr); 2761efd4aadfSBarry Smith ierr = SNESSetApplicationContext(snes->npc,appctx);CHKERRQ(ierr); 27626e2a1849SPeter Brune ierr = VecDestroy(&fpc);CHKERRQ(ierr); 27636e2a1849SPeter Brune 27646e2a1849SPeter Brune /* copy the function pointers over */ 2765efd4aadfSBarry Smith ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr); 27666e2a1849SPeter Brune 27676e2a1849SPeter Brune /* default to 1 iteration */ 2768efd4aadfSBarry Smith ierr = SNESSetTolerances(snes->npc,0.0,0.0,0.0,1,snes->npc->max_funcs);CHKERRQ(ierr); 2769efd4aadfSBarry Smith if (snes->npcside==PC_RIGHT) { 2770efd4aadfSBarry Smith ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 2771a9936a0cSPeter Brune } else { 2772efd4aadfSBarry Smith ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_NONE);CHKERRQ(ierr); 2773a9936a0cSPeter Brune } 2774efd4aadfSBarry Smith ierr = SNESSetFromOptions(snes->npc);CHKERRQ(ierr); 27756e2a1849SPeter Brune 27766e2a1849SPeter Brune /* copy the line search context over */ 27777601faf0SJed Brown ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 2778efd4aadfSBarry Smith ierr = SNESGetLineSearch(snes->npc,&pclinesearch);CHKERRQ(ierr); 27796b2b7091SBarry Smith ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr); 27806b2b7091SBarry Smith ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr); 27816b2b7091SBarry Smith ierr = SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);CHKERRQ(ierr); 27826b2b7091SBarry Smith ierr = SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);CHKERRQ(ierr); 27836e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 27846e2a1849SPeter Brune } 278532b97717SPeter Brune if (snes->mf) { 278632b97717SPeter Brune ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr); 278732b97717SPeter Brune } 278832b97717SPeter Brune if (snes->ops->usercompute && !snes->user) { 278932b97717SPeter Brune ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 279032b97717SPeter Brune } 27916e2a1849SPeter Brune 279237ec4e1aSPeter Brune snes->jac_iter = 0; 279337ec4e1aSPeter Brune snes->pre_iter = 0; 279437ec4e1aSPeter Brune 2795410397dcSLisandro Dalcin if (snes->ops->setup) { 2796410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2797410397dcSLisandro Dalcin } 279858c9b817SLisandro Dalcin 2799efd4aadfSBarry Smith if (snes->npc && (snes->npcside== PC_LEFT)) { 28006c67d002SPeter Brune if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 280155d4788fSPeter Brune ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 2802be95d8f1SBarry Smith ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC);CHKERRQ(ierr); 28036c67d002SPeter Brune } 28046c67d002SPeter Brune } 28056c67d002SPeter Brune 28067aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 28073a40ed3dSBarry Smith PetscFunctionReturn(0); 28089b94acceSBarry Smith } 28099b94acceSBarry Smith 281037596af1SLisandro Dalcin /*@ 281137596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 281237596af1SLisandro Dalcin 281337596af1SLisandro Dalcin Collective on SNES 281437596af1SLisandro Dalcin 281537596af1SLisandro Dalcin Input Parameter: 281637596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 281737596af1SLisandro Dalcin 2818d25893d9SBarry Smith Level: intermediate 2819d25893d9SBarry Smith 2820d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 282137596af1SLisandro Dalcin 282237596af1SLisandro Dalcin .keywords: SNES, destroy 282337596af1SLisandro Dalcin 282437596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 282537596af1SLisandro Dalcin @*/ 282637596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 282737596af1SLisandro Dalcin { 282837596af1SLisandro Dalcin PetscErrorCode ierr; 282937596af1SLisandro Dalcin 283037596af1SLisandro Dalcin PetscFunctionBegin; 283137596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2832d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2833d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 28340298fd71SBarry Smith snes->user = NULL; 2835d25893d9SBarry Smith } 2836efd4aadfSBarry Smith if (snes->npc) { 2837efd4aadfSBarry Smith ierr = SNESReset(snes->npc);CHKERRQ(ierr); 28388a23116dSBarry Smith } 28398a23116dSBarry Smith 284037596af1SLisandro Dalcin if (snes->ops->reset) { 284137596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 284237596af1SLisandro Dalcin } 28439e764e56SPeter Brune if (snes->ksp) { 28449e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 28459e764e56SPeter Brune } 28469e764e56SPeter Brune 28479e764e56SPeter Brune if (snes->linesearch) { 2848f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 28499e764e56SPeter Brune } 28509e764e56SPeter Brune 28516bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 28526bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 28536bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 28546bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 28556bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 28566bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2857c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2858c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 2859f5af7f23SKarl Rupp 286040fdac6aSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 286140fdac6aSLawrence Mitchell 286237596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 286337596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 286437596af1SLisandro Dalcin PetscFunctionReturn(0); 286537596af1SLisandro Dalcin } 286637596af1SLisandro Dalcin 286752baeb72SSatish Balay /*@ 28689b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 28699b94acceSBarry Smith with SNESCreate(). 28709b94acceSBarry Smith 2871c7afd0dbSLois Curfman McInnes Collective on SNES 2872c7afd0dbSLois Curfman McInnes 28739b94acceSBarry Smith Input Parameter: 28749b94acceSBarry Smith . snes - the SNES context 28759b94acceSBarry Smith 287636851e7fSLois Curfman McInnes Level: beginner 287736851e7fSLois Curfman McInnes 28789b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 28799b94acceSBarry Smith 288063a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 28819b94acceSBarry Smith @*/ 28826bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 28839b94acceSBarry Smith { 28846849ba73SBarry Smith PetscErrorCode ierr; 28853a40ed3dSBarry Smith 28863a40ed3dSBarry Smith PetscFunctionBegin; 28876bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 28886bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 28896bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2890d4bb536fSBarry Smith 28916bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 2892efd4aadfSBarry Smith ierr = SNESDestroy(&(*snes)->npc);CHKERRQ(ierr); 28936b8b9a38SLisandro Dalcin 2894e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 2895e04113cfSBarry Smith ierr = PetscObjectSAWsViewOff((PetscObject)*snes);CHKERRQ(ierr); 28966bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 28976d4c513bSLisandro Dalcin 2898dc822a44SJed Brown ierr = DMCoarsenHookRemove((*snes)->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,*snes);CHKERRQ(ierr); 28996bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 29006bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2901f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 29026b8b9a38SLisandro Dalcin 29036bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 29046bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 29056bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 29066b8b9a38SLisandro Dalcin } 29076bf464f9SBarry Smith if ((*snes)->conv_malloc) { 29086bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 29096bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 291058c9b817SLisandro Dalcin } 29116bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2912a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 29133a40ed3dSBarry Smith PetscFunctionReturn(0); 29149b94acceSBarry Smith } 29159b94acceSBarry Smith 29169b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 29179b94acceSBarry Smith 2918a8054027SBarry Smith /*@ 2919a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2920a8054027SBarry Smith 29213f9fe445SBarry Smith Logically Collective on SNES 2922a8054027SBarry Smith 2923a8054027SBarry Smith Input Parameters: 2924a8054027SBarry Smith + snes - the SNES context 2925a8054027SBarry 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 29263b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2927a8054027SBarry Smith 2928a8054027SBarry Smith Options Database Keys: 2929a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2930a8054027SBarry Smith 2931a8054027SBarry Smith Notes: 2932a8054027SBarry Smith The default is 1 2933a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2934a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2935a8054027SBarry Smith 2936a8054027SBarry Smith Level: intermediate 2937a8054027SBarry Smith 2938a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2939a8054027SBarry Smith 2940e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2941a8054027SBarry Smith 2942a8054027SBarry Smith @*/ 29437087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2944a8054027SBarry Smith { 2945a8054027SBarry Smith PetscFunctionBegin; 29460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2947e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2948e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2949c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2950a8054027SBarry Smith snes->lagpreconditioner = lag; 2951a8054027SBarry Smith PetscFunctionReturn(0); 2952a8054027SBarry Smith } 2953a8054027SBarry Smith 2954efd51863SBarry Smith /*@ 2955efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2956efd51863SBarry Smith 2957efd51863SBarry Smith Logically Collective on SNES 2958efd51863SBarry Smith 2959efd51863SBarry Smith Input Parameters: 2960efd51863SBarry Smith + snes - the SNES context 2961efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2962efd51863SBarry Smith 2963efd51863SBarry Smith Options Database Keys: 2964efd51863SBarry Smith . -snes_grid_sequence <steps> 2965efd51863SBarry Smith 2966efd51863SBarry Smith Level: intermediate 2967efd51863SBarry Smith 2968c0df2a02SJed Brown Notes: 2969c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2970c0df2a02SJed Brown 2971efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2972efd51863SBarry Smith 2973fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetGridSequence() 2974efd51863SBarry Smith 2975efd51863SBarry Smith @*/ 2976efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2977efd51863SBarry Smith { 2978efd51863SBarry Smith PetscFunctionBegin; 2979efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2980efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2981efd51863SBarry Smith snes->gridsequence = steps; 2982efd51863SBarry Smith PetscFunctionReturn(0); 2983efd51863SBarry Smith } 2984efd51863SBarry Smith 2985fa19ca70SBarry Smith /*@ 2986fa19ca70SBarry Smith SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does 2987fa19ca70SBarry Smith 2988fa19ca70SBarry Smith Logically Collective on SNES 2989fa19ca70SBarry Smith 2990fa19ca70SBarry Smith Input Parameter: 2991fa19ca70SBarry Smith . snes - the SNES context 2992fa19ca70SBarry Smith 2993fa19ca70SBarry Smith Output Parameter: 2994fa19ca70SBarry Smith . steps - the number of refinements to do, defaults to 0 2995fa19ca70SBarry Smith 2996fa19ca70SBarry Smith Options Database Keys: 2997fa19ca70SBarry Smith . -snes_grid_sequence <steps> 2998fa19ca70SBarry Smith 2999fa19ca70SBarry Smith Level: intermediate 3000fa19ca70SBarry Smith 3001fa19ca70SBarry Smith Notes: 3002fa19ca70SBarry Smith Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3003fa19ca70SBarry Smith 3004fa19ca70SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 3005fa19ca70SBarry Smith 3006fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetGridSequence() 3007fa19ca70SBarry Smith 3008fa19ca70SBarry Smith @*/ 3009fa19ca70SBarry Smith PetscErrorCode SNESGetGridSequence(SNES snes,PetscInt *steps) 3010fa19ca70SBarry Smith { 3011fa19ca70SBarry Smith PetscFunctionBegin; 3012fa19ca70SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3013fa19ca70SBarry Smith *steps = snes->gridsequence; 3014fa19ca70SBarry Smith PetscFunctionReturn(0); 3015fa19ca70SBarry Smith } 3016fa19ca70SBarry Smith 3017a8054027SBarry Smith /*@ 3018a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 3019a8054027SBarry Smith 30203f9fe445SBarry Smith Not Collective 3021a8054027SBarry Smith 3022a8054027SBarry Smith Input Parameter: 3023a8054027SBarry Smith . snes - the SNES context 3024a8054027SBarry Smith 3025a8054027SBarry Smith Output Parameter: 3026a8054027SBarry 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 30273b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3028a8054027SBarry Smith 3029a8054027SBarry Smith Options Database Keys: 3030a8054027SBarry Smith . -snes_lag_preconditioner <lag> 3031a8054027SBarry Smith 3032a8054027SBarry Smith Notes: 3033a8054027SBarry Smith The default is 1 3034a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3035a8054027SBarry Smith 3036a8054027SBarry Smith Level: intermediate 3037a8054027SBarry Smith 3038a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 3039a8054027SBarry Smith 3040a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 3041a8054027SBarry Smith 3042a8054027SBarry Smith @*/ 30437087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 3044a8054027SBarry Smith { 3045a8054027SBarry Smith PetscFunctionBegin; 30460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3047a8054027SBarry Smith *lag = snes->lagpreconditioner; 3048a8054027SBarry Smith PetscFunctionReturn(0); 3049a8054027SBarry Smith } 3050a8054027SBarry Smith 3051e35cf81dSBarry Smith /*@ 3052e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 3053e35cf81dSBarry Smith often the preconditioner is rebuilt. 3054e35cf81dSBarry Smith 30553f9fe445SBarry Smith Logically Collective on SNES 3056e35cf81dSBarry Smith 3057e35cf81dSBarry Smith Input Parameters: 3058e35cf81dSBarry Smith + snes - the SNES context 3059e35cf81dSBarry 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 3060fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 3061e35cf81dSBarry Smith 3062e35cf81dSBarry Smith Options Database Keys: 3063e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 3064e35cf81dSBarry Smith 3065e35cf81dSBarry Smith Notes: 3066e35cf81dSBarry Smith The default is 1 3067e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3068fe3ffe1eSBarry 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 3069fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 3070e35cf81dSBarry Smith 3071e35cf81dSBarry Smith Level: intermediate 3072e35cf81dSBarry Smith 3073e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 3074e35cf81dSBarry Smith 3075e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 3076e35cf81dSBarry Smith 3077e35cf81dSBarry Smith @*/ 30787087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 3079e35cf81dSBarry Smith { 3080e35cf81dSBarry Smith PetscFunctionBegin; 30810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3082e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3083e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3084c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 3085e35cf81dSBarry Smith snes->lagjacobian = lag; 3086e35cf81dSBarry Smith PetscFunctionReturn(0); 3087e35cf81dSBarry Smith } 3088e35cf81dSBarry Smith 3089e35cf81dSBarry Smith /*@ 3090e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 3091e35cf81dSBarry Smith 30923f9fe445SBarry Smith Not Collective 3093e35cf81dSBarry Smith 3094e35cf81dSBarry Smith Input Parameter: 3095e35cf81dSBarry Smith . snes - the SNES context 3096e35cf81dSBarry Smith 3097e35cf81dSBarry Smith Output Parameter: 3098e35cf81dSBarry 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 3099e35cf81dSBarry Smith the Jacobian is built etc. 3100e35cf81dSBarry Smith 3101e35cf81dSBarry Smith Options Database Keys: 3102e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 3103e35cf81dSBarry Smith 3104e35cf81dSBarry Smith Notes: 3105e35cf81dSBarry Smith The default is 1 3106e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3107e35cf81dSBarry Smith 3108e35cf81dSBarry Smith Level: intermediate 3109e35cf81dSBarry Smith 3110e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 3111e35cf81dSBarry Smith 3112e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 3113e35cf81dSBarry Smith 3114e35cf81dSBarry Smith @*/ 31157087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 3116e35cf81dSBarry Smith { 3117e35cf81dSBarry Smith PetscFunctionBegin; 31180700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3119e35cf81dSBarry Smith *lag = snes->lagjacobian; 3120e35cf81dSBarry Smith PetscFunctionReturn(0); 3121e35cf81dSBarry Smith } 3122e35cf81dSBarry Smith 312337ec4e1aSPeter Brune /*@ 312437ec4e1aSPeter Brune SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves 312537ec4e1aSPeter Brune 312637ec4e1aSPeter Brune Logically collective on SNES 312737ec4e1aSPeter Brune 312837ec4e1aSPeter Brune Input Parameter: 312937ec4e1aSPeter Brune + snes - the SNES context 31309d7e2deaSPeter Brune - flg - jacobian lagging persists if true 313137ec4e1aSPeter Brune 313237ec4e1aSPeter Brune Options Database Keys: 313337ec4e1aSPeter Brune . -snes_lag_jacobian_persists <flg> 313437ec4e1aSPeter Brune 313537ec4e1aSPeter Brune Notes: This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 313637ec4e1aSPeter Brune several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 313737ec4e1aSPeter Brune timesteps may present huge efficiency gains. 313837ec4e1aSPeter Brune 313937ec4e1aSPeter Brune Level: developer 314037ec4e1aSPeter Brune 3141be95d8f1SBarry Smith .keywords: SNES, nonlinear, lag 314237ec4e1aSPeter Brune 3143be95d8f1SBarry Smith .seealso: SNESSetLagPreconditionerPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC() 314437ec4e1aSPeter Brune 314537ec4e1aSPeter Brune @*/ 314637ec4e1aSPeter Brune PetscErrorCode SNESSetLagJacobianPersists(SNES snes,PetscBool flg) 314737ec4e1aSPeter Brune { 314837ec4e1aSPeter Brune PetscFunctionBegin; 314937ec4e1aSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 315037ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes,flg,2); 315137ec4e1aSPeter Brune snes->lagjac_persist = flg; 315237ec4e1aSPeter Brune PetscFunctionReturn(0); 315337ec4e1aSPeter Brune } 315437ec4e1aSPeter Brune 315537ec4e1aSPeter Brune /*@ 315637ec4e1aSPeter Brune SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple solves 315737ec4e1aSPeter Brune 315837ec4e1aSPeter Brune Logically Collective on SNES 315937ec4e1aSPeter Brune 316037ec4e1aSPeter Brune Input Parameter: 316137ec4e1aSPeter Brune + snes - the SNES context 31629d7e2deaSPeter Brune - flg - preconditioner lagging persists if true 316337ec4e1aSPeter Brune 316437ec4e1aSPeter Brune Options Database Keys: 316537ec4e1aSPeter Brune . -snes_lag_jacobian_persists <flg> 316637ec4e1aSPeter Brune 316737ec4e1aSPeter Brune Notes: This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 316837ec4e1aSPeter Brune by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 316937ec4e1aSPeter Brune several timesteps may present huge efficiency gains. 317037ec4e1aSPeter Brune 317137ec4e1aSPeter Brune Level: developer 317237ec4e1aSPeter Brune 3173be95d8f1SBarry Smith .keywords: SNES, nonlinear, lag 317437ec4e1aSPeter Brune 3175be95d8f1SBarry Smith .seealso: SNESSetLagJacobianPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC() 317637ec4e1aSPeter Brune 317737ec4e1aSPeter Brune @*/ 317837ec4e1aSPeter Brune PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg) 317937ec4e1aSPeter Brune { 318037ec4e1aSPeter Brune PetscFunctionBegin; 318137ec4e1aSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 318237ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes,flg,2); 318337ec4e1aSPeter Brune snes->lagpre_persist = flg; 318437ec4e1aSPeter Brune PetscFunctionReturn(0); 318537ec4e1aSPeter Brune } 318637ec4e1aSPeter Brune 31879b94acceSBarry Smith /*@ 3188be5caee7SBarry Smith SNESSetForceIteration - force SNESSolve() to take at least one iteration regardless of the initial residual norm 3189be5caee7SBarry Smith 3190be5caee7SBarry Smith Logically Collective on SNES 3191be5caee7SBarry Smith 3192be5caee7SBarry Smith Input Parameters: 3193be5caee7SBarry Smith + snes - the SNES context 3194be5caee7SBarry Smith - force - PETSC_TRUE require at least one iteration 3195be5caee7SBarry Smith 3196be5caee7SBarry Smith Options Database Keys: 3197be5caee7SBarry Smith . -snes_force_iteration <force> - Sets forcing an iteration 3198be5caee7SBarry Smith 3199be5caee7SBarry Smith Notes: 3200be5caee7SBarry Smith This is used sometimes with TS to prevent TS from detecting a false steady state solution 3201be5caee7SBarry Smith 3202be5caee7SBarry Smith Level: intermediate 3203be5caee7SBarry Smith 3204be5caee7SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 3205be5caee7SBarry Smith 3206be5caee7SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance() 3207be5caee7SBarry Smith @*/ 3208be5caee7SBarry Smith PetscErrorCode SNESSetForceIteration(SNES snes,PetscBool force) 3209be5caee7SBarry Smith { 3210be5caee7SBarry Smith PetscFunctionBegin; 3211be5caee7SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3212be5caee7SBarry Smith snes->forceiteration = force; 3213be5caee7SBarry Smith PetscFunctionReturn(0); 3214be5caee7SBarry Smith } 3215be5caee7SBarry Smith 3216be5caee7SBarry Smith 3217be5caee7SBarry Smith /*@ 3218d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 32199b94acceSBarry Smith 32203f9fe445SBarry Smith Logically Collective on SNES 3221c7afd0dbSLois Curfman McInnes 32229b94acceSBarry Smith Input Parameters: 3223c7afd0dbSLois Curfman McInnes + snes - the SNES context 322470441072SBarry Smith . abstol - absolute convergence tolerance 322533174efeSLois Curfman McInnes . rtol - relative convergence tolerance 32265358d0d4SBarry Smith . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 322733174efeSLois Curfman McInnes . maxit - maximum number of iterations 3228c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 3229fee21e36SBarry Smith 323033174efeSLois Curfman McInnes Options Database Keys: 323170441072SBarry Smith + -snes_atol <abstol> - Sets abstol 3232c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 3233c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 3234c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 3235c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 32369b94acceSBarry Smith 3237d7a720efSLois Curfman McInnes Notes: 32389b94acceSBarry Smith The default maximum number of iterations is 50. 32399b94acceSBarry Smith The default maximum number of function evaluations is 1000. 32409b94acceSBarry Smith 324136851e7fSLois Curfman McInnes Level: intermediate 324236851e7fSLois Curfman McInnes 324333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 32449b94acceSBarry Smith 3245be5caee7SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance(), SNESSetForceIteration() 32469b94acceSBarry Smith @*/ 32477087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 32489b94acceSBarry Smith { 32493a40ed3dSBarry Smith PetscFunctionBegin; 32500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3251c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 3252c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 3253c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 3254c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 3255c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 3256c5eb9154SBarry Smith 3257ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 325857622a8eSBarry Smith if (abstol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol); 3259ab54825eSJed Brown snes->abstol = abstol; 3260ab54825eSJed Brown } 3261ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 326257622a8eSBarry 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); 3263ab54825eSJed Brown snes->rtol = rtol; 3264ab54825eSJed Brown } 3265ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 326657622a8eSBarry Smith if (stol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol); 3267c60f73f4SPeter Brune snes->stol = stol; 3268ab54825eSJed Brown } 3269ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 3270ce94432eSBarry Smith if (maxit < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 3271ab54825eSJed Brown snes->max_its = maxit; 3272ab54825eSJed Brown } 3273ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 3274ce94432eSBarry Smith if (maxf < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 3275ab54825eSJed Brown snes->max_funcs = maxf; 3276ab54825eSJed Brown } 327788976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 32783a40ed3dSBarry Smith PetscFunctionReturn(0); 32799b94acceSBarry Smith } 32809b94acceSBarry Smith 3281e4d06f11SPatrick Farrell /*@ 3282e4d06f11SPatrick Farrell SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test. 3283e4d06f11SPatrick Farrell 3284e4d06f11SPatrick Farrell Logically Collective on SNES 3285e4d06f11SPatrick Farrell 3286e4d06f11SPatrick Farrell Input Parameters: 3287e4d06f11SPatrick Farrell + snes - the SNES context 3288e4d06f11SPatrick Farrell - divtol - the divergence tolerance. Use -1 to deactivate the test. 3289e4d06f11SPatrick Farrell 3290e4d06f11SPatrick Farrell Options Database Keys: 3291e4d06f11SPatrick Farrell + -snes_divergence_tolerance <divtol> - Sets divtol 3292e4d06f11SPatrick Farrell 3293e4d06f11SPatrick Farrell Notes: 3294e4d06f11SPatrick Farrell The default divergence tolerance is 1e4. 3295e4d06f11SPatrick Farrell 3296e4d06f11SPatrick Farrell Level: intermediate 3297e4d06f11SPatrick Farrell 3298e4d06f11SPatrick Farrell .keywords: SNES, nonlinear, set, divergence, tolerance 3299e4d06f11SPatrick Farrell 3300e4d06f11SPatrick Farrell .seealso: SNESSetTolerances(), SNESGetDivergenceTolerance 3301e4d06f11SPatrick Farrell @*/ 3302e4d06f11SPatrick Farrell PetscErrorCode SNESSetDivergenceTolerance(SNES snes,PetscReal divtol) 3303e4d06f11SPatrick Farrell { 3304e4d06f11SPatrick Farrell PetscFunctionBegin; 3305e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3306e4d06f11SPatrick Farrell PetscValidLogicalCollectiveReal(snes,divtol,2); 3307e4d06f11SPatrick Farrell 3308e4d06f11SPatrick Farrell if (divtol != PETSC_DEFAULT) { 3309e4d06f11SPatrick Farrell snes->divtol = divtol; 3310e4d06f11SPatrick Farrell } 3311e4d06f11SPatrick Farrell else { 3312e4d06f11SPatrick Farrell snes->divtol = 1.0e4; 3313e4d06f11SPatrick Farrell } 3314e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3315e4d06f11SPatrick Farrell } 3316e4d06f11SPatrick Farrell 33179b94acceSBarry Smith /*@ 331833174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 331933174efeSLois Curfman McInnes 3320c7afd0dbSLois Curfman McInnes Not Collective 3321c7afd0dbSLois Curfman McInnes 332233174efeSLois Curfman McInnes Input Parameters: 3323c7afd0dbSLois Curfman McInnes + snes - the SNES context 332485385478SLisandro Dalcin . atol - absolute convergence tolerance 332533174efeSLois Curfman McInnes . rtol - relative convergence tolerance 332633174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 332733174efeSLois Curfman McInnes of the change in the solution between steps 332833174efeSLois Curfman McInnes . maxit - maximum number of iterations 3329c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 3330fee21e36SBarry Smith 333133174efeSLois Curfman McInnes Notes: 33320298fd71SBarry Smith The user can specify NULL for any parameter that is not needed. 333333174efeSLois Curfman McInnes 333436851e7fSLois Curfman McInnes Level: intermediate 333536851e7fSLois Curfman McInnes 333633174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 333733174efeSLois Curfman McInnes 333833174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 333933174efeSLois Curfman McInnes @*/ 33407087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 334133174efeSLois Curfman McInnes { 33423a40ed3dSBarry Smith PetscFunctionBegin; 33430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 334485385478SLisandro Dalcin if (atol) *atol = snes->abstol; 334533174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 3346c60f73f4SPeter Brune if (stol) *stol = snes->stol; 334733174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 334833174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 33493a40ed3dSBarry Smith PetscFunctionReturn(0); 335033174efeSLois Curfman McInnes } 335133174efeSLois Curfman McInnes 3352e4d06f11SPatrick Farrell /*@ 3353e4d06f11SPatrick Farrell SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test. 3354e4d06f11SPatrick Farrell 3355e4d06f11SPatrick Farrell Not Collective 3356e4d06f11SPatrick Farrell 3357e4d06f11SPatrick Farrell Input Parameters: 3358e4d06f11SPatrick Farrell + snes - the SNES context 3359e4d06f11SPatrick Farrell - divtol - divergence tolerance 3360e4d06f11SPatrick Farrell 3361e4d06f11SPatrick Farrell Level: intermediate 3362e4d06f11SPatrick Farrell 3363e4d06f11SPatrick Farrell .keywords: SNES, nonlinear, get, divergence, tolerance 3364e4d06f11SPatrick Farrell 3365e4d06f11SPatrick Farrell .seealso: SNESSetDivergenceTolerance() 3366e4d06f11SPatrick Farrell @*/ 3367e4d06f11SPatrick Farrell PetscErrorCode SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol) 3368e4d06f11SPatrick Farrell { 3369e4d06f11SPatrick Farrell PetscFunctionBegin; 3370e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3371e4d06f11SPatrick Farrell if (divtol) *divtol = snes->divtol; 3372e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3373e4d06f11SPatrick Farrell } 3374e4d06f11SPatrick Farrell 337533174efeSLois Curfman McInnes /*@ 33769b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 33779b94acceSBarry Smith 33783f9fe445SBarry Smith Logically Collective on SNES 3379fee21e36SBarry Smith 3380c7afd0dbSLois Curfman McInnes Input Parameters: 3381c7afd0dbSLois Curfman McInnes + snes - the SNES context 3382c7afd0dbSLois Curfman McInnes - tol - tolerance 3383c7afd0dbSLois Curfman McInnes 33849b94acceSBarry Smith Options Database Key: 3385c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 33869b94acceSBarry Smith 338736851e7fSLois Curfman McInnes Level: intermediate 338836851e7fSLois Curfman McInnes 33899b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 33909b94acceSBarry Smith 33912492ecdbSBarry Smith .seealso: SNESSetTolerances() 33929b94acceSBarry Smith @*/ 33937087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 33949b94acceSBarry Smith { 33953a40ed3dSBarry Smith PetscFunctionBegin; 33960700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3397c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 33989b94acceSBarry Smith snes->deltatol = tol; 33993a40ed3dSBarry Smith PetscFunctionReturn(0); 34009b94acceSBarry Smith } 34019b94acceSBarry Smith 3402df9fa365SBarry Smith /* 3403df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 3404df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 3405df9fa365SBarry Smith macros instead of functions 3406df9fa365SBarry Smith */ 3407d96771aaSLisandro Dalcin PetscErrorCode SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx) 3408ce1608b8SBarry Smith { 3409dfbe8321SBarry Smith PetscErrorCode ierr; 3410ce1608b8SBarry Smith 3411ce1608b8SBarry Smith PetscFunctionBegin; 34120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3413d96771aaSLisandro Dalcin ierr = KSPMonitorLGResidualNorm((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 3414ce1608b8SBarry Smith PetscFunctionReturn(0); 3415ce1608b8SBarry Smith } 3416ce1608b8SBarry Smith 3417d96771aaSLisandro Dalcin PetscErrorCode SNESMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *lgctx) 3418df9fa365SBarry Smith { 3419dfbe8321SBarry Smith PetscErrorCode ierr; 3420df9fa365SBarry Smith 3421df9fa365SBarry Smith PetscFunctionBegin; 3422d96771aaSLisandro Dalcin ierr = KSPMonitorLGResidualNormCreate(comm,host,label,x,y,m,n,lgctx);CHKERRQ(ierr); 3423df9fa365SBarry Smith PetscFunctionReturn(0); 3424df9fa365SBarry Smith } 3425df9fa365SBarry Smith 34266ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 34276ba87a44SLisandro Dalcin 34287087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 3429b271bb04SBarry Smith { 3430b271bb04SBarry Smith PetscDrawLG lg; 3431b271bb04SBarry Smith PetscErrorCode ierr; 3432b271bb04SBarry Smith PetscReal x,y,per; 3433b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 3434b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 3435b271bb04SBarry Smith PetscDraw draw; 3436b271bb04SBarry Smith 3437459f5d12SBarry Smith PetscFunctionBegin; 34384d4332d5SBarry Smith PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4); 3439b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 3440b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3441b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3442b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 3443b271bb04SBarry Smith x = (PetscReal)n; 344477b4d14cSPeter Brune if (rnorm > 0.0) y = PetscLog10Real(rnorm); 344594c9c6d3SKarl Rupp else y = -15.0; 3446b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 34476934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3448b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 34496934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3450b271bb04SBarry Smith } 3451b271bb04SBarry Smith 3452b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 3453b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3454b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3455b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 3456b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 3457b271bb04SBarry Smith x = (PetscReal)n; 3458b271bb04SBarry Smith y = 100.0*per; 3459b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 34606934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3461b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 34626934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3463b271bb04SBarry Smith } 3464b271bb04SBarry Smith 3465b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 3466b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3467b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3468b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 3469b271bb04SBarry Smith x = (PetscReal)n; 3470b271bb04SBarry Smith y = (prev - rnorm)/prev; 3471b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 34726934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3473b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 34746934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3475b271bb04SBarry Smith } 3476b271bb04SBarry Smith 3477b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 3478b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3479b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3480b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 3481b271bb04SBarry Smith x = (PetscReal)n; 3482b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 3483b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 3484b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3485b271bb04SBarry Smith } 34866934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3487b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 34886934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3489b271bb04SBarry Smith } 3490b271bb04SBarry Smith prev = rnorm; 3491b271bb04SBarry Smith PetscFunctionReturn(0); 3492b271bb04SBarry Smith } 3493b271bb04SBarry Smith 3494228d79bcSJed Brown /*@ 3495228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 3496228d79bcSJed Brown 3497228d79bcSJed Brown Collective on SNES 3498228d79bcSJed Brown 3499228d79bcSJed Brown Input Parameters: 3500228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 3501228d79bcSJed Brown . iter - iteration number 3502228d79bcSJed Brown - rnorm - relative norm of the residual 3503228d79bcSJed Brown 3504228d79bcSJed Brown Notes: 3505228d79bcSJed Brown This routine is called by the SNES implementations. 3506228d79bcSJed Brown It does not typically need to be called by the user. 3507228d79bcSJed Brown 3508228d79bcSJed Brown Level: developer 3509228d79bcSJed Brown 3510228d79bcSJed Brown .seealso: SNESMonitorSet() 3511228d79bcSJed Brown @*/ 35127a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 35137a03ce2fSLisandro Dalcin { 35147a03ce2fSLisandro Dalcin PetscErrorCode ierr; 35157a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 35167a03ce2fSLisandro Dalcin 35177a03ce2fSLisandro Dalcin PetscFunctionBegin; 35185edff71fSBarry Smith ierr = VecLockPush(snes->vec_sol);CHKERRQ(ierr); 35197a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 35207a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 35217a03ce2fSLisandro Dalcin } 35225edff71fSBarry Smith ierr = VecLockPop(snes->vec_sol);CHKERRQ(ierr); 35237a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 35247a03ce2fSLisandro Dalcin } 35257a03ce2fSLisandro Dalcin 35269b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 35279b94acceSBarry Smith 3528bf388a1fSBarry Smith /*MC 3529bf388a1fSBarry Smith SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver 3530bf388a1fSBarry Smith 3531bf388a1fSBarry Smith Synopsis: 3532aaa7dc30SBarry Smith #include <petscsnes.h> 3533bf388a1fSBarry Smith $ PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3534bf388a1fSBarry Smith 3535bf388a1fSBarry Smith + snes - the SNES context 3536bf388a1fSBarry Smith . its - iteration number 3537bf388a1fSBarry Smith . norm - 2-norm function value (may be estimated) 3538bf388a1fSBarry Smith - mctx - [optional] monitoring context 3539bf388a1fSBarry Smith 3540878cb397SSatish Balay Level: advanced 3541878cb397SSatish Balay 3542bf388a1fSBarry Smith .seealso: SNESMonitorSet(), SNESMonitorGet() 3543bf388a1fSBarry Smith M*/ 3544bf388a1fSBarry Smith 35459b94acceSBarry Smith /*@C 3546a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 35479b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 35489b94acceSBarry Smith progress. 35499b94acceSBarry Smith 35503f9fe445SBarry Smith Logically Collective on SNES 3551fee21e36SBarry Smith 3552c7afd0dbSLois Curfman McInnes Input Parameters: 3553c7afd0dbSLois Curfman McInnes + snes - the SNES context 35546e4dcb14SBarry Smith . f - the monitor function, see SNESMonitorFunction for the calling sequence 3555b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 35560298fd71SBarry Smith monitor routine (use NULL if no context is desired) 3557b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 35580298fd71SBarry Smith (may be NULL) 35599b94acceSBarry Smith 35609665c990SLois Curfman McInnes Options Database Keys: 3561a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 35624619e776SBarry Smith . -snes_monitor_lg_residualnorm - sets line graph monitor, 3563a6570f20SBarry Smith uses SNESMonitorLGCreate() 3564cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 3565c7afd0dbSLois Curfman McInnes been hardwired into a code by 3566a6570f20SBarry Smith calls to SNESMonitorSet(), but 3567c7afd0dbSLois Curfman McInnes does not cancel those set via 3568c7afd0dbSLois Curfman McInnes the options database. 35699665c990SLois Curfman McInnes 3570639f9d9dSBarry Smith Notes: 35716bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3572a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 35736bc08f3fSLois Curfman McInnes order in which they were set. 3574639f9d9dSBarry Smith 3575025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 3576025f1a04SBarry Smith 357736851e7fSLois Curfman McInnes Level: intermediate 357836851e7fSLois Curfman McInnes 35799b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 35809b94acceSBarry Smith 3581bf388a1fSBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction 35829b94acceSBarry Smith @*/ 35836e4dcb14SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 35849b94acceSBarry Smith { 3585b90d0a6eSBarry Smith PetscInt i; 3586649052a6SBarry Smith PetscErrorCode ierr; 358778064530SBarry Smith PetscBool identical; 3588b90d0a6eSBarry Smith 35893a40ed3dSBarry Smith PetscFunctionBegin; 35900700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3591b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 359278064530SBarry Smith ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical);CHKERRQ(ierr); 359378064530SBarry Smith if (identical) PetscFunctionReturn(0); 3594649052a6SBarry Smith } 359578064530SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 35966e4dcb14SBarry Smith snes->monitor[snes->numbermonitors] = f; 3597b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3598639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 35993a40ed3dSBarry Smith PetscFunctionReturn(0); 36009b94acceSBarry Smith } 36019b94acceSBarry Smith 3602a278d85bSSatish Balay /*@ 3603a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 36045cd90555SBarry Smith 36053f9fe445SBarry Smith Logically Collective on SNES 3606c7afd0dbSLois Curfman McInnes 36075cd90555SBarry Smith Input Parameters: 36085cd90555SBarry Smith . snes - the SNES context 36095cd90555SBarry Smith 36101a480d89SAdministrator Options Database Key: 3611a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3612a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3613c7afd0dbSLois Curfman McInnes set via the options database 36145cd90555SBarry Smith 36155cd90555SBarry Smith Notes: 36165cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 36175cd90555SBarry Smith 361836851e7fSLois Curfman McInnes Level: intermediate 361936851e7fSLois Curfman McInnes 36205cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 36215cd90555SBarry Smith 3622a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 36235cd90555SBarry Smith @*/ 36247087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 36255cd90555SBarry Smith { 3626d952e501SBarry Smith PetscErrorCode ierr; 3627d952e501SBarry Smith PetscInt i; 3628d952e501SBarry Smith 36295cd90555SBarry Smith PetscFunctionBegin; 36300700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3631d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 3632d952e501SBarry Smith if (snes->monitordestroy[i]) { 36333c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3634d952e501SBarry Smith } 3635d952e501SBarry Smith } 36365cd90555SBarry Smith snes->numbermonitors = 0; 36375cd90555SBarry Smith PetscFunctionReturn(0); 36385cd90555SBarry Smith } 36395cd90555SBarry Smith 3640bf388a1fSBarry Smith /*MC 3641bf388a1fSBarry Smith SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 3642bf388a1fSBarry Smith 3643bf388a1fSBarry Smith Synopsis: 3644aaa7dc30SBarry Smith #include <petscsnes.h> 3645bf388a1fSBarry Smith $ PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3646bf388a1fSBarry Smith 3647bf388a1fSBarry Smith + snes - the SNES context 3648bf388a1fSBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3649bf388a1fSBarry Smith . cctx - [optional] convergence context 3650bf388a1fSBarry Smith . reason - reason for convergence/divergence 3651bf388a1fSBarry Smith . xnorm - 2-norm of current iterate 3652bf388a1fSBarry Smith . gnorm - 2-norm of current step 3653bf388a1fSBarry Smith - f - 2-norm of function 3654bf388a1fSBarry Smith 3655878cb397SSatish Balay Level: intermediate 3656bf388a1fSBarry Smith 3657bf388a1fSBarry Smith .seealso: SNESSetConvergenceTest(), SNESGetConvergenceTest() 3658bf388a1fSBarry Smith M*/ 3659bf388a1fSBarry Smith 36609b94acceSBarry Smith /*@C 36619b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 36629b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 36639b94acceSBarry Smith 36643f9fe445SBarry Smith Logically Collective on SNES 3665fee21e36SBarry Smith 3666c7afd0dbSLois Curfman McInnes Input Parameters: 3667c7afd0dbSLois Curfman McInnes + snes - the SNES context 3668bf388a1fSBarry Smith . SNESConvergenceTestFunction - routine to test for convergence 36690298fd71SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be NULL) 36700298fd71SBarry Smith - destroy - [optional] destructor for the context (may be NULL; NULL_FUNCTION in Fortran) 36719b94acceSBarry Smith 367236851e7fSLois Curfman McInnes Level: advanced 367336851e7fSLois Curfman McInnes 36749b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 36759b94acceSBarry Smith 3676e2a6519dSDmitry Karpeev .seealso: SNESConvergedDefault(), SNESConvergedSkip(), SNESConvergenceTestFunction 36779b94acceSBarry Smith @*/ 3678bf388a1fSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 36799b94acceSBarry Smith { 36807f7931b9SBarry Smith PetscErrorCode ierr; 36817f7931b9SBarry Smith 36823a40ed3dSBarry Smith PetscFunctionBegin; 36830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3684e2a6519dSDmitry Karpeev if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 36857f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 36867f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 36877f7931b9SBarry Smith } 3688bf388a1fSBarry Smith snes->ops->converged = SNESConvergenceTestFunction; 36897f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 369085385478SLisandro Dalcin snes->cnvP = cctx; 36913a40ed3dSBarry Smith PetscFunctionReturn(0); 36929b94acceSBarry Smith } 36939b94acceSBarry Smith 369452baeb72SSatish Balay /*@ 3695184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3696184914b5SBarry Smith 3697184914b5SBarry Smith Not Collective 3698184914b5SBarry Smith 3699184914b5SBarry Smith Input Parameter: 3700184914b5SBarry Smith . snes - the SNES context 3701184914b5SBarry Smith 3702184914b5SBarry Smith Output Parameter: 37034d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3704184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 3705184914b5SBarry Smith 37066a4d7782SBarry Smith Options Database: 37076a4d7782SBarry Smith . -snes_converged_reason - prints the reason to standard out 37086a4d7782SBarry Smith 3709184914b5SBarry Smith Level: intermediate 3710184914b5SBarry Smith 37116a4d7782SBarry Smith Notes: Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING. 3712184914b5SBarry Smith 3713184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 3714184914b5SBarry Smith 371533866048SMatthew G. Knepley .seealso: SNESSetConvergenceTest(), SNESSetConvergedReason(), SNESConvergedReason 3716184914b5SBarry Smith @*/ 37177087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3718184914b5SBarry Smith { 3719184914b5SBarry Smith PetscFunctionBegin; 37200700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37214482741eSBarry Smith PetscValidPointer(reason,2); 3722184914b5SBarry Smith *reason = snes->reason; 3723184914b5SBarry Smith PetscFunctionReturn(0); 3724184914b5SBarry Smith } 3725184914b5SBarry Smith 372633866048SMatthew G. Knepley /*@ 372733866048SMatthew G. Knepley SNESSetConvergedReason - Sets the reason the SNES iteration was stopped. 372833866048SMatthew G. Knepley 372933866048SMatthew G. Knepley Not Collective 373033866048SMatthew G. Knepley 373133866048SMatthew G. Knepley Input Parameters: 373233866048SMatthew G. Knepley + snes - the SNES context 373333866048SMatthew G. Knepley - reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 373433866048SMatthew G. Knepley manual pages for the individual convergence tests for complete lists 373533866048SMatthew G. Knepley 373633866048SMatthew G. Knepley Level: intermediate 373733866048SMatthew G. Knepley 373833866048SMatthew G. Knepley .keywords: SNES, nonlinear, set, convergence, test 373933866048SMatthew G. Knepley .seealso: SNESGetConvergedReason(), SNESSetConvergenceTest(), SNESConvergedReason 374033866048SMatthew G. Knepley @*/ 374133866048SMatthew G. Knepley PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason) 374233866048SMatthew G. Knepley { 374333866048SMatthew G. Knepley PetscFunctionBegin; 374433866048SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 374533866048SMatthew G. Knepley snes->reason = reason; 374633866048SMatthew G. Knepley PetscFunctionReturn(0); 374733866048SMatthew G. Knepley } 374833866048SMatthew G. Knepley 3749c9005455SLois Curfman McInnes /*@ 3750c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3751c9005455SLois Curfman McInnes 37523f9fe445SBarry Smith Logically Collective on SNES 3753fee21e36SBarry Smith 3754c7afd0dbSLois Curfman McInnes Input Parameters: 3755c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 37568c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3757cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3758758f92a0SBarry Smith . na - size of a and its 375964731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3760758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3761c7afd0dbSLois Curfman McInnes 3762308dcc3eSBarry Smith Notes: 37630298fd71SBarry Smith If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3764308dcc3eSBarry Smith default array of length 10000 is allocated. 3765308dcc3eSBarry Smith 3766c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3767c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3768c9005455SLois Curfman McInnes during the section of code that is being timed. 3769c9005455SLois Curfman McInnes 377036851e7fSLois Curfman McInnes Level: intermediate 377136851e7fSLois Curfman McInnes 3772c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3773758f92a0SBarry Smith 377408405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3775758f92a0SBarry Smith 3776c9005455SLois Curfman McInnes @*/ 37777087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3778c9005455SLois Curfman McInnes { 3779308dcc3eSBarry Smith PetscErrorCode ierr; 3780308dcc3eSBarry Smith 37813a40ed3dSBarry Smith PetscFunctionBegin; 37820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37837a1ec6d4SBarry Smith if (a) PetscValidScalarPointer(a,2); 3784a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 37857a1ec6d4SBarry Smith if (!a) { 3786308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 37877fdeb8b9SBarry Smith ierr = PetscCalloc1(na,&a);CHKERRQ(ierr); 37887fdeb8b9SBarry Smith ierr = PetscCalloc1(na,&its);CHKERRQ(ierr); 3789f5af7f23SKarl Rupp 3790308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3791308dcc3eSBarry Smith } 3792c9005455SLois Curfman McInnes snes->conv_hist = a; 3793758f92a0SBarry Smith snes->conv_hist_its = its; 3794758f92a0SBarry Smith snes->conv_hist_max = na; 3795a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3796758f92a0SBarry Smith snes->conv_hist_reset = reset; 3797758f92a0SBarry Smith PetscFunctionReturn(0); 3798758f92a0SBarry Smith } 3799758f92a0SBarry Smith 3800308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3801c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3802c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 380399e0435eSBarry Smith 38048cc058d9SJed Brown PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3805308dcc3eSBarry Smith { 3806308dcc3eSBarry Smith mxArray *mat; 3807308dcc3eSBarry Smith PetscInt i; 3808308dcc3eSBarry Smith PetscReal *ar; 3809308dcc3eSBarry Smith 3810308dcc3eSBarry Smith PetscFunctionBegin; 3811308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3812308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3813f5af7f23SKarl Rupp for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 3814308dcc3eSBarry Smith PetscFunctionReturn(mat); 3815308dcc3eSBarry Smith } 3816308dcc3eSBarry Smith #endif 3817308dcc3eSBarry Smith 38180c4c9dddSBarry Smith /*@C 3819758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3820758f92a0SBarry Smith 38213f9fe445SBarry Smith Not Collective 3822758f92a0SBarry Smith 3823758f92a0SBarry Smith Input Parameter: 3824758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3825758f92a0SBarry Smith 3826758f92a0SBarry Smith Output Parameters: 3827758f92a0SBarry Smith . a - array to hold history 3828758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3829758f92a0SBarry Smith negative if not converged) for each solve. 3830758f92a0SBarry Smith - na - size of a and its 3831758f92a0SBarry Smith 3832758f92a0SBarry Smith Notes: 3833758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3834758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3835758f92a0SBarry Smith 3836758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3837758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3838758f92a0SBarry Smith during the section of code that is being timed. 3839758f92a0SBarry Smith 3840758f92a0SBarry Smith Level: intermediate 3841758f92a0SBarry Smith 3842758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3843758f92a0SBarry Smith 3844758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3845758f92a0SBarry Smith 3846758f92a0SBarry Smith @*/ 38477087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3848758f92a0SBarry Smith { 3849758f92a0SBarry Smith PetscFunctionBegin; 38500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3851758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3852758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3853758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 38543a40ed3dSBarry Smith PetscFunctionReturn(0); 3855c9005455SLois Curfman McInnes } 3856c9005455SLois Curfman McInnes 3857ac226902SBarry Smith /*@C 385876b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3859eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 38607e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 386176b2cf59SMatthew Knepley 38623f9fe445SBarry Smith Logically Collective on SNES 386376b2cf59SMatthew Knepley 386476b2cf59SMatthew Knepley Input Parameters: 386576b2cf59SMatthew Knepley . snes - The nonlinear solver context 386676b2cf59SMatthew Knepley . func - The function 386776b2cf59SMatthew Knepley 386876b2cf59SMatthew Knepley Calling sequence of func: 3869b5d30489SBarry Smith . func (SNES snes, PetscInt step); 387076b2cf59SMatthew Knepley 387176b2cf59SMatthew Knepley . step - The current step of the iteration 387276b2cf59SMatthew Knepley 3873fe97e370SBarry Smith Level: advanced 3874fe97e370SBarry Smith 3875fe97e370SBarry 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() 3876fe97e370SBarry Smith This is not used by most users. 387776b2cf59SMatthew Knepley 387876b2cf59SMatthew Knepley .keywords: SNES, update 3879b5d30489SBarry Smith 38808d359177SBarry Smith .seealso SNESSetJacobian(), SNESSolve() 388176b2cf59SMatthew Knepley @*/ 38827087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 388376b2cf59SMatthew Knepley { 388476b2cf59SMatthew Knepley PetscFunctionBegin; 38850700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3886e7788613SBarry Smith snes->ops->update = func; 388776b2cf59SMatthew Knepley PetscFunctionReturn(0); 388876b2cf59SMatthew Knepley } 388976b2cf59SMatthew Knepley 38909b94acceSBarry Smith /* 38919b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 38929b94acceSBarry Smith positive parameter delta. 38939b94acceSBarry Smith 38949b94acceSBarry Smith Input Parameters: 3895c7afd0dbSLois Curfman McInnes + snes - the SNES context 38969b94acceSBarry Smith . y - approximate solution of linear system 38979b94acceSBarry Smith . fnorm - 2-norm of current function 3898c7afd0dbSLois Curfman McInnes - delta - trust region size 38999b94acceSBarry Smith 39009b94acceSBarry Smith Output Parameters: 3901c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 39029b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 39039b94acceSBarry Smith region, and exceeds zero otherwise. 3904c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 39059b94acceSBarry Smith 39069b94acceSBarry Smith Note: 390704d7464bSBarry Smith For non-trust region methods such as SNESNEWTONLS, the parameter delta 39089b94acceSBarry Smith is set to be the maximum allowable step size. 39099b94acceSBarry Smith 39109b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 39119b94acceSBarry Smith */ 3912dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 39139b94acceSBarry Smith { 3914064f8208SBarry Smith PetscReal nrm; 3915ea709b57SSatish Balay PetscScalar cnorm; 3916dfbe8321SBarry Smith PetscErrorCode ierr; 39173a40ed3dSBarry Smith 39183a40ed3dSBarry Smith PetscFunctionBegin; 39190700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 39200700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3921c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3922184914b5SBarry Smith 3923064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3924064f8208SBarry Smith if (nrm > *delta) { 3925064f8208SBarry Smith nrm = *delta/nrm; 3926064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3927064f8208SBarry Smith cnorm = nrm; 39282dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 39299b94acceSBarry Smith *ynorm = *delta; 39309b94acceSBarry Smith } else { 39319b94acceSBarry Smith *gpnorm = 0.0; 3932064f8208SBarry Smith *ynorm = nrm; 39339b94acceSBarry Smith } 39343a40ed3dSBarry Smith PetscFunctionReturn(0); 39359b94acceSBarry Smith } 39369b94acceSBarry Smith 39372a359c20SBarry Smith /*@ 39382a359c20SBarry Smith SNESReasonView - Displays the reason a SNES solve converged or diverged to a viewer 39392a359c20SBarry Smith 39402a359c20SBarry Smith Collective on SNES 39412a359c20SBarry Smith 39422a359c20SBarry Smith Parameter: 39432a359c20SBarry Smith + snes - iterative context obtained from SNESCreate() 39442a359c20SBarry Smith - viewer - the viewer to display the reason 39452a359c20SBarry Smith 39462a359c20SBarry Smith 39472a359c20SBarry Smith Options Database Keys: 39482a359c20SBarry Smith . -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 39492a359c20SBarry Smith 39502a359c20SBarry Smith Level: beginner 39512a359c20SBarry Smith 39522a359c20SBarry Smith .keywords: SNES, solve, linear system 39532a359c20SBarry Smith 39542a359c20SBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault() 39552a359c20SBarry Smith 39562a359c20SBarry Smith @*/ 39572a359c20SBarry Smith PetscErrorCode SNESReasonView(SNES snes,PetscViewer viewer) 39582a359c20SBarry Smith { 39592a359c20SBarry Smith PetscErrorCode ierr; 39602a359c20SBarry Smith PetscBool isAscii; 39612a359c20SBarry Smith 39622a359c20SBarry Smith PetscFunctionBegin; 39632a359c20SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);CHKERRQ(ierr); 39642a359c20SBarry Smith if (isAscii) { 39652a359c20SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 39662a359c20SBarry Smith if (snes->reason > 0) { 39672a359c20SBarry Smith if (((PetscObject) snes)->prefix) { 39682a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 39692a359c20SBarry Smith } else { 39702a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 39712a359c20SBarry Smith } 39722a359c20SBarry Smith } else { 39732a359c20SBarry Smith if (((PetscObject) snes)->prefix) { 39742a359c20SBarry 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); 39752a359c20SBarry Smith } else { 39762a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 39772a359c20SBarry Smith } 39782a359c20SBarry Smith } 39792a359c20SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 39802a359c20SBarry Smith } 39812a359c20SBarry Smith PetscFunctionReturn(0); 39822a359c20SBarry Smith } 39832a359c20SBarry Smith 39842a359c20SBarry Smith /*@C 39852a359c20SBarry Smith SNESReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed. 39862a359c20SBarry Smith 39872a359c20SBarry Smith Collective on SNES 39882a359c20SBarry Smith 39892a359c20SBarry Smith Input Parameters: 39902a359c20SBarry Smith . snes - the SNES object 39912a359c20SBarry Smith 39922a359c20SBarry Smith Level: intermediate 39932a359c20SBarry Smith 39942a359c20SBarry Smith @*/ 39952a359c20SBarry Smith PetscErrorCode SNESReasonViewFromOptions(SNES snes) 39962a359c20SBarry Smith { 39972a359c20SBarry Smith PetscErrorCode ierr; 39982a359c20SBarry Smith PetscViewer viewer; 39992a359c20SBarry Smith PetscBool flg; 40002a359c20SBarry Smith static PetscBool incall = PETSC_FALSE; 40012a359c20SBarry Smith PetscViewerFormat format; 40022a359c20SBarry Smith 40032a359c20SBarry Smith PetscFunctionBegin; 40042a359c20SBarry Smith if (incall) PetscFunctionReturn(0); 40052a359c20SBarry Smith incall = PETSC_TRUE; 40062a359c20SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg);CHKERRQ(ierr); 40072a359c20SBarry Smith if (flg) { 40082a359c20SBarry Smith ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 40092a359c20SBarry Smith ierr = SNESReasonView(snes,viewer);CHKERRQ(ierr); 40102a359c20SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 40112a359c20SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 40122a359c20SBarry Smith } 40132a359c20SBarry Smith incall = PETSC_FALSE; 40142a359c20SBarry Smith PetscFunctionReturn(0); 40152a359c20SBarry Smith } 40162a359c20SBarry Smith 40176ce558aeSBarry Smith /*@C 4018f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 4019f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 40209b94acceSBarry Smith 4021c7afd0dbSLois Curfman McInnes Collective on SNES 4022c7afd0dbSLois Curfman McInnes 4023b2002411SLois Curfman McInnes Input Parameters: 4024c7afd0dbSLois Curfman McInnes + snes - the SNES context 40250298fd71SBarry Smith . b - the constant part of the equation F(x) = b, or NULL to use zero. 402685385478SLisandro Dalcin - x - the solution vector. 40279b94acceSBarry Smith 4028b2002411SLois Curfman McInnes Notes: 40298ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 40308ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 40318ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 40328ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 40338ddd3da0SLois Curfman McInnes 403436851e7fSLois Curfman McInnes Level: beginner 403536851e7fSLois Curfman McInnes 40369b94acceSBarry Smith .keywords: SNES, nonlinear, solve 40379b94acceSBarry Smith 4038c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 40399b94acceSBarry Smith @*/ 40407087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 40419b94acceSBarry Smith { 4042dfbe8321SBarry Smith PetscErrorCode ierr; 4043ace3abfcSBarry Smith PetscBool flg; 4044efd51863SBarry Smith PetscInt grid; 40450298fd71SBarry Smith Vec xcreated = NULL; 4046caa4e7f2SJed Brown DM dm; 4047052efed2SBarry Smith 40483a40ed3dSBarry Smith PetscFunctionBegin; 40490700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4050a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 4051a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 40520700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 405385385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 405485385478SLisandro Dalcin 405506fc46c8SMatthew G. Knepley { 405606fc46c8SMatthew G. Knepley PetscViewer viewer; 405706fc46c8SMatthew G. Knepley PetscViewerFormat format; 405806fc46c8SMatthew G. Knepley PetscBool flg; 405906fc46c8SMatthew G. Knepley static PetscBool incall = PETSC_FALSE; 406006fc46c8SMatthew G. Knepley 406106fc46c8SMatthew G. Knepley if (!incall) { 406206fc46c8SMatthew G. Knepley ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) snes), ((PetscObject) snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg);CHKERRQ(ierr); 406306fc46c8SMatthew G. Knepley if (flg) { 406406fc46c8SMatthew G. Knepley PetscConvEst conv; 406506fc46c8SMatthew G. Knepley PetscReal alpha; /* Convergence rate of the solution error in the L_2 norm */ 406606fc46c8SMatthew G. Knepley 406706fc46c8SMatthew G. Knepley incall = PETSC_TRUE; 406806fc46c8SMatthew G. Knepley ierr = PetscConvEstCreate(PetscObjectComm((PetscObject) snes), &conv);CHKERRQ(ierr); 406906fc46c8SMatthew G. Knepley ierr = PetscConvEstSetSolver(conv, snes);CHKERRQ(ierr); 407006fc46c8SMatthew G. Knepley ierr = PetscConvEstSetFromOptions(conv);CHKERRQ(ierr); 40710955ed61SMatthew G. Knepley ierr = PetscConvEstSetUp(conv);CHKERRQ(ierr); 407206fc46c8SMatthew G. Knepley ierr = PetscConvEstGetConvRate(conv, &alpha);CHKERRQ(ierr); 407306fc46c8SMatthew G. Knepley ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr); 407406fc46c8SMatthew G. Knepley ierr = PetscConvEstRateView(conv, alpha, viewer);CHKERRQ(ierr); 407506fc46c8SMatthew G. Knepley ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 407606fc46c8SMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 407706fc46c8SMatthew G. Knepley ierr = PetscConvEstDestroy(&conv);CHKERRQ(ierr); 407806fc46c8SMatthew G. Knepley incall = PETSC_FALSE; 407906fc46c8SMatthew G. Knepley } 408006fc46c8SMatthew G. Knepley } 408106fc46c8SMatthew G. Knepley } 4082caa4e7f2SJed Brown if (!x) { 4083caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4084caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 4085a69afd8bSBarry Smith x = xcreated; 4086a69afd8bSBarry Smith } 4087ce1779c8SBarry Smith ierr = SNESViewFromOptions(snes,NULL,"-snes_view_pre");CHKERRQ(ierr); 4088f05ece33SBarry Smith 4089ce94432eSBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);} 4090efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 4091efd51863SBarry Smith 409285385478SLisandro Dalcin /* set solution vector */ 4093efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 40946bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 409585385478SLisandro Dalcin snes->vec_sol = x; 4096caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4097caa4e7f2SJed Brown 4098caa4e7f2SJed Brown /* set affine vector if provided */ 409985385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 41006bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 410185385478SLisandro Dalcin snes->vec_rhs = b; 410285385478SLisandro Dalcin 4103154060b5SMatthew G. Knepley if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 4104154060b5SMatthew 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"); 4105154060b5SMatthew G. Knepley if (!snes->vec_sol_update /* && snes->vec_sol */) { 4106154060b5SMatthew G. Knepley ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 4107154060b5SMatthew G. Knepley ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);CHKERRQ(ierr); 4108154060b5SMatthew G. Knepley } 4109154060b5SMatthew G. Knepley ierr = DMShellSetGlobalVector(dm,snes->vec_sol);CHKERRQ(ierr); 411070e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 41113f149594SLisandro Dalcin 41127eee914bSBarry Smith if (!grid) { 41137eee914bSBarry Smith if (snes->ops->computeinitialguess) { 4114d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 4115d25893d9SBarry Smith } 4116dd568438SSatish Balay } 4117d25893d9SBarry Smith 4118abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 4119971e163fSPeter Brune if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;} 4120d5e45103SBarry Smith 41213f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 41224936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 412385385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 412417186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 4125422a814eSBarry Smith snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 41263f149594SLisandro Dalcin 412737ec4e1aSPeter Brune if (snes->lagjac_persist) snes->jac_iter += snes->iter; 412837ec4e1aSPeter Brune if (snes->lagpre_persist) snes->pre_iter += snes->iter; 412937ec4e1aSPeter Brune 413027b0f280SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg);CHKERRQ(ierr); 4131da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 41322a359c20SBarry Smith ierr = SNESReasonViewFromOptions(snes);CHKERRQ(ierr); 41335968eb51SBarry Smith 4134ce94432eSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 41359c8e83a9SBarry Smith if (snes->reason < 0) break; 4136efd51863SBarry Smith if (grid < snes->gridsequence) { 4137efd51863SBarry Smith DM fine; 4138efd51863SBarry Smith Vec xnew; 4139efd51863SBarry Smith Mat interp; 4140efd51863SBarry Smith 4141ce94432eSBarry Smith ierr = DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);CHKERRQ(ierr); 4142ce94432eSBarry Smith if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 41430298fd71SBarry Smith ierr = DMCreateInterpolation(snes->dm,fine,&interp,NULL);CHKERRQ(ierr); 4144efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 4145efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 4146c833c3b5SJed Brown ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 4147efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 4148efd51863SBarry Smith x = xnew; 4149efd51863SBarry Smith 4150efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 4151efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 4152efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 4153ce94432eSBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr); 4154efd51863SBarry Smith } 4155efd51863SBarry Smith } 4156ce1779c8SBarry Smith ierr = SNESViewFromOptions(snes,NULL,"-snes_view");CHKERRQ(ierr); 4157685405a1SBarry Smith ierr = VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution");CHKERRQ(ierr); 41583f7e2da0SPeter Brune 4159a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 4160e04113cfSBarry Smith ierr = PetscObjectSAWsBlock((PetscObject)snes);CHKERRQ(ierr); 41613a40ed3dSBarry Smith PetscFunctionReturn(0); 41629b94acceSBarry Smith } 41639b94acceSBarry Smith 41649b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 41659b94acceSBarry Smith 416682bf6240SBarry Smith /*@C 41674b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 41689b94acceSBarry Smith 4169fee21e36SBarry Smith Collective on SNES 4170fee21e36SBarry Smith 4171c7afd0dbSLois Curfman McInnes Input Parameters: 4172c7afd0dbSLois Curfman McInnes + snes - the SNES context 4173454a90a3SBarry Smith - type - a known method 4174c7afd0dbSLois Curfman McInnes 4175c7afd0dbSLois Curfman McInnes Options Database Key: 4176454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 417704d7464bSBarry Smith of available methods (for instance, newtonls or newtontr) 4178ae12b187SLois Curfman McInnes 41799b94acceSBarry Smith Notes: 4180e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 418104d7464bSBarry Smith + SNESNEWTONLS - Newton's method with line search 4182c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 418304d7464bSBarry Smith . SNESNEWTONTR - Newton's method with trust region 4184c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 41859b94acceSBarry Smith 4186ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 4187ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 4188ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 4189ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 4190ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 4191ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 4192ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 4193ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 4194ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 4195b0a32e0cSBarry Smith appropriate method. 419636851e7fSLois Curfman McInnes 41978f6c3df8SBarry Smith Developer Notes: SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates 41988f6c3df8SBarry Smith the constructor in that list and calls it to create the spexific object. 41998f6c3df8SBarry Smith 420036851e7fSLois Curfman McInnes Level: intermediate 4201a703fe33SLois Curfman McInnes 4202454a90a3SBarry Smith .keywords: SNES, set, type 4203435da068SBarry Smith 42048f6c3df8SBarry Smith .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions() 4205435da068SBarry Smith 42069b94acceSBarry Smith @*/ 420719fd82e9SBarry Smith PetscErrorCode SNESSetType(SNES snes,SNESType type) 42089b94acceSBarry Smith { 4209dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 4210ace3abfcSBarry Smith PetscBool match; 42113a40ed3dSBarry Smith 42123a40ed3dSBarry Smith PetscFunctionBegin; 42130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 42144482741eSBarry Smith PetscValidCharPointer(type,2); 421582bf6240SBarry Smith 4216251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 42170f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 421892ff6ae8SBarry Smith 42191c9cd337SJed Brown ierr = PetscFunctionListFind(SNESList,type,&r);CHKERRQ(ierr); 4220e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 422175396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 4222b5c23020SJed Brown if (snes->ops->destroy) { 4223b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 42240298fd71SBarry Smith snes->ops->destroy = NULL; 4225b5c23020SJed Brown } 422675396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 422775396ef9SLisandro Dalcin snes->ops->setup = 0; 422875396ef9SLisandro Dalcin snes->ops->solve = 0; 422975396ef9SLisandro Dalcin snes->ops->view = 0; 423075396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 423175396ef9SLisandro Dalcin snes->ops->destroy = 0; 423275396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 423375396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 4234f5af7f23SKarl Rupp 4235454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 423603bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 42373a40ed3dSBarry Smith PetscFunctionReturn(0); 42389b94acceSBarry Smith } 42399b94acceSBarry Smith 42409b94acceSBarry Smith /*@C 42419a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 42429b94acceSBarry Smith 4243c7afd0dbSLois Curfman McInnes Not Collective 4244c7afd0dbSLois Curfman McInnes 42459b94acceSBarry Smith Input Parameter: 42464b0e389bSBarry Smith . snes - nonlinear solver context 42479b94acceSBarry Smith 42489b94acceSBarry Smith Output Parameter: 42493a7fca6bSBarry Smith . type - SNES method (a character string) 42509b94acceSBarry Smith 425136851e7fSLois Curfman McInnes Level: intermediate 425236851e7fSLois Curfman McInnes 4253454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 42549b94acceSBarry Smith @*/ 425519fd82e9SBarry Smith PetscErrorCode SNESGetType(SNES snes,SNESType *type) 42569b94acceSBarry Smith { 42573a40ed3dSBarry Smith PetscFunctionBegin; 42580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 42594482741eSBarry Smith PetscValidPointer(type,2); 42607adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 42613a40ed3dSBarry Smith PetscFunctionReturn(0); 42629b94acceSBarry Smith } 42639b94acceSBarry Smith 42643cd8a7caSMatthew G. Knepley /*@ 42653cd8a7caSMatthew G. Knepley SNESSetSolution - Sets the solution vector for use by the SNES routines. 42663cd8a7caSMatthew G. Knepley 42673cd8a7caSMatthew G. Knepley Logically Collective on SNES and Vec 42683cd8a7caSMatthew G. Knepley 42693cd8a7caSMatthew G. Knepley Input Parameters: 42703cd8a7caSMatthew G. Knepley + snes - the SNES context obtained from SNESCreate() 42713cd8a7caSMatthew G. Knepley - u - the solution vector 42723cd8a7caSMatthew G. Knepley 42733cd8a7caSMatthew G. Knepley Level: beginner 42743cd8a7caSMatthew G. Knepley 42753cd8a7caSMatthew G. Knepley .keywords: SNES, set, solution 42763cd8a7caSMatthew G. Knepley @*/ 42773cd8a7caSMatthew G. Knepley PetscErrorCode SNESSetSolution(SNES snes, Vec u) 42783cd8a7caSMatthew G. Knepley { 42793cd8a7caSMatthew G. Knepley DM dm; 42803cd8a7caSMatthew G. Knepley PetscErrorCode ierr; 42813cd8a7caSMatthew G. Knepley 42823cd8a7caSMatthew G. Knepley PetscFunctionBegin; 42833cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 42843cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 42853cd8a7caSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) u);CHKERRQ(ierr); 42863cd8a7caSMatthew G. Knepley ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 42873cd8a7caSMatthew G. Knepley 42883cd8a7caSMatthew G. Knepley snes->vec_sol = u; 42893cd8a7caSMatthew G. Knepley 42903cd8a7caSMatthew G. Knepley ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 42913cd8a7caSMatthew G. Knepley ierr = DMShellSetGlobalVector(dm, u);CHKERRQ(ierr); 42923cd8a7caSMatthew G. Knepley PetscFunctionReturn(0); 42933cd8a7caSMatthew G. Knepley } 42943cd8a7caSMatthew G. Knepley 429552baeb72SSatish Balay /*@ 42969b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 4297c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 42989b94acceSBarry Smith 4299c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4300c7afd0dbSLois Curfman McInnes 43019b94acceSBarry Smith Input Parameter: 43029b94acceSBarry Smith . snes - the SNES context 43039b94acceSBarry Smith 43049b94acceSBarry Smith Output Parameter: 43059b94acceSBarry Smith . x - the solution 43069b94acceSBarry Smith 430770e92668SMatthew Knepley Level: intermediate 430836851e7fSLois Curfman McInnes 43099b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 43109b94acceSBarry Smith 431185385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 43129b94acceSBarry Smith @*/ 43137087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 43149b94acceSBarry Smith { 43153a40ed3dSBarry Smith PetscFunctionBegin; 43160700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 43174482741eSBarry Smith PetscValidPointer(x,2); 431885385478SLisandro Dalcin *x = snes->vec_sol; 431970e92668SMatthew Knepley PetscFunctionReturn(0); 432070e92668SMatthew Knepley } 432170e92668SMatthew Knepley 432252baeb72SSatish Balay /*@ 43239b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 43249b94acceSBarry Smith stored. 43259b94acceSBarry Smith 4326c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4327c7afd0dbSLois Curfman McInnes 43289b94acceSBarry Smith Input Parameter: 43299b94acceSBarry Smith . snes - the SNES context 43309b94acceSBarry Smith 43319b94acceSBarry Smith Output Parameter: 43329b94acceSBarry Smith . x - the solution update 43339b94acceSBarry Smith 433436851e7fSLois Curfman McInnes Level: advanced 433536851e7fSLois Curfman McInnes 43369b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 43379b94acceSBarry Smith 433885385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 43399b94acceSBarry Smith @*/ 43407087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 43419b94acceSBarry Smith { 43423a40ed3dSBarry Smith PetscFunctionBegin; 43430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 43444482741eSBarry Smith PetscValidPointer(x,2); 434585385478SLisandro Dalcin *x = snes->vec_sol_update; 43463a40ed3dSBarry Smith PetscFunctionReturn(0); 43479b94acceSBarry Smith } 43489b94acceSBarry Smith 43499b94acceSBarry Smith /*@C 43503638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 43519b94acceSBarry Smith 4352a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 4353c7afd0dbSLois Curfman McInnes 43549b94acceSBarry Smith Input Parameter: 43559b94acceSBarry Smith . snes - the SNES context 43569b94acceSBarry Smith 43579b94acceSBarry Smith Output Parameter: 43580298fd71SBarry Smith + r - the vector that is used to store residuals (or NULL if you don't want it) 4359f8b49ee9SBarry Smith . f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details 43600298fd71SBarry Smith - ctx - the function context (or NULL if you don't want it) 43619b94acceSBarry Smith 436236851e7fSLois Curfman McInnes Level: advanced 436336851e7fSLois Curfman McInnes 4364a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 43659b94acceSBarry Smith 4366bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction 43679b94acceSBarry Smith @*/ 4368f8b49ee9SBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx) 43699b94acceSBarry Smith { 4370a63bb30eSJed Brown PetscErrorCode ierr; 43716cab3a1bSJed Brown DM dm; 4372a63bb30eSJed Brown 43733a40ed3dSBarry Smith PetscFunctionBegin; 43740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4375a63bb30eSJed Brown if (r) { 4376a63bb30eSJed Brown if (!snes->vec_func) { 4377a63bb30eSJed Brown if (snes->vec_rhs) { 4378a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 4379a63bb30eSJed Brown } else if (snes->vec_sol) { 4380a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 4381a63bb30eSJed Brown } else if (snes->dm) { 4382a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 4383a63bb30eSJed Brown } 4384a63bb30eSJed Brown } 4385a63bb30eSJed Brown *r = snes->vec_func; 4386a63bb30eSJed Brown } 43876cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4388f8b49ee9SBarry Smith ierr = DMSNESGetFunction(dm,f,ctx);CHKERRQ(ierr); 43893a40ed3dSBarry Smith PetscFunctionReturn(0); 43909b94acceSBarry Smith } 43919b94acceSBarry Smith 4392c79ef259SPeter Brune /*@C 4393be95d8f1SBarry Smith SNESGetNGS - Returns the NGS function and context. 4394c79ef259SPeter Brune 4395c79ef259SPeter Brune Input Parameter: 4396c79ef259SPeter Brune . snes - the SNES context 4397c79ef259SPeter Brune 4398c79ef259SPeter Brune Output Parameter: 4399be95d8f1SBarry Smith + f - the function (or NULL) see SNESNGSFunction for details 44000298fd71SBarry Smith - ctx - the function context (or NULL) 4401c79ef259SPeter Brune 4402c79ef259SPeter Brune Level: advanced 4403c79ef259SPeter Brune 4404c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 4405c79ef259SPeter Brune 4406be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetFunction() 4407c79ef259SPeter Brune @*/ 4408c79ef259SPeter Brune 4409be95d8f1SBarry Smith PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx) 4410646217ecSPeter Brune { 44116cab3a1bSJed Brown PetscErrorCode ierr; 44126cab3a1bSJed Brown DM dm; 44136cab3a1bSJed Brown 4414646217ecSPeter Brune PetscFunctionBegin; 4415646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 44166cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4417be95d8f1SBarry Smith ierr = DMSNESGetNGS(dm,f,ctx);CHKERRQ(ierr); 4418646217ecSPeter Brune PetscFunctionReturn(0); 4419646217ecSPeter Brune } 4420646217ecSPeter Brune 44213c7409f5SSatish Balay /*@C 44223c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 4423d850072dSLois Curfman McInnes SNES options in the database. 44243c7409f5SSatish Balay 44253f9fe445SBarry Smith Logically Collective on SNES 4426fee21e36SBarry Smith 4427c7afd0dbSLois Curfman McInnes Input Parameter: 4428c7afd0dbSLois Curfman McInnes + snes - the SNES context 4429c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4430c7afd0dbSLois Curfman McInnes 4431d850072dSLois Curfman McInnes Notes: 4432a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4433c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4434d850072dSLois Curfman McInnes 443536851e7fSLois Curfman McInnes Level: advanced 443636851e7fSLois Curfman McInnes 44373c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 4438a86d99e1SLois Curfman McInnes 4439a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 44403c7409f5SSatish Balay @*/ 44417087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 44423c7409f5SSatish Balay { 4443dfbe8321SBarry Smith PetscErrorCode ierr; 44443c7409f5SSatish Balay 44453a40ed3dSBarry Smith PetscFunctionBegin; 44460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4447639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 44481cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 444935f5d045SPeter Brune if (snes->linesearch) { 44507601faf0SJed Brown ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 445108b6c495SPeter Brune ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 445235f5d045SPeter Brune } 445335f5d045SPeter Brune ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 44543a40ed3dSBarry Smith PetscFunctionReturn(0); 44553c7409f5SSatish Balay } 44563c7409f5SSatish Balay 44573c7409f5SSatish Balay /*@C 4458f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 4459d850072dSLois Curfman McInnes SNES options in the database. 44603c7409f5SSatish Balay 44613f9fe445SBarry Smith Logically Collective on SNES 4462fee21e36SBarry Smith 4463c7afd0dbSLois Curfman McInnes Input Parameters: 4464c7afd0dbSLois Curfman McInnes + snes - the SNES context 4465c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4466c7afd0dbSLois Curfman McInnes 4467d850072dSLois Curfman McInnes Notes: 4468a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4469c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4470d850072dSLois Curfman McInnes 447136851e7fSLois Curfman McInnes Level: advanced 447236851e7fSLois Curfman McInnes 44733c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 4474a86d99e1SLois Curfman McInnes 4475a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 44763c7409f5SSatish Balay @*/ 44777087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 44783c7409f5SSatish Balay { 4479dfbe8321SBarry Smith PetscErrorCode ierr; 44803c7409f5SSatish Balay 44813a40ed3dSBarry Smith PetscFunctionBegin; 44820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4483639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 44841cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 448535f5d045SPeter Brune if (snes->linesearch) { 44867601faf0SJed Brown ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 448708b6c495SPeter Brune ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 448835f5d045SPeter Brune } 448935f5d045SPeter Brune ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 44903a40ed3dSBarry Smith PetscFunctionReturn(0); 44913c7409f5SSatish Balay } 44923c7409f5SSatish Balay 44939ab63eb5SSatish Balay /*@C 44943c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 44953c7409f5SSatish Balay SNES options in the database. 44963c7409f5SSatish Balay 4497c7afd0dbSLois Curfman McInnes Not Collective 4498c7afd0dbSLois Curfman McInnes 44993c7409f5SSatish Balay Input Parameter: 45003c7409f5SSatish Balay . snes - the SNES context 45013c7409f5SSatish Balay 45023c7409f5SSatish Balay Output Parameter: 45033c7409f5SSatish Balay . prefix - pointer to the prefix string used 45043c7409f5SSatish Balay 45054ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 45069ab63eb5SSatish Balay sufficient length to hold the prefix. 45079ab63eb5SSatish Balay 450836851e7fSLois Curfman McInnes Level: advanced 450936851e7fSLois Curfman McInnes 45103c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 4511a86d99e1SLois Curfman McInnes 4512a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 45133c7409f5SSatish Balay @*/ 45147087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 45153c7409f5SSatish Balay { 4516dfbe8321SBarry Smith PetscErrorCode ierr; 45173c7409f5SSatish Balay 45183a40ed3dSBarry Smith PetscFunctionBegin; 45190700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4520639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 45213a40ed3dSBarry Smith PetscFunctionReturn(0); 45223c7409f5SSatish Balay } 45233c7409f5SSatish Balay 4524b2002411SLois Curfman McInnes 45253cea93caSBarry Smith /*@C 45261c84c290SBarry Smith SNESRegister - Adds a method to the nonlinear solver package. 45271c84c290SBarry Smith 45281c84c290SBarry Smith Not collective 45291c84c290SBarry Smith 45301c84c290SBarry Smith Input Parameters: 45311c84c290SBarry Smith + name_solver - name of a new user-defined solver 45321c84c290SBarry Smith - routine_create - routine to create method context 45331c84c290SBarry Smith 45341c84c290SBarry Smith Notes: 45351c84c290SBarry Smith SNESRegister() may be called multiple times to add several user-defined solvers. 45361c84c290SBarry Smith 45371c84c290SBarry Smith Sample usage: 45381c84c290SBarry Smith .vb 4539bdf89e91SBarry Smith SNESRegister("my_solver",MySolverCreate); 45401c84c290SBarry Smith .ve 45411c84c290SBarry Smith 45421c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 45431c84c290SBarry Smith $ SNESSetType(snes,"my_solver") 45441c84c290SBarry Smith or at runtime via the option 45451c84c290SBarry Smith $ -snes_type my_solver 45461c84c290SBarry Smith 45471c84c290SBarry Smith Level: advanced 45481c84c290SBarry Smith 45491c84c290SBarry Smith Note: If your function is not being put into a shared library then use SNESRegister() instead 45501c84c290SBarry Smith 45511c84c290SBarry Smith .keywords: SNES, nonlinear, register 45521c84c290SBarry Smith 45531c84c290SBarry Smith .seealso: SNESRegisterAll(), SNESRegisterDestroy() 45543cea93caSBarry Smith 45557f6c08e0SMatthew Knepley Level: advanced 45563cea93caSBarry Smith @*/ 4557bdf89e91SBarry Smith PetscErrorCode SNESRegister(const char sname[],PetscErrorCode (*function)(SNES)) 4558b2002411SLois Curfman McInnes { 4559dfbe8321SBarry Smith PetscErrorCode ierr; 4560b2002411SLois Curfman McInnes 4561b2002411SLois Curfman McInnes PetscFunctionBegin; 4562a240a19fSJed Brown ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr); 4563b2002411SLois Curfman McInnes PetscFunctionReturn(0); 4564b2002411SLois Curfman McInnes } 4565da9b6338SBarry Smith 45667087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 4567da9b6338SBarry Smith { 4568dfbe8321SBarry Smith PetscErrorCode ierr; 456977431f27SBarry Smith PetscInt N,i,j; 4570da9b6338SBarry Smith Vec u,uh,fh; 4571da9b6338SBarry Smith PetscScalar value; 4572da9b6338SBarry Smith PetscReal norm; 4573da9b6338SBarry Smith 4574da9b6338SBarry Smith PetscFunctionBegin; 4575da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 4576da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 4577da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 4578da9b6338SBarry Smith 4579da9b6338SBarry Smith /* currently only works for sequential */ 458022d28d08SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");CHKERRQ(ierr); 4581da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 4582da9b6338SBarry Smith for (i=0; i<N; i++) { 4583da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 458477431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 4585da9b6338SBarry Smith for (j=-10; j<11; j++) { 45868b49ba18SBarry Smith value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0); 4587da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 45883ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 4589da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 459077431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 4591da9b6338SBarry Smith value = -value; 4592da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 4593da9b6338SBarry Smith } 4594da9b6338SBarry Smith } 45956bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 45966bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 4597da9b6338SBarry Smith PetscFunctionReturn(0); 4598da9b6338SBarry Smith } 459971f87433Sdalcinl 460071f87433Sdalcinl /*@ 4601fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 460271f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 460371f87433Sdalcinl Newton method. 460471f87433Sdalcinl 46053f9fe445SBarry Smith Logically Collective on SNES 460671f87433Sdalcinl 460771f87433Sdalcinl Input Parameters: 460871f87433Sdalcinl + snes - SNES context 460971f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 461071f87433Sdalcinl 461164ba62caSBarry Smith Options Database: 461264ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 461364ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 461464ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 461564ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 461664ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 461764ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 461864ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 461964ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 462064ba62caSBarry Smith 462171f87433Sdalcinl Notes: 462271f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 462371f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 462471f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 462571f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 462671f87433Sdalcinl solver. 462771f87433Sdalcinl 462871f87433Sdalcinl Level: advanced 462971f87433Sdalcinl 463071f87433Sdalcinl Reference: 463171f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 463271f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 463371f87433Sdalcinl 463471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 463571f87433Sdalcinl 4636fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 463771f87433Sdalcinl @*/ 46387087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 463971f87433Sdalcinl { 464071f87433Sdalcinl PetscFunctionBegin; 46410700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4642acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 464371f87433Sdalcinl snes->ksp_ewconv = flag; 464471f87433Sdalcinl PetscFunctionReturn(0); 464571f87433Sdalcinl } 464671f87433Sdalcinl 464771f87433Sdalcinl /*@ 4648fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 464971f87433Sdalcinl for computing relative tolerance for linear solvers within an 465071f87433Sdalcinl inexact Newton method. 465171f87433Sdalcinl 465271f87433Sdalcinl Not Collective 465371f87433Sdalcinl 465471f87433Sdalcinl Input Parameter: 465571f87433Sdalcinl . snes - SNES context 465671f87433Sdalcinl 465771f87433Sdalcinl Output Parameter: 465871f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 465971f87433Sdalcinl 466071f87433Sdalcinl Notes: 466171f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 466271f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 466371f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 466471f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 466571f87433Sdalcinl solver. 466671f87433Sdalcinl 466771f87433Sdalcinl Level: advanced 466871f87433Sdalcinl 466971f87433Sdalcinl Reference: 467071f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 467171f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 467271f87433Sdalcinl 467371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 467471f87433Sdalcinl 4675fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 467671f87433Sdalcinl @*/ 46777087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 467871f87433Sdalcinl { 467971f87433Sdalcinl PetscFunctionBegin; 46800700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 468171f87433Sdalcinl PetscValidPointer(flag,2); 468271f87433Sdalcinl *flag = snes->ksp_ewconv; 468371f87433Sdalcinl PetscFunctionReturn(0); 468471f87433Sdalcinl } 468571f87433Sdalcinl 468671f87433Sdalcinl /*@ 4687fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 468871f87433Sdalcinl convergence criteria for the linear solvers within an inexact 468971f87433Sdalcinl Newton method. 469071f87433Sdalcinl 46913f9fe445SBarry Smith Logically Collective on SNES 469271f87433Sdalcinl 469371f87433Sdalcinl Input Parameters: 469471f87433Sdalcinl + snes - SNES context 469571f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 469671f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 469771f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 469871f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 469971f87433Sdalcinl (0 <= gamma2 <= 1) 470071f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 470171f87433Sdalcinl . alpha2 - power for safeguard 470271f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 470371f87433Sdalcinl 470471f87433Sdalcinl Note: 470571f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 470671f87433Sdalcinl 470771f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 470871f87433Sdalcinl 470971f87433Sdalcinl Level: advanced 471071f87433Sdalcinl 471171f87433Sdalcinl Reference: 471271f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 471371f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 471471f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 471571f87433Sdalcinl 471671f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 471771f87433Sdalcinl 4718fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 471971f87433Sdalcinl @*/ 4720f5af7f23SKarl Rupp PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 472171f87433Sdalcinl { 4722fa9f3622SBarry Smith SNESKSPEW *kctx; 47235fd66863SKarl Rupp 472471f87433Sdalcinl PetscFunctionBegin; 47250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4726fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4727e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4728c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 4729c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4730c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4731c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 4732c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 4733c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 4734c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 473571f87433Sdalcinl 473671f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 473771f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 473871f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 473971f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 474071f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 474171f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 474271f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 474371f87433Sdalcinl 4744f23aa3ddSBarry 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); 474557622a8eSBarry 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); 474657622a8eSBarry 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); 474757622a8eSBarry 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); 474857622a8eSBarry 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); 474957622a8eSBarry 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); 475071f87433Sdalcinl PetscFunctionReturn(0); 475171f87433Sdalcinl } 475271f87433Sdalcinl 475371f87433Sdalcinl /*@ 4754fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 475571f87433Sdalcinl convergence criteria for the linear solvers within an inexact 475671f87433Sdalcinl Newton method. 475771f87433Sdalcinl 475871f87433Sdalcinl Not Collective 475971f87433Sdalcinl 476071f87433Sdalcinl Input Parameters: 476171f87433Sdalcinl snes - SNES context 476271f87433Sdalcinl 476371f87433Sdalcinl Output Parameters: 476471f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 476571f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 476671f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 4767bf388a1fSBarry Smith . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 476871f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 476971f87433Sdalcinl . alpha2 - power for safeguard 477071f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 477171f87433Sdalcinl 477271f87433Sdalcinl Level: advanced 477371f87433Sdalcinl 477471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 477571f87433Sdalcinl 4776fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 477771f87433Sdalcinl @*/ 4778bf388a1fSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 477971f87433Sdalcinl { 4780fa9f3622SBarry Smith SNESKSPEW *kctx; 47815fd66863SKarl Rupp 478271f87433Sdalcinl PetscFunctionBegin; 47830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4784fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4785e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 478671f87433Sdalcinl if (version) *version = kctx->version; 478771f87433Sdalcinl if (rtol_0) *rtol_0 = kctx->rtol_0; 478871f87433Sdalcinl if (rtol_max) *rtol_max = kctx->rtol_max; 478971f87433Sdalcinl if (gamma) *gamma = kctx->gamma; 479071f87433Sdalcinl if (alpha) *alpha = kctx->alpha; 479171f87433Sdalcinl if (alpha2) *alpha2 = kctx->alpha2; 479271f87433Sdalcinl if (threshold) *threshold = kctx->threshold; 479371f87433Sdalcinl PetscFunctionReturn(0); 479471f87433Sdalcinl } 479571f87433Sdalcinl 4796d5378b5fSDmitry Karpeev PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 479771f87433Sdalcinl { 479871f87433Sdalcinl PetscErrorCode ierr; 4799fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 480071f87433Sdalcinl PetscReal rtol = PETSC_DEFAULT,stol; 480171f87433Sdalcinl 480271f87433Sdalcinl PetscFunctionBegin; 4803d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 480430058271SDmitry Karpeev if (!snes->iter) { 480530058271SDmitry Karpeev rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 480630058271SDmitry Karpeev ierr = VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);CHKERRQ(ierr); 480730058271SDmitry Karpeev } 4808f5af7f23SKarl Rupp else { 480971f87433Sdalcinl if (kctx->version == 1) { 481071f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 481171f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 481285ec1a3cSBarry Smith stol = PetscPowReal(kctx->rtol_last,kctx->alpha2); 481371f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 481471f87433Sdalcinl } else if (kctx->version == 2) { 481585ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 481685ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha); 481771f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 481871f87433Sdalcinl } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 481985ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 482071f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 482185ec1a3cSBarry Smith stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha); 482271f87433Sdalcinl stol = PetscMax(rtol,stol); 482371f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 482471f87433Sdalcinl /* safeguard: avoid oversolving */ 482530058271SDmitry Karpeev stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm; 482671f87433Sdalcinl stol = PetscMax(rtol,stol); 482771f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4828e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 482971f87433Sdalcinl } 483071f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 483171f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 483271f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 483357622a8eSBarry Smith ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);CHKERRQ(ierr); 483471f87433Sdalcinl PetscFunctionReturn(0); 483571f87433Sdalcinl } 483671f87433Sdalcinl 4837d5378b5fSDmitry Karpeev PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 483871f87433Sdalcinl { 483971f87433Sdalcinl PetscErrorCode ierr; 4840fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 484171f87433Sdalcinl PCSide pcside; 484271f87433Sdalcinl Vec lres; 484371f87433Sdalcinl 484471f87433Sdalcinl PetscFunctionBegin; 4845d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 484671f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 484771dbe336SPeter Brune kctx->norm_last = snes->norm; 484871f87433Sdalcinl if (kctx->version == 1) { 48494f00ce20SMatthew G. Knepley PC pc; 48504f00ce20SMatthew G. Knepley PetscBool isNone; 48514f00ce20SMatthew G. Knepley 48524f00ce20SMatthew G. Knepley ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); 48534f00ce20SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);CHKERRQ(ierr); 4854b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 48554f00ce20SMatthew G. Knepley if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 485671f87433Sdalcinl /* KSP residual is true linear residual */ 485771f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 485871f87433Sdalcinl } else { 485971f87433Sdalcinl /* KSP residual is preconditioned residual */ 486071f87433Sdalcinl /* compute true linear residual norm */ 486171f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 486271f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 486371f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 486471f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 48656bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 486671f87433Sdalcinl } 486771f87433Sdalcinl } 486871f87433Sdalcinl PetscFunctionReturn(0); 486971f87433Sdalcinl } 487071f87433Sdalcinl 4871d4211eb9SBarry Smith /*@ 4872d4211eb9SBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 4873d4211eb9SBarry Smith 4874d4211eb9SBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 4875d4211eb9SBarry Smith 4876d4211eb9SBarry Smith Input Parameter: 4877d4211eb9SBarry Smith . snes - the SNES context 4878d4211eb9SBarry Smith 4879d4211eb9SBarry Smith Output Parameter: 4880d4211eb9SBarry Smith . ksp - the KSP context 4881d4211eb9SBarry Smith 4882d4211eb9SBarry Smith Notes: 4883d4211eb9SBarry Smith The user can then directly manipulate the KSP context to set various 4884d4211eb9SBarry Smith options, etc. Likewise, the user can then extract and manipulate the 4885d4211eb9SBarry Smith PC contexts as well. 4886d4211eb9SBarry Smith 4887d4211eb9SBarry Smith Level: beginner 4888d4211eb9SBarry Smith 4889d4211eb9SBarry Smith .keywords: SNES, nonlinear, get, KSP, context 4890d4211eb9SBarry Smith 4891d4211eb9SBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 4892d4211eb9SBarry Smith @*/ 4893d4211eb9SBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 489471f87433Sdalcinl { 489571f87433Sdalcinl PetscErrorCode ierr; 489671f87433Sdalcinl 489771f87433Sdalcinl PetscFunctionBegin; 4898d4211eb9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4899d4211eb9SBarry Smith PetscValidPointer(ksp,2); 4900d4211eb9SBarry Smith 4901d4211eb9SBarry Smith if (!snes->ksp) { 4902a5c2985bSBarry Smith PetscBool monitor = PETSC_FALSE; 4903a5c2985bSBarry Smith 4904d4211eb9SBarry Smith ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr); 4905d4211eb9SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 49063bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);CHKERRQ(ierr); 4907d4211eb9SBarry Smith 4908d5378b5fSDmitry Karpeev ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);CHKERRQ(ierr); 4909d5378b5fSDmitry Karpeev ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);CHKERRQ(ierr); 4910a5c2985bSBarry Smith 4911c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes",&monitor,NULL);CHKERRQ(ierr); 4912a5c2985bSBarry Smith if (monitor) { 4913a5c2985bSBarry Smith ierr = KSPMonitorSet(snes->ksp,KSPMonitorSNES,snes,NULL);CHKERRQ(ierr); 4914a5c2985bSBarry Smith } 4915e5f7ee39SBarry Smith monitor = PETSC_FALSE; 4916c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes_lg",&monitor,NULL);CHKERRQ(ierr); 4917e5f7ee39SBarry Smith if (monitor) { 4918e5f7ee39SBarry Smith PetscObject *objs; 49198b0b5a47SLisandro Dalcin ierr = KSPMonitorSNESLGResidualNormCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,600,&objs);CHKERRQ(ierr); 4920e5f7ee39SBarry Smith objs[0] = (PetscObject) snes; 4921e5f7ee39SBarry Smith ierr = KSPMonitorSet(snes->ksp,(PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*))KSPMonitorSNESLGResidualNorm,objs,(PetscErrorCode (*)(void**))KSPMonitorSNESLGResidualNormDestroy);CHKERRQ(ierr); 4922e5f7ee39SBarry Smith } 4923d4211eb9SBarry Smith } 4924d4211eb9SBarry Smith *ksp = snes->ksp; 492571f87433Sdalcinl PetscFunctionReturn(0); 492671f87433Sdalcinl } 49276c699258SBarry Smith 4928d4211eb9SBarry Smith 4929af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 49306c699258SBarry Smith /*@ 49312a808120SBarry Smith SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners 49326c699258SBarry Smith 49333f9fe445SBarry Smith Logically Collective on SNES 49346c699258SBarry Smith 49356c699258SBarry Smith Input Parameters: 49362a808120SBarry Smith + snes - the nonlinear solver context 49372a808120SBarry Smith - dm - the dm, cannot be NULL 49386c699258SBarry Smith 49396c699258SBarry Smith Level: intermediate 49406c699258SBarry Smith 494190deff25SFande Kong .seealso: SNESGetDM(), SNESHasDM(), KSPSetDM(), KSPGetDM() 49426c699258SBarry Smith @*/ 49437087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 49446c699258SBarry Smith { 49456c699258SBarry Smith PetscErrorCode ierr; 4946345fed2cSBarry Smith KSP ksp; 4947942e3340SBarry Smith DMSNES sdm; 49486c699258SBarry Smith 49496c699258SBarry Smith PetscFunctionBegin; 49500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 49512a808120SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,2); 49522a808120SBarry Smith ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 4953942e3340SBarry Smith if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 495451f4b3c7SToby Isaac if (snes->dm->dmsnes && !dm->dmsnes) { 4955942e3340SBarry Smith ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr); 4956942e3340SBarry Smith ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr); 4957f5af7f23SKarl Rupp if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 49586cab3a1bSJed Brown } 4959dc822a44SJed Brown ierr = DMCoarsenHookRemove(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 49606bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 49616cab3a1bSJed Brown } 49626c699258SBarry Smith snes->dm = dm; 4963116d1032SJed Brown snes->dmAuto = PETSC_FALSE; 4964f5af7f23SKarl Rupp 4965345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4966345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4967f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 4968efd4aadfSBarry Smith if (snes->npc) { 4969efd4aadfSBarry Smith ierr = SNESSetDM(snes->npc, snes->dm);CHKERRQ(ierr); 4970efd4aadfSBarry Smith ierr = SNESSetNPCSide(snes,snes->npcside);CHKERRQ(ierr); 49712c155ee1SBarry Smith } 49726c699258SBarry Smith PetscFunctionReturn(0); 49736c699258SBarry Smith } 49746c699258SBarry Smith 49756c699258SBarry Smith /*@ 49766c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 49776c699258SBarry Smith 49783f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 49796c699258SBarry Smith 49806c699258SBarry Smith Input Parameter: 49816c699258SBarry Smith . snes - the preconditioner context 49826c699258SBarry Smith 49836c699258SBarry Smith Output Parameter: 49846c699258SBarry Smith . dm - the dm 49856c699258SBarry Smith 49866c699258SBarry Smith Level: intermediate 49876c699258SBarry Smith 498890deff25SFande Kong .seealso: SNESSetDM(), SNESHasDM(), KSPSetDM(), KSPGetDM() 49896c699258SBarry Smith @*/ 49907087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 49916c699258SBarry Smith { 49926cab3a1bSJed Brown PetscErrorCode ierr; 49936cab3a1bSJed Brown 49946c699258SBarry Smith PetscFunctionBegin; 49950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 49966cab3a1bSJed Brown if (!snes->dm) { 4997ce94432eSBarry Smith ierr = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr); 4998116d1032SJed Brown snes->dmAuto = PETSC_TRUE; 49996cab3a1bSJed Brown } 50006c699258SBarry Smith *dm = snes->dm; 50016c699258SBarry Smith PetscFunctionReturn(0); 50026c699258SBarry Smith } 50030807856dSBarry Smith 500490deff25SFande Kong 500590deff25SFande Kong /*@ 500690deff25SFande Kong SNESHasDM - Whether snes has dm 500790deff25SFande Kong 500890deff25SFande Kong Not collective but all processes must return the same value 500990deff25SFande Kong 501090deff25SFande Kong Input Parameter: 501190deff25SFande Kong . snes - the nonlinear solver object 501290deff25SFande Kong 501390deff25SFande Kong Output Parameter: 501490deff25SFande Kong . hasdm - a flag indicates whether there is dm in snes 501590deff25SFande Kong 501690deff25SFande Kong Level: intermediate 501790deff25SFande Kong 501890deff25SFande Kong .seealso: SNESGetDM(), SNESSetDM(), KSPSetDM(), KSPGetDM() 501990deff25SFande Kong @*/ 502090deff25SFande Kong PetscErrorCode SNESHasDM(SNES snes,PetscBool *hasdm) 502190deff25SFande Kong { 502290deff25SFande Kong PetscFunctionBegin; 502390deff25SFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 502490deff25SFande Kong PetscValidPointer(hasdm,2); 502590deff25SFande Kong if (snes->dm) *hasdm = PETSC_TRUE; 502690deff25SFande Kong else *hasdm = PETSC_FALSE; 502790deff25SFande Kong PetscFunctionReturn(0); 502890deff25SFande Kong } 502990deff25SFande Kong 503031823bd8SMatthew G Knepley /*@ 5031be95d8f1SBarry Smith SNESSetNPC - Sets the nonlinear preconditioner to be used. 503231823bd8SMatthew G Knepley 503331823bd8SMatthew G Knepley Collective on SNES 503431823bd8SMatthew G Knepley 503531823bd8SMatthew G Knepley Input Parameters: 503631823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 503731823bd8SMatthew G Knepley - pc - the preconditioner object 503831823bd8SMatthew G Knepley 503931823bd8SMatthew G Knepley Notes: 5040be95d8f1SBarry Smith Use SNESGetNPC() to retrieve the preconditioner context (for example, 504131823bd8SMatthew G Knepley to configure it using the API). 504231823bd8SMatthew G Knepley 504331823bd8SMatthew G Knepley Level: developer 504431823bd8SMatthew G Knepley 504531823bd8SMatthew G Knepley .keywords: SNES, set, precondition 50463ad1a0b9SPatrick Farrell .seealso: SNESGetNPC(), SNESHasNPC() 504731823bd8SMatthew G Knepley @*/ 5048be95d8f1SBarry Smith PetscErrorCode SNESSetNPC(SNES snes, SNES pc) 504931823bd8SMatthew G Knepley { 505031823bd8SMatthew G Knepley PetscErrorCode ierr; 505131823bd8SMatthew G Knepley 505231823bd8SMatthew G Knepley PetscFunctionBegin; 505331823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 505431823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 505531823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 505631823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 5057efd4aadfSBarry Smith ierr = SNESDestroy(&snes->npc);CHKERRQ(ierr); 5058efd4aadfSBarry Smith snes->npc = pc; 5059efd4aadfSBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc);CHKERRQ(ierr); 506031823bd8SMatthew G Knepley PetscFunctionReturn(0); 506131823bd8SMatthew G Knepley } 506231823bd8SMatthew G Knepley 506331823bd8SMatthew G Knepley /*@ 5064be95d8f1SBarry Smith SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver. 506531823bd8SMatthew G Knepley 506631823bd8SMatthew G Knepley Not Collective 506731823bd8SMatthew G Knepley 506831823bd8SMatthew G Knepley Input Parameter: 506931823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 507031823bd8SMatthew G Knepley 507131823bd8SMatthew G Knepley Output Parameter: 507231823bd8SMatthew G Knepley . pc - preconditioner context 507331823bd8SMatthew G Knepley 5074be95d8f1SBarry Smith Notes: If a SNES was previously set with SNESSetNPC() then that SNES is returned. 5075be95d8f1SBarry Smith 507631823bd8SMatthew G Knepley Level: developer 507731823bd8SMatthew G Knepley 507831823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 50793ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESHasNPC() 508031823bd8SMatthew G Knepley @*/ 5081be95d8f1SBarry Smith PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) 508231823bd8SMatthew G Knepley { 508331823bd8SMatthew G Knepley PetscErrorCode ierr; 5084a64e098fSPeter Brune const char *optionsprefix; 508531823bd8SMatthew G Knepley 508631823bd8SMatthew G Knepley PetscFunctionBegin; 508731823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 508831823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 5089efd4aadfSBarry Smith if (!snes->npc) { 5090efd4aadfSBarry Smith ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc);CHKERRQ(ierr); 5091efd4aadfSBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1);CHKERRQ(ierr); 5092efd4aadfSBarry Smith ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr); 5093a64e098fSPeter Brune ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 5094efd4aadfSBarry Smith ierr = SNESSetOptionsPrefix(snes->npc,optionsprefix);CHKERRQ(ierr); 5095efd4aadfSBarry Smith ierr = SNESAppendOptionsPrefix(snes->npc,"npc_");CHKERRQ(ierr); 5096efd4aadfSBarry Smith ierr = SNESSetCountersReset(snes->npc,PETSC_FALSE);CHKERRQ(ierr); 509731823bd8SMatthew G Knepley } 5098efd4aadfSBarry Smith *pc = snes->npc; 509931823bd8SMatthew G Knepley PetscFunctionReturn(0); 510031823bd8SMatthew G Knepley } 510131823bd8SMatthew G Knepley 51023ad1a0b9SPatrick Farrell /*@ 51033ad1a0b9SPatrick Farrell SNESHasNPC - Returns whether a nonlinear preconditioner exists 51043ad1a0b9SPatrick Farrell 51053ad1a0b9SPatrick Farrell Not Collective 51063ad1a0b9SPatrick Farrell 51073ad1a0b9SPatrick Farrell Input Parameter: 51083ad1a0b9SPatrick Farrell . snes - iterative context obtained from SNESCreate() 51093ad1a0b9SPatrick Farrell 51103ad1a0b9SPatrick Farrell Output Parameter: 51113ad1a0b9SPatrick Farrell . has_npc - whether the SNES has an NPC or not 51123ad1a0b9SPatrick Farrell 51133ad1a0b9SPatrick Farrell Level: developer 51143ad1a0b9SPatrick Farrell 51153ad1a0b9SPatrick Farrell .keywords: SNES, has, preconditioner 51163ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESGetNPC() 51173ad1a0b9SPatrick Farrell @*/ 51183ad1a0b9SPatrick Farrell PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 51193ad1a0b9SPatrick Farrell { 51203ad1a0b9SPatrick Farrell PetscFunctionBegin; 51213ad1a0b9SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5122efd4aadfSBarry Smith *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE); 51233ad1a0b9SPatrick Farrell PetscFunctionReturn(0); 51243ad1a0b9SPatrick Farrell } 51253ad1a0b9SPatrick Farrell 5126c40d0f55SPeter Brune /*@ 5127be95d8f1SBarry Smith SNESSetNPCSide - Sets the preconditioning side. 5128c40d0f55SPeter Brune 5129c40d0f55SPeter Brune Logically Collective on SNES 5130c40d0f55SPeter Brune 5131c40d0f55SPeter Brune Input Parameter: 5132c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5133c40d0f55SPeter Brune 5134c40d0f55SPeter Brune Output Parameter: 5135c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5136c40d0f55SPeter Brune .vb 51372d547940SBarry Smith PC_LEFT - left preconditioning 51382d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5139c40d0f55SPeter Brune .ve 5140c40d0f55SPeter Brune 5141c40d0f55SPeter Brune Options Database Keys: 5142c40d0f55SPeter Brune . -snes_pc_side <right,left> 5143c40d0f55SPeter Brune 51442d547940SBarry Smith Notes: SNESNRICHARDSON and SNESNCG only support left preconditioning. 51452d547940SBarry Smith 5146c40d0f55SPeter Brune Level: intermediate 5147c40d0f55SPeter Brune 5148c40d0f55SPeter Brune .keywords: SNES, set, right, left, side, preconditioner, flag 5149c40d0f55SPeter Brune 5150be95d8f1SBarry Smith .seealso: SNESGetNPCSide(), KSPSetPCSide() 5151c40d0f55SPeter Brune @*/ 5152be95d8f1SBarry Smith PetscErrorCode SNESSetNPCSide(SNES snes,PCSide side) 5153c40d0f55SPeter Brune { 5154c40d0f55SPeter Brune PetscFunctionBegin; 5155c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5156c40d0f55SPeter Brune PetscValidLogicalCollectiveEnum(snes,side,2); 5157efd4aadfSBarry Smith snes->npcside= side; 5158c40d0f55SPeter Brune PetscFunctionReturn(0); 5159c40d0f55SPeter Brune } 5160c40d0f55SPeter Brune 5161c40d0f55SPeter Brune /*@ 5162be95d8f1SBarry Smith SNESGetNPCSide - Gets the preconditioning side. 5163c40d0f55SPeter Brune 5164c40d0f55SPeter Brune Not Collective 5165c40d0f55SPeter Brune 5166c40d0f55SPeter Brune Input Parameter: 5167c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5168c40d0f55SPeter Brune 5169c40d0f55SPeter Brune Output Parameter: 5170c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5171c40d0f55SPeter Brune .vb 51722d547940SBarry Smith PC_LEFT - left preconditioning 51732d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5174c40d0f55SPeter Brune .ve 5175c40d0f55SPeter Brune 5176c40d0f55SPeter Brune Level: intermediate 5177c40d0f55SPeter Brune 5178c40d0f55SPeter Brune .keywords: SNES, get, right, left, side, preconditioner, flag 5179c40d0f55SPeter Brune 5180be95d8f1SBarry Smith .seealso: SNESSetNPCSide(), KSPGetPCSide() 5181c40d0f55SPeter Brune @*/ 5182be95d8f1SBarry Smith PetscErrorCode SNESGetNPCSide(SNES snes,PCSide *side) 5183c40d0f55SPeter Brune { 5184c40d0f55SPeter Brune PetscFunctionBegin; 5185c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5186c40d0f55SPeter Brune PetscValidPointer(side,2); 5187efd4aadfSBarry Smith *side = snes->npcside; 5188c40d0f55SPeter Brune PetscFunctionReturn(0); 5189c40d0f55SPeter Brune } 5190c40d0f55SPeter Brune 51919e764e56SPeter Brune /*@ 51927601faf0SJed Brown SNESSetLineSearch - Sets the linesearch on the SNES instance. 51939e764e56SPeter Brune 51949e764e56SPeter Brune Collective on SNES 51959e764e56SPeter Brune 51969e764e56SPeter Brune Input Parameters: 51979e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 51989e764e56SPeter Brune - linesearch - the linesearch object 51999e764e56SPeter Brune 52009e764e56SPeter Brune Notes: 52017601faf0SJed Brown Use SNESGetLineSearch() to retrieve the preconditioner context (for example, 52029e764e56SPeter Brune to configure it using the API). 52039e764e56SPeter Brune 52049e764e56SPeter Brune Level: developer 52059e764e56SPeter Brune 52069e764e56SPeter Brune .keywords: SNES, set, linesearch 52077601faf0SJed Brown .seealso: SNESGetLineSearch() 52089e764e56SPeter Brune @*/ 52097601faf0SJed Brown PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 52109e764e56SPeter Brune { 52119e764e56SPeter Brune PetscErrorCode ierr; 52129e764e56SPeter Brune 52139e764e56SPeter Brune PetscFunctionBegin; 52149e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5215f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 52169e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 52179e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 5218f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 5219f5af7f23SKarl Rupp 52209e764e56SPeter Brune snes->linesearch = linesearch; 5221f5af7f23SKarl Rupp 52223bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 52239e764e56SPeter Brune PetscFunctionReturn(0); 52249e764e56SPeter Brune } 52259e764e56SPeter Brune 5226a34ceb2aSJed Brown /*@ 52277601faf0SJed Brown SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 52288141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 52299e764e56SPeter Brune 52309e764e56SPeter Brune Not Collective 52319e764e56SPeter Brune 52329e764e56SPeter Brune Input Parameter: 52339e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 52349e764e56SPeter Brune 52359e764e56SPeter Brune Output Parameter: 52369e764e56SPeter Brune . linesearch - linesearch context 52379e764e56SPeter Brune 5238162e0bf5SPeter Brune Level: beginner 52399e764e56SPeter Brune 52409e764e56SPeter Brune .keywords: SNES, get, linesearch 5241162e0bf5SPeter Brune .seealso: SNESSetLineSearch(), SNESLineSearchCreate() 52429e764e56SPeter Brune @*/ 52437601faf0SJed Brown PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 52449e764e56SPeter Brune { 52459e764e56SPeter Brune PetscErrorCode ierr; 52469e764e56SPeter Brune const char *optionsprefix; 52479e764e56SPeter Brune 52489e764e56SPeter Brune PetscFunctionBegin; 52499e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 52509e764e56SPeter Brune PetscValidPointer(linesearch, 2); 52519e764e56SPeter Brune if (!snes->linesearch) { 52529e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 525382f516ccSBarry Smith ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr); 5254f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 5255b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 52569e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 52573bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 52589e764e56SPeter Brune } 52599e764e56SPeter Brune *linesearch = snes->linesearch; 52609e764e56SPeter Brune PetscFunctionReturn(0); 52619e764e56SPeter Brune } 52629e764e56SPeter Brune 526369b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 5264c6db04a5SJed Brown #include <mex.h> 526569b4f73cSBarry Smith 52668f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 52678f6e6473SBarry Smith 52680807856dSBarry Smith /* 5269bf388a1fSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with SNESSetFunctionMatlab(). 52700807856dSBarry Smith 52710807856dSBarry Smith Collective on SNES 52720807856dSBarry Smith 52730807856dSBarry Smith Input Parameters: 52740807856dSBarry Smith + snes - the SNES context 52750807856dSBarry Smith - x - input vector 52760807856dSBarry Smith 52770807856dSBarry Smith Output Parameter: 52780807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 52790807856dSBarry Smith 52800807856dSBarry Smith Notes: 52810807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 52820807856dSBarry Smith implementations, so most users would not generally call this routine 52830807856dSBarry Smith themselves. 52840807856dSBarry Smith 52850807856dSBarry Smith Level: developer 52860807856dSBarry Smith 52870807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 52880807856dSBarry Smith 52890807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 529061b2408cSBarry Smith */ 52917087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 52920807856dSBarry Smith { 5293e650e774SBarry Smith PetscErrorCode ierr; 52948f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 52958f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 52968f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 529791621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 5298e650e774SBarry Smith 52990807856dSBarry Smith PetscFunctionBegin; 53000807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 53010807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 53020807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 53030807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 53040807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 53050807856dSBarry Smith 53060807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 5307e650e774SBarry Smith 530891621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 5309e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 5310e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 531191621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 531291621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 531391621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 53148f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 53158f6e6473SBarry Smith prhs[4] = sctx->ctx; 5316b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 5317e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5318e650e774SBarry Smith mxDestroyArray(prhs[0]); 5319e650e774SBarry Smith mxDestroyArray(prhs[1]); 5320e650e774SBarry Smith mxDestroyArray(prhs[2]); 53218f6e6473SBarry Smith mxDestroyArray(prhs[3]); 5322e650e774SBarry Smith mxDestroyArray(plhs[0]); 53230807856dSBarry Smith PetscFunctionReturn(0); 53240807856dSBarry Smith } 53250807856dSBarry Smith 532661b2408cSBarry Smith /* 53270807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 53280807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 5329e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 53300807856dSBarry Smith 53310807856dSBarry Smith Logically Collective on SNES 53320807856dSBarry Smith 53330807856dSBarry Smith Input Parameters: 53340807856dSBarry Smith + snes - the SNES context 53350807856dSBarry Smith . r - vector to store function value 5336f8b49ee9SBarry Smith - f - function evaluation routine 53370807856dSBarry Smith 53380807856dSBarry Smith Notes: 53390807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 53400807856dSBarry Smith $ f'(x) x = -f(x), 53410807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 53420807856dSBarry Smith 53430807856dSBarry Smith Level: beginner 53440807856dSBarry Smith 5345c5b75c40SBarry Smith Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5346c5b75c40SBarry Smith 53470807856dSBarry Smith .keywords: SNES, nonlinear, set, function 53480807856dSBarry Smith 53490807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 535061b2408cSBarry Smith */ 5351f8b49ee9SBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *f,mxArray *ctx) 53520807856dSBarry Smith { 53530807856dSBarry Smith PetscErrorCode ierr; 53548f6e6473SBarry Smith SNESMatlabContext *sctx; 53550807856dSBarry Smith 53560807856dSBarry Smith PetscFunctionBegin; 53578f6e6473SBarry Smith /* currently sctx is memory bleed */ 5358854ce69bSBarry Smith ierr = PetscNew(&sctx);CHKERRQ(ierr); 5359f8b49ee9SBarry Smith ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr); 53608f6e6473SBarry Smith /* 53618f6e6473SBarry Smith This should work, but it doesn't 53628f6e6473SBarry Smith sctx->ctx = ctx; 53638f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 53648f6e6473SBarry Smith */ 53658f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 53668f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 53670807856dSBarry Smith PetscFunctionReturn(0); 53680807856dSBarry Smith } 536969b4f73cSBarry Smith 537061b2408cSBarry Smith /* 5371bf388a1fSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with SNESSetJacobianMatlab(). 537261b2408cSBarry Smith 537361b2408cSBarry Smith Collective on SNES 537461b2408cSBarry Smith 537561b2408cSBarry Smith Input Parameters: 537661b2408cSBarry Smith + snes - the SNES context 537761b2408cSBarry Smith . x - input vector 537861b2408cSBarry Smith . A, B - the matrices 537961b2408cSBarry Smith - ctx - user context 538061b2408cSBarry Smith 538161b2408cSBarry Smith Level: developer 538261b2408cSBarry Smith 538361b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 538461b2408cSBarry Smith 538561b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 538661b2408cSBarry Smith @*/ 5387f3229a78SSatish Balay PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat A,Mat B,void *ctx) 538861b2408cSBarry Smith { 538961b2408cSBarry Smith PetscErrorCode ierr; 539061b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 539161b2408cSBarry Smith int nlhs = 2,nrhs = 6; 539261b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 539361b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 539461b2408cSBarry Smith 539561b2408cSBarry Smith PetscFunctionBegin; 539661b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 539761b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 539861b2408cSBarry Smith 539961b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 540061b2408cSBarry Smith 540161b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 540261b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 540361b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 540461b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 540561b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 540661b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 540761b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 540861b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 540961b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 541061b2408cSBarry Smith prhs[5] = sctx->ctx; 5411b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 541261b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 541361b2408cSBarry Smith mxDestroyArray(prhs[0]); 541461b2408cSBarry Smith mxDestroyArray(prhs[1]); 541561b2408cSBarry Smith mxDestroyArray(prhs[2]); 541661b2408cSBarry Smith mxDestroyArray(prhs[3]); 541761b2408cSBarry Smith mxDestroyArray(prhs[4]); 541861b2408cSBarry Smith mxDestroyArray(plhs[0]); 541961b2408cSBarry Smith mxDestroyArray(plhs[1]); 542061b2408cSBarry Smith PetscFunctionReturn(0); 542161b2408cSBarry Smith } 542261b2408cSBarry Smith 542361b2408cSBarry Smith /* 542461b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 542561b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 5426e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 542761b2408cSBarry Smith 542861b2408cSBarry Smith Logically Collective on SNES 542961b2408cSBarry Smith 543061b2408cSBarry Smith Input Parameters: 543161b2408cSBarry Smith + snes - the SNES context 543261b2408cSBarry Smith . A,B - Jacobian matrices 5433f8b49ee9SBarry Smith . J - function evaluation routine 543461b2408cSBarry Smith - ctx - user context 543561b2408cSBarry Smith 543661b2408cSBarry Smith Level: developer 543761b2408cSBarry Smith 5438c5b75c40SBarry Smith Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5439c5b75c40SBarry Smith 544061b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 544161b2408cSBarry Smith 5442f8b49ee9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction(), J 544361b2408cSBarry Smith */ 5444f8b49ee9SBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *J,mxArray *ctx) 544561b2408cSBarry Smith { 544661b2408cSBarry Smith PetscErrorCode ierr; 544761b2408cSBarry Smith SNESMatlabContext *sctx; 544861b2408cSBarry Smith 544961b2408cSBarry Smith PetscFunctionBegin; 545061b2408cSBarry Smith /* currently sctx is memory bleed */ 5451854ce69bSBarry Smith ierr = PetscNew(&sctx);CHKERRQ(ierr); 5452f8b49ee9SBarry Smith ierr = PetscStrallocpy(J,&sctx->funcname);CHKERRQ(ierr); 545361b2408cSBarry Smith /* 545461b2408cSBarry Smith This should work, but it doesn't 545561b2408cSBarry Smith sctx->ctx = ctx; 545661b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 545761b2408cSBarry Smith */ 545861b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 545961b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 546061b2408cSBarry Smith PetscFunctionReturn(0); 546161b2408cSBarry Smith } 546269b4f73cSBarry Smith 5463f9eb7ae2SShri Abhyankar /* 5464f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 5465f9eb7ae2SShri Abhyankar 5466f9eb7ae2SShri Abhyankar Collective on SNES 5467f9eb7ae2SShri Abhyankar 5468f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 5469f9eb7ae2SShri Abhyankar @*/ 54707087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 5471f9eb7ae2SShri Abhyankar { 5472f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 547348f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 5474f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 5475f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 5476f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 5477f9eb7ae2SShri Abhyankar Vec x = snes->vec_sol; 5478f9eb7ae2SShri Abhyankar 5479f9eb7ae2SShri Abhyankar PetscFunctionBegin; 5480f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5481f9eb7ae2SShri Abhyankar 5482f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 5483f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 5484f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 5485f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 5486f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 5487f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 5488f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 5489f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 5490f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 5491f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5492f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 5493f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 5494f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 5495f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 5496f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 5497f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 5498f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 5499f9eb7ae2SShri Abhyankar } 5500f9eb7ae2SShri Abhyankar 5501f9eb7ae2SShri Abhyankar /* 5502e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 5503f9eb7ae2SShri Abhyankar 5504f9eb7ae2SShri Abhyankar Level: developer 5505f9eb7ae2SShri Abhyankar 5506c5b75c40SBarry Smith Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5507c5b75c40SBarry Smith 5508f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 5509f9eb7ae2SShri Abhyankar 5510f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 5511f9eb7ae2SShri Abhyankar */ 55126e4dcb14SBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *f,mxArray *ctx) 5513f9eb7ae2SShri Abhyankar { 5514f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 5515f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 5516f9eb7ae2SShri Abhyankar 5517f9eb7ae2SShri Abhyankar PetscFunctionBegin; 5518f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 5519854ce69bSBarry Smith ierr = PetscNew(&sctx);CHKERRQ(ierr); 55206e4dcb14SBarry Smith ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr); 5521f9eb7ae2SShri Abhyankar /* 5522f9eb7ae2SShri Abhyankar This should work, but it doesn't 5523f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 5524f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 5525f9eb7ae2SShri Abhyankar */ 5526f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 55270298fd71SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,NULL);CHKERRQ(ierr); 5528f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 5529f9eb7ae2SShri Abhyankar } 5530f9eb7ae2SShri Abhyankar 553169b4f73cSBarry Smith #endif 5532