19b94acceSBarry Smith 2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h> /*I "petscsnes.h" I*/ 36cab3a1bSJed Brown #include <petscdmshell.h> /*I "petscdmshell.h" I*/ 49b94acceSBarry Smith 5ace3abfcSBarry Smith PetscBool SNESRegisterAllCalled = PETSC_FALSE; 68ba1e511SMatthew Knepley PetscFList SNESList = PETSC_NULL; 78ba1e511SMatthew Knepley 88ba1e511SMatthew Knepley /* Logging support */ 97087cfbeSBarry Smith PetscClassId SNES_CLASSID; 10f1c6b773SPeter Brune PetscLogEvent SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval; 11a09944afSBarry Smith 12a09944afSBarry Smith #undef __FUNCT__ 13e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged" 14e113a28aSBarry Smith /*@ 15e113a28aSBarry Smith SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 16e113a28aSBarry Smith 173f9fe445SBarry Smith Logically Collective on SNES 18e113a28aSBarry Smith 19e113a28aSBarry Smith Input Parameters: 20e113a28aSBarry Smith + snes - iterative context obtained from SNESCreate() 21e113a28aSBarry Smith - flg - PETSC_TRUE indicates you want the error generated 22e113a28aSBarry Smith 23e113a28aSBarry Smith Options database keys: 24e113a28aSBarry Smith . -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false) 25e113a28aSBarry Smith 26e113a28aSBarry Smith Level: intermediate 27e113a28aSBarry Smith 28e113a28aSBarry Smith Notes: 29e113a28aSBarry Smith Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 30e113a28aSBarry Smith to determine if it has converged. 31e113a28aSBarry Smith 32e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 33e113a28aSBarry Smith 34e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 35e113a28aSBarry Smith @*/ 367087cfbeSBarry Smith PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 37e113a28aSBarry Smith { 38e113a28aSBarry Smith PetscFunctionBegin; 39e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 40acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flg,2); 41e113a28aSBarry Smith snes->errorifnotconverged = flg; 42dd568438SSatish Balay 43e113a28aSBarry Smith PetscFunctionReturn(0); 44e113a28aSBarry Smith } 45e113a28aSBarry Smith 46e113a28aSBarry Smith #undef __FUNCT__ 47e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged" 48e113a28aSBarry Smith /*@ 49e113a28aSBarry Smith SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 50e113a28aSBarry Smith 51e113a28aSBarry Smith Not Collective 52e113a28aSBarry Smith 53e113a28aSBarry Smith Input Parameter: 54e113a28aSBarry Smith . snes - iterative context obtained from SNESCreate() 55e113a28aSBarry Smith 56e113a28aSBarry Smith Output Parameter: 57e113a28aSBarry Smith . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 58e113a28aSBarry Smith 59e113a28aSBarry Smith Level: intermediate 60e113a28aSBarry Smith 61e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 62e113a28aSBarry Smith 63e113a28aSBarry Smith .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 64e113a28aSBarry Smith @*/ 657087cfbeSBarry Smith PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 66e113a28aSBarry Smith { 67e113a28aSBarry Smith PetscFunctionBegin; 68e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 69e113a28aSBarry Smith PetscValidPointer(flag,2); 70e113a28aSBarry Smith *flag = snes->errorifnotconverged; 71e113a28aSBarry Smith PetscFunctionReturn(0); 72e113a28aSBarry Smith } 73e113a28aSBarry Smith 74e113a28aSBarry Smith #undef __FUNCT__ 754936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError" 76e725d27bSBarry Smith /*@ 774936397dSBarry Smith SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not 784936397dSBarry Smith in the functions domain. For example, negative pressure. 794936397dSBarry Smith 803f9fe445SBarry Smith Logically Collective on SNES 814936397dSBarry Smith 824936397dSBarry Smith Input Parameters: 836a388c36SPeter Brune . snes - the SNES context 844936397dSBarry Smith 8528529972SSatish Balay Level: advanced 864936397dSBarry Smith 874936397dSBarry Smith .keywords: SNES, view 884936397dSBarry Smith 894936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction() 904936397dSBarry Smith @*/ 917087cfbeSBarry Smith PetscErrorCode SNESSetFunctionDomainError(SNES snes) 924936397dSBarry Smith { 934936397dSBarry Smith PetscFunctionBegin; 940700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 954936397dSBarry Smith snes->domainerror = PETSC_TRUE; 964936397dSBarry Smith PetscFunctionReturn(0); 974936397dSBarry Smith } 984936397dSBarry Smith 996a388c36SPeter Brune 1006a388c36SPeter Brune #undef __FUNCT__ 1016a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError" 1026a388c36SPeter Brune /*@ 103c77b2880SPeter Brune SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction; 1046a388c36SPeter Brune 1056a388c36SPeter Brune Logically Collective on SNES 1066a388c36SPeter Brune 1076a388c36SPeter Brune Input Parameters: 1086a388c36SPeter Brune . snes - the SNES context 1096a388c36SPeter Brune 1106a388c36SPeter Brune Output Parameters: 1116a388c36SPeter Brune . domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise. 1126a388c36SPeter Brune 1136a388c36SPeter Brune Level: advanced 1146a388c36SPeter Brune 1156a388c36SPeter Brune .keywords: SNES, view 1166a388c36SPeter Brune 1176a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction() 1186a388c36SPeter Brune @*/ 1196a388c36SPeter Brune PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 1206a388c36SPeter Brune { 1216a388c36SPeter Brune PetscFunctionBegin; 1226a388c36SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1236a388c36SPeter Brune PetscValidPointer(domainerror, 2); 1246a388c36SPeter Brune *domainerror = snes->domainerror; 1256a388c36SPeter Brune PetscFunctionReturn(0); 1266a388c36SPeter Brune } 1276a388c36SPeter Brune 1286a388c36SPeter Brune 1294936397dSBarry Smith #undef __FUNCT__ 1304a2ae208SSatish Balay #define __FUNCT__ "SNESView" 1317e2c5f70SBarry Smith /*@C 1329b94acceSBarry Smith SNESView - Prints the SNES data structure. 1339b94acceSBarry Smith 1344c49b128SBarry Smith Collective on SNES 135fee21e36SBarry Smith 136c7afd0dbSLois Curfman McInnes Input Parameters: 137c7afd0dbSLois Curfman McInnes + SNES - the SNES context 138c7afd0dbSLois Curfman McInnes - viewer - visualization context 139c7afd0dbSLois Curfman McInnes 1409b94acceSBarry Smith Options Database Key: 141c8a8ba5cSLois Curfman McInnes . -snes_view - Calls SNESView() at end of SNESSolve() 1429b94acceSBarry Smith 1439b94acceSBarry Smith Notes: 1449b94acceSBarry Smith The available visualization contexts include 145b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 146b0a32e0cSBarry Smith - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 147c8a8ba5cSLois Curfman McInnes output where only the first processor opens 148c8a8ba5cSLois Curfman McInnes the file. All other processors send their 149c8a8ba5cSLois Curfman McInnes data to the first processor to print. 1509b94acceSBarry Smith 1513e081fefSLois Curfman McInnes The user can open an alternative visualization context with 152b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 1539b94acceSBarry Smith 15436851e7fSLois Curfman McInnes Level: beginner 15536851e7fSLois Curfman McInnes 1569b94acceSBarry Smith .keywords: SNES, view 1579b94acceSBarry Smith 158b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen() 1599b94acceSBarry Smith @*/ 1607087cfbeSBarry Smith PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 1619b94acceSBarry Smith { 162fa9f3622SBarry Smith SNESKSPEW *kctx; 163dfbe8321SBarry Smith PetscErrorCode ierr; 16494b7f48cSBarry Smith KSP ksp; 1657f1410a3SPeter Brune SNESLineSearch linesearch; 166ace3abfcSBarry Smith PetscBool iascii,isstring; 1679b94acceSBarry Smith 1683a40ed3dSBarry Smith PetscFunctionBegin; 1690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1703050cee2SBarry Smith if (!viewer) { 1717adad957SLisandro Dalcin ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 1723050cee2SBarry Smith } 1730700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 174c9780b6fSBarry Smith PetscCheckSameComm(snes,1,viewer,2); 17574679c65SBarry Smith 176251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 177251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 17832077d6dSBarry Smith if (iascii) { 179317d6ea6SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr); 180e7788613SBarry Smith if (snes->ops->view) { 181b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 182e7788613SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 183b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1840ef38995SBarry Smith } 18577431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 186a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n", 187c60f73f4SPeter Brune snes->rtol,snes->abstol,snes->stol);CHKERRQ(ierr); 18877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 18977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 1909b94acceSBarry Smith if (snes->ksp_ewconv) { 191fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 1929b94acceSBarry Smith if (kctx) { 19377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 194a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr); 195a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr); 1969b94acceSBarry Smith } 1979b94acceSBarry Smith } 198eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 199eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 200eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 201eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 202eb1f6c34SBarry Smith } 203eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 204eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 205eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 20642f4f86dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 207eb1f6c34SBarry Smith } 2080f5bd95cSBarry Smith } else if (isstring) { 209317d6ea6SBarry Smith const char *type; 210454a90a3SBarry Smith ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 211b0a32e0cSBarry Smith ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 21219bcc07fSBarry Smith } 21342f4f86dSBarry Smith if (snes->pc && snes->usespc) { 2144a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2154a0c5b0cSMatthew G Knepley ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr); 2164a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2174a0c5b0cSMatthew G Knepley } 2182c155ee1SBarry Smith if (snes->usesksp) { 2192c155ee1SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 220b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 22194b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 222b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2232c155ee1SBarry Smith } 2247f1410a3SPeter Brune if (snes->linesearch) { 2257f1410a3SPeter Brune ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2267f1410a3SPeter Brune ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr); 2277f1410a3SPeter Brune ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr); 2287f1410a3SPeter Brune ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2297f1410a3SPeter Brune } 2303a40ed3dSBarry Smith PetscFunctionReturn(0); 2319b94acceSBarry Smith } 2329b94acceSBarry Smith 23376b2cf59SMatthew Knepley /* 23476b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 23576b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 23676b2cf59SMatthew Knepley */ 23776b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 238a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 2396849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 24076b2cf59SMatthew Knepley 241e74ef692SMatthew Knepley #undef __FUNCT__ 242e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker" 243ac226902SBarry Smith /*@C 24476b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 24576b2cf59SMatthew Knepley 24676b2cf59SMatthew Knepley Not Collective 24776b2cf59SMatthew Knepley 24876b2cf59SMatthew Knepley Input Parameter: 24976b2cf59SMatthew Knepley . snescheck - function that checks for options 25076b2cf59SMatthew Knepley 25176b2cf59SMatthew Knepley Level: developer 25276b2cf59SMatthew Knepley 25376b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 25476b2cf59SMatthew Knepley @*/ 2557087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 25676b2cf59SMatthew Knepley { 25776b2cf59SMatthew Knepley PetscFunctionBegin; 25876b2cf59SMatthew Knepley if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 259e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 26076b2cf59SMatthew Knepley } 26176b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 26276b2cf59SMatthew Knepley PetscFunctionReturn(0); 26376b2cf59SMatthew Knepley } 26476b2cf59SMatthew Knepley 2657087cfbeSBarry Smith extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 266aa3661deSLisandro Dalcin 267aa3661deSLisandro Dalcin #undef __FUNCT__ 268aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private" 269ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 270aa3661deSLisandro Dalcin { 271aa3661deSLisandro Dalcin Mat J; 272aa3661deSLisandro Dalcin KSP ksp; 273aa3661deSLisandro Dalcin PC pc; 274ace3abfcSBarry Smith PetscBool match; 275aa3661deSLisandro Dalcin PetscErrorCode ierr; 276aa3661deSLisandro Dalcin 277aa3661deSLisandro Dalcin PetscFunctionBegin; 2780700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 279aa3661deSLisandro Dalcin 28098613b67SLisandro Dalcin if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 28198613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 28298613b67SLisandro Dalcin ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr); 28398613b67SLisandro Dalcin } 28498613b67SLisandro Dalcin 285aa3661deSLisandro Dalcin if (version == 1) { 286aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 28798613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2889c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 289aa3661deSLisandro Dalcin } else if (version == 2) { 290e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 29182a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 292aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 293aa3661deSLisandro Dalcin #else 294e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 295aa3661deSLisandro Dalcin #endif 296a8248277SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 297aa3661deSLisandro Dalcin 298aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 299d3462f78SMatthew Knepley if (hasOperator) { 300aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 301aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 302aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 303aa3661deSLisandro Dalcin } else { 304aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 305aa3661deSLisandro Dalcin provided preconditioner matrix with the default matrix free version. */ 3066cab3a1bSJed Brown void *functx; 3076cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 3086cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 309aa3661deSLisandro Dalcin /* Force no preconditioner */ 310aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 311aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 312251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 313aa3661deSLisandro Dalcin if (!match) { 314aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 315aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 316aa3661deSLisandro Dalcin } 317aa3661deSLisandro Dalcin } 3186bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 319aa3661deSLisandro Dalcin PetscFunctionReturn(0); 320aa3661deSLisandro Dalcin } 321aa3661deSLisandro Dalcin 3224a2ae208SSatish Balay #undef __FUNCT__ 323dfe15315SJed Brown #define __FUNCT__ "DMRestrictHook_SNESVecSol" 324dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx) 325dfe15315SJed Brown { 326dfe15315SJed Brown SNES snes = (SNES)ctx; 327dfe15315SJed Brown PetscErrorCode ierr; 328dfe15315SJed Brown Vec Xfine,Xfine_named = PETSC_NULL,Xcoarse; 329dfe15315SJed Brown 330dfe15315SJed Brown PetscFunctionBegin; 331dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 332dfe15315SJed Brown else { 333dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr); 334dfe15315SJed Brown Xfine = Xfine_named; 335dfe15315SJed Brown } 336dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 337dfe15315SJed Brown ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr); 338dfe15315SJed Brown ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr); 339dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 340dfe15315SJed Brown if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);} 341dfe15315SJed Brown PetscFunctionReturn(0); 342dfe15315SJed Brown } 343dfe15315SJed Brown 344dfe15315SJed Brown #undef __FUNCT__ 345caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES" 346a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 347a6950cb2SJed Brown * safely call SNESGetDM() in their residual evaluation routine. */ 348caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx) 349caa4e7f2SJed Brown { 350caa4e7f2SJed Brown SNES snes = (SNES)ctx; 351caa4e7f2SJed Brown PetscErrorCode ierr; 352caa4e7f2SJed Brown Mat Asave = A,Bsave = B; 353dfe15315SJed Brown Vec X,Xnamed = PETSC_NULL; 354dfe15315SJed Brown DM dmsave; 355caa4e7f2SJed Brown 356caa4e7f2SJed Brown PetscFunctionBegin; 357dfe15315SJed Brown dmsave = snes->dm; 358dfe15315SJed Brown ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr); 359dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 360dfe15315SJed Brown else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ 361dfe15315SJed Brown ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 362dfe15315SJed Brown X = Xnamed; 363dfe15315SJed Brown } 364dfe15315SJed Brown ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr); 365caa4e7f2SJed Brown if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time"); 366dfe15315SJed Brown if (Xnamed) { 367dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 368dfe15315SJed Brown } 369dfe15315SJed Brown snes->dm = dmsave; 370caa4e7f2SJed Brown PetscFunctionReturn(0); 371caa4e7f2SJed Brown } 372caa4e7f2SJed Brown 373caa4e7f2SJed Brown #undef __FUNCT__ 3746cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices" 3756cab3a1bSJed Brown /*@ 3766cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 3776cab3a1bSJed Brown 3786cab3a1bSJed Brown Collective 3796cab3a1bSJed Brown 3806cab3a1bSJed Brown Input Arguments: 3816cab3a1bSJed Brown . snes - snes to configure 3826cab3a1bSJed Brown 3836cab3a1bSJed Brown Level: developer 3846cab3a1bSJed Brown 3856cab3a1bSJed Brown .seealso: SNESSetUp() 3866cab3a1bSJed Brown @*/ 3876cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 3886cab3a1bSJed Brown { 3896cab3a1bSJed Brown PetscErrorCode ierr; 3906cab3a1bSJed Brown DM dm; 3916cab3a1bSJed Brown SNESDM sdm; 3926cab3a1bSJed Brown 3936cab3a1bSJed Brown PetscFunctionBegin; 3946cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3956cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 396caa4e7f2SJed Brown if (!sdm->computejacobian) { 3976cab3a1bSJed Brown Mat J,B; 3986cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 3996cab3a1bSJed Brown if (snes->mf_operator) { 4006cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4016cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4026cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4036cab3a1bSJed Brown } else { 4046cab3a1bSJed Brown J = B; 4056cab3a1bSJed Brown ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr); 4066cab3a1bSJed Brown } 4076cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr); 4086cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 4096cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 4106cab3a1bSJed Brown } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) { 4116cab3a1bSJed Brown Mat J; 4126cab3a1bSJed Brown void *functx; 4136cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4146cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4156cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4166cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 4176cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 4186cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 419caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 4206cab3a1bSJed Brown Mat J,B; 4216cab3a1bSJed Brown void *functx; 4226cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4236cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4246cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4256cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4266cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 4276cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr); 4286cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 4296cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 430caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 4316cab3a1bSJed Brown Mat J,B; 4326cab3a1bSJed Brown J = snes->jacobian; 4336cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4346cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 4356cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 4366cab3a1bSJed Brown } 437caa4e7f2SJed Brown { 43860a3618bSJed Brown PetscBool flg = PETSC_FALSE; 439caa4e7f2SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr); 440caa4e7f2SJed Brown if (flg) { /* Plan to transition to this model */ 441caa4e7f2SJed Brown KSP ksp; 442caa4e7f2SJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 443caa4e7f2SJed Brown ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr); 444dfe15315SJed Brown ierr = DMCoarsenHookAdd(snes->dm,PETSC_NULL,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 445caa4e7f2SJed Brown } 446caa4e7f2SJed Brown } 4476cab3a1bSJed Brown PetscFunctionReturn(0); 4486cab3a1bSJed Brown } 4496cab3a1bSJed Brown 4506cab3a1bSJed Brown #undef __FUNCT__ 4514a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 4529b94acceSBarry Smith /*@ 45394b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 4549b94acceSBarry Smith 455c7afd0dbSLois Curfman McInnes Collective on SNES 456c7afd0dbSLois Curfman McInnes 4579b94acceSBarry Smith Input Parameter: 4589b94acceSBarry Smith . snes - the SNES context 4599b94acceSBarry Smith 46036851e7fSLois Curfman McInnes Options Database Keys: 461ea630c6eSPeter Brune + -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas 46282738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 46382738288SBarry Smith of the change in the solution between steps 46470441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 465b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 466b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 467b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 4684839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 469ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 470a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 471e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 472b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 4732492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 47482738288SBarry Smith solver; hence iterations will continue until max_it 4751fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 47682738288SBarry Smith of convergence test 477e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 478e8105e01SRichard Katz filename given prints to stdout 479a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 480a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 481a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 482a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 483e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 4845968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 485fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 48682738288SBarry Smith 48782738288SBarry Smith Options Database for Eisenstat-Walker method: 488fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 4894b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 49036851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 49136851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 49236851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 49336851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 49436851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 49536851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 49682738288SBarry Smith 49711ca99fdSLois Curfman McInnes Notes: 49811ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 4990598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 50083e2fdc7SBarry Smith 50136851e7fSLois Curfman McInnes Level: beginner 50236851e7fSLois Curfman McInnes 5039b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 5049b94acceSBarry Smith 50569ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 5069b94acceSBarry Smith @*/ 5077087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 5089b94acceSBarry Smith { 509872b6db9SPeter Brune PetscBool flg,mf,mf_operator,pcset; 510efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 511aa3661deSLisandro Dalcin MatStructure matflag; 51285385478SLisandro Dalcin const char *deft = SNESLS; 51385385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 51485385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 515e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 51651e86f29SPeter Brune const char *optionsprefix; 517649052a6SBarry Smith PetscViewer monviewer; 51885385478SLisandro Dalcin PetscErrorCode ierr; 519c14b057cSPeter Brune DM dm; 5209b94acceSBarry Smith 5213a40ed3dSBarry Smith PetscFunctionBegin; 5220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 523ca161407SBarry Smith 524186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 5253194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 5267adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 527b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 528d64ed03dSBarry Smith if (flg) { 529186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 5307adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 531186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 532d64ed03dSBarry Smith } 53390d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 534909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 53593c39befSBarry Smith 536c60f73f4SPeter Brune ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr); 53757034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 538186905e3SBarry Smith 53957034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 540b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 541b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 54224254dc1SJed Brown ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 543ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 544acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 54585385478SLisandro Dalcin 546a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 547a8054027SBarry Smith if (flg) { 548a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 549a8054027SBarry Smith } 550e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 551e35cf81dSBarry Smith if (flg) { 552e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 553e35cf81dSBarry Smith } 554efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 555efd51863SBarry Smith if (flg) { 556efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 557efd51863SBarry Smith } 558a8054027SBarry Smith 55985385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 56085385478SLisandro Dalcin if (flg) { 56185385478SLisandro Dalcin switch (indx) { 5627f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 5637f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 56485385478SLisandro Dalcin } 56585385478SLisandro Dalcin } 56685385478SLisandro Dalcin 567acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 568186905e3SBarry Smith 569fdacfa88SPeter Brune ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr); 570fdacfa88SPeter Brune if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); } 571fdacfa88SPeter Brune 57285385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 57385385478SLisandro Dalcin 574acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 575186905e3SBarry Smith 576fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 577fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 578fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 579fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 580fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 581fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 582fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 583186905e3SBarry Smith 58490d69ab7SBarry Smith flg = PETSC_FALSE; 585acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 586a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 587eabae89aSBarry Smith 588a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 589e8105e01SRichard Katz if (flg) { 590649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 591649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 592e8105e01SRichard Katz } 593eabae89aSBarry Smith 594b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 595b271bb04SBarry Smith if (flg) { 596b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 597b271bb04SBarry Smith } 598b271bb04SBarry Smith 599a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 600eabae89aSBarry Smith if (flg) { 601649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 602f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 603e8105e01SRichard Katz } 604eabae89aSBarry Smith 605a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 606eabae89aSBarry Smith if (flg) { 607649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 608649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 609eabae89aSBarry Smith } 610eabae89aSBarry Smith 6115180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 6125180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 6135180491cSLisandro Dalcin 61490d69ab7SBarry Smith flg = PETSC_FALSE; 615acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 616a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 61790d69ab7SBarry Smith flg = PETSC_FALSE; 618acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 619a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 62090d69ab7SBarry Smith flg = PETSC_FALSE; 621acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 622a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 62390d69ab7SBarry Smith flg = PETSC_FALSE; 624acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 625a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 62690d69ab7SBarry Smith flg = PETSC_FALSE; 627acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 628b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 629e24b481bSBarry Smith 63090d69ab7SBarry Smith flg = PETSC_FALSE; 631acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 6324b27c08aSLois Curfman McInnes if (flg) { 6336cab3a1bSJed Brown void *functx; 6346cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 6356cab3a1bSJed Brown ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr); 636ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 6379b94acceSBarry Smith } 638639f9d9dSBarry Smith 639aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 640aa3661deSLisandro Dalcin flg = PETSC_FALSE; 641acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 642a8248277SBarry Smith if (flg && mf_operator) { 643a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 644a8248277SBarry Smith mf = PETSC_TRUE; 645a8248277SBarry Smith } 646aa3661deSLisandro Dalcin flg = PETSC_FALSE; 647acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 648aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 649aa3661deSLisandro Dalcin mf_version = 1; 650aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 651aa3661deSLisandro Dalcin 652d28543b3SPeter Brune 65389b92e6fSPeter Brune /* GS Options */ 65489b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 65589b92e6fSPeter Brune 65676b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 65776b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 65876b2cf59SMatthew Knepley } 65976b2cf59SMatthew Knepley 660e7788613SBarry Smith if (snes->ops->setfromoptions) { 661e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 662639f9d9dSBarry Smith } 6635d973c19SBarry Smith 6645d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 6655d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 666b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 6674bbc92c1SBarry Smith 668aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 6691cee3971SBarry Smith 6701cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 671aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 672aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 67385385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 67493993e2dSLois Curfman McInnes 6759e764e56SPeter Brune if (!snes->linesearch) { 676f1c6b773SPeter Brune ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 6779e764e56SPeter Brune } 678f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 6799e764e56SPeter Brune 68051e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 68151e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 68251e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 68351e86f29SPeter Brune if (pcset && (!snes->pc)) { 68451e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 68551e86f29SPeter Brune } 6864a0c5b0cSMatthew G Knepley if (snes->pc) { 687fde0ff24SPeter Brune ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr); 688fde0ff24SPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr); 689c14b057cSPeter Brune ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 690c14b057cSPeter Brune ierr = SNESSetDM(snes->pc, dm);CHKERRQ(ierr); 69188976e71SPeter Brune /* default to 1 iteration */ 69288976e71SPeter Brune ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr); 693534ebe21SPeter Brune ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 6944a0c5b0cSMatthew G Knepley ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 6954a0c5b0cSMatthew G Knepley } 6963a40ed3dSBarry Smith PetscFunctionReturn(0); 6979b94acceSBarry Smith } 6989b94acceSBarry Smith 699d25893d9SBarry Smith #undef __FUNCT__ 700d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 701d25893d9SBarry Smith /*@ 702d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 703d25893d9SBarry Smith the nonlinear solvers. 704d25893d9SBarry Smith 705d25893d9SBarry Smith Logically Collective on SNES 706d25893d9SBarry Smith 707d25893d9SBarry Smith Input Parameters: 708d25893d9SBarry Smith + snes - the SNES context 709d25893d9SBarry Smith . compute - function to compute the context 710d25893d9SBarry Smith - destroy - function to destroy the context 711d25893d9SBarry Smith 712d25893d9SBarry Smith Level: intermediate 713d25893d9SBarry Smith 714d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 715d25893d9SBarry Smith 716d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 717d25893d9SBarry Smith @*/ 718d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 719d25893d9SBarry Smith { 720d25893d9SBarry Smith PetscFunctionBegin; 721d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 722d25893d9SBarry Smith snes->ops->usercompute = compute; 723d25893d9SBarry Smith snes->ops->userdestroy = destroy; 724d25893d9SBarry Smith PetscFunctionReturn(0); 725d25893d9SBarry Smith } 726a847f771SSatish Balay 7274a2ae208SSatish Balay #undef __FUNCT__ 7284a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 729b07ff414SBarry Smith /*@ 7309b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 7319b94acceSBarry Smith the nonlinear solvers. 7329b94acceSBarry Smith 7333f9fe445SBarry Smith Logically Collective on SNES 734fee21e36SBarry Smith 735c7afd0dbSLois Curfman McInnes Input Parameters: 736c7afd0dbSLois Curfman McInnes + snes - the SNES context 737c7afd0dbSLois Curfman McInnes - usrP - optional user context 738c7afd0dbSLois Curfman McInnes 73936851e7fSLois Curfman McInnes Level: intermediate 74036851e7fSLois Curfman McInnes 7419b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 7429b94acceSBarry Smith 743*ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext() 7449b94acceSBarry Smith @*/ 7457087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 7469b94acceSBarry Smith { 7471b2093e4SBarry Smith PetscErrorCode ierr; 748b07ff414SBarry Smith KSP ksp; 7491b2093e4SBarry Smith 7503a40ed3dSBarry Smith PetscFunctionBegin; 7510700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 752b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 753b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 7549b94acceSBarry Smith snes->user = usrP; 7553a40ed3dSBarry Smith PetscFunctionReturn(0); 7569b94acceSBarry Smith } 75774679c65SBarry Smith 7584a2ae208SSatish Balay #undef __FUNCT__ 7594a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 760b07ff414SBarry Smith /*@ 7619b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 7629b94acceSBarry Smith nonlinear solvers. 7639b94acceSBarry Smith 764c7afd0dbSLois Curfman McInnes Not Collective 765c7afd0dbSLois Curfman McInnes 7669b94acceSBarry Smith Input Parameter: 7679b94acceSBarry Smith . snes - SNES context 7689b94acceSBarry Smith 7699b94acceSBarry Smith Output Parameter: 7709b94acceSBarry Smith . usrP - user context 7719b94acceSBarry Smith 77236851e7fSLois Curfman McInnes Level: intermediate 77336851e7fSLois Curfman McInnes 7749b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 7759b94acceSBarry Smith 7769b94acceSBarry Smith .seealso: SNESSetApplicationContext() 7779b94acceSBarry Smith @*/ 778e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 7799b94acceSBarry Smith { 7803a40ed3dSBarry Smith PetscFunctionBegin; 7810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 782e71120c6SJed Brown *(void**)usrP = snes->user; 7833a40ed3dSBarry Smith PetscFunctionReturn(0); 7849b94acceSBarry Smith } 78574679c65SBarry Smith 7864a2ae208SSatish Balay #undef __FUNCT__ 7874a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 7889b94acceSBarry Smith /*@ 789c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 790c8228a4eSBarry Smith at this time. 7919b94acceSBarry Smith 792c7afd0dbSLois Curfman McInnes Not Collective 793c7afd0dbSLois Curfman McInnes 7949b94acceSBarry Smith Input Parameter: 7959b94acceSBarry Smith . snes - SNES context 7969b94acceSBarry Smith 7979b94acceSBarry Smith Output Parameter: 7989b94acceSBarry Smith . iter - iteration number 7999b94acceSBarry Smith 800c8228a4eSBarry Smith Notes: 801c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 802c8228a4eSBarry Smith 803c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 80408405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 80508405cd6SLois Curfman McInnes .vb 80608405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 80708405cd6SLois Curfman McInnes if (!(it % 2)) { 80808405cd6SLois Curfman McInnes [compute Jacobian here] 80908405cd6SLois Curfman McInnes } 81008405cd6SLois Curfman McInnes .ve 811c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 81208405cd6SLois Curfman McInnes recomputed every second SNES iteration. 813c8228a4eSBarry Smith 81436851e7fSLois Curfman McInnes Level: intermediate 81536851e7fSLois Curfman McInnes 8162b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 8172b668275SBarry Smith 818b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 8199b94acceSBarry Smith @*/ 8207087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 8219b94acceSBarry Smith { 8223a40ed3dSBarry Smith PetscFunctionBegin; 8230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8244482741eSBarry Smith PetscValidIntPointer(iter,2); 8259b94acceSBarry Smith *iter = snes->iter; 8263a40ed3dSBarry Smith PetscFunctionReturn(0); 8279b94acceSBarry Smith } 82874679c65SBarry Smith 8294a2ae208SSatish Balay #undef __FUNCT__ 830360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 831360c497dSPeter Brune /*@ 832360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 833360c497dSPeter Brune 834360c497dSPeter Brune Not Collective 835360c497dSPeter Brune 836360c497dSPeter Brune Input Parameter: 837360c497dSPeter Brune . snes - SNES context 838360c497dSPeter Brune . iter - iteration number 839360c497dSPeter Brune 840360c497dSPeter Brune Level: developer 841360c497dSPeter Brune 842360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 843360c497dSPeter Brune 844360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 845360c497dSPeter Brune @*/ 846360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 847360c497dSPeter Brune { 848360c497dSPeter Brune PetscErrorCode ierr; 849360c497dSPeter Brune 850360c497dSPeter Brune PetscFunctionBegin; 851360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 852360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 853360c497dSPeter Brune snes->iter = iter; 854360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 855360c497dSPeter Brune PetscFunctionReturn(0); 856360c497dSPeter Brune } 857360c497dSPeter Brune 858360c497dSPeter Brune #undef __FUNCT__ 8594a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 8609b94acceSBarry Smith /*@ 8619b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 8629b94acceSBarry Smith with SNESSSetFunction(). 8639b94acceSBarry Smith 864c7afd0dbSLois Curfman McInnes Collective on SNES 865c7afd0dbSLois Curfman McInnes 8669b94acceSBarry Smith Input Parameter: 8679b94acceSBarry Smith . snes - SNES context 8689b94acceSBarry Smith 8699b94acceSBarry Smith Output Parameter: 8709b94acceSBarry Smith . fnorm - 2-norm of function 8719b94acceSBarry Smith 87236851e7fSLois Curfman McInnes Level: intermediate 87336851e7fSLois Curfman McInnes 8749b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 875a86d99e1SLois Curfman McInnes 876b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 8779b94acceSBarry Smith @*/ 8787087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 8799b94acceSBarry Smith { 8803a40ed3dSBarry Smith PetscFunctionBegin; 8810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8824482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 8839b94acceSBarry Smith *fnorm = snes->norm; 8843a40ed3dSBarry Smith PetscFunctionReturn(0); 8859b94acceSBarry Smith } 88674679c65SBarry Smith 887360c497dSPeter Brune 888360c497dSPeter Brune #undef __FUNCT__ 889360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 890360c497dSPeter Brune /*@ 891360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 892360c497dSPeter Brune 893360c497dSPeter Brune Collective on SNES 894360c497dSPeter Brune 895360c497dSPeter Brune Input Parameter: 896360c497dSPeter Brune . snes - SNES context 897360c497dSPeter Brune . fnorm - 2-norm of function 898360c497dSPeter Brune 899360c497dSPeter Brune Level: developer 900360c497dSPeter Brune 901360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 902360c497dSPeter Brune 903360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 904360c497dSPeter Brune @*/ 905360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 906360c497dSPeter Brune { 907360c497dSPeter Brune 908360c497dSPeter Brune PetscErrorCode ierr; 909360c497dSPeter Brune 910360c497dSPeter Brune PetscFunctionBegin; 911360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 912360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 913360c497dSPeter Brune snes->norm = fnorm; 914360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 915360c497dSPeter Brune PetscFunctionReturn(0); 916360c497dSPeter Brune } 917360c497dSPeter Brune 9184a2ae208SSatish Balay #undef __FUNCT__ 919b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 9209b94acceSBarry Smith /*@ 921b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 9229b94acceSBarry Smith attempted by the nonlinear solver. 9239b94acceSBarry Smith 924c7afd0dbSLois Curfman McInnes Not Collective 925c7afd0dbSLois Curfman McInnes 9269b94acceSBarry Smith Input Parameter: 9279b94acceSBarry Smith . snes - SNES context 9289b94acceSBarry Smith 9299b94acceSBarry Smith Output Parameter: 9309b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 9319b94acceSBarry Smith 932c96a6f78SLois Curfman McInnes Notes: 933c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 934c96a6f78SLois Curfman McInnes 93536851e7fSLois Curfman McInnes Level: intermediate 93636851e7fSLois Curfman McInnes 9379b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 93858ebbce7SBarry Smith 939e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 94058ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 9419b94acceSBarry Smith @*/ 9427087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 9439b94acceSBarry Smith { 9443a40ed3dSBarry Smith PetscFunctionBegin; 9450700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9464482741eSBarry Smith PetscValidIntPointer(nfails,2); 94750ffb88aSMatthew Knepley *nfails = snes->numFailures; 94850ffb88aSMatthew Knepley PetscFunctionReturn(0); 94950ffb88aSMatthew Knepley } 95050ffb88aSMatthew Knepley 95150ffb88aSMatthew Knepley #undef __FUNCT__ 952b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 95350ffb88aSMatthew Knepley /*@ 954b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 95550ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 95650ffb88aSMatthew Knepley 95750ffb88aSMatthew Knepley Not Collective 95850ffb88aSMatthew Knepley 95950ffb88aSMatthew Knepley Input Parameters: 96050ffb88aSMatthew Knepley + snes - SNES context 96150ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 96250ffb88aSMatthew Knepley 96350ffb88aSMatthew Knepley Level: intermediate 96450ffb88aSMatthew Knepley 96550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 96658ebbce7SBarry Smith 967e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 96858ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 96950ffb88aSMatthew Knepley @*/ 9707087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 97150ffb88aSMatthew Knepley { 97250ffb88aSMatthew Knepley PetscFunctionBegin; 9730700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 97450ffb88aSMatthew Knepley snes->maxFailures = maxFails; 97550ffb88aSMatthew Knepley PetscFunctionReturn(0); 97650ffb88aSMatthew Knepley } 97750ffb88aSMatthew Knepley 97850ffb88aSMatthew Knepley #undef __FUNCT__ 979b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 98050ffb88aSMatthew Knepley /*@ 981b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 98250ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 98350ffb88aSMatthew Knepley 98450ffb88aSMatthew Knepley Not Collective 98550ffb88aSMatthew Knepley 98650ffb88aSMatthew Knepley Input Parameter: 98750ffb88aSMatthew Knepley . snes - SNES context 98850ffb88aSMatthew Knepley 98950ffb88aSMatthew Knepley Output Parameter: 99050ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 99150ffb88aSMatthew Knepley 99250ffb88aSMatthew Knepley Level: intermediate 99350ffb88aSMatthew Knepley 99450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 99558ebbce7SBarry Smith 996e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 99758ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 99858ebbce7SBarry Smith 99950ffb88aSMatthew Knepley @*/ 10007087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 100150ffb88aSMatthew Knepley { 100250ffb88aSMatthew Knepley PetscFunctionBegin; 10030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10044482741eSBarry Smith PetscValidIntPointer(maxFails,2); 100550ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 10063a40ed3dSBarry Smith PetscFunctionReturn(0); 10079b94acceSBarry Smith } 1008a847f771SSatish Balay 10094a2ae208SSatish Balay #undef __FUNCT__ 10102541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 10112541af92SBarry Smith /*@ 10122541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 10132541af92SBarry Smith done by SNES. 10142541af92SBarry Smith 10152541af92SBarry Smith Not Collective 10162541af92SBarry Smith 10172541af92SBarry Smith Input Parameter: 10182541af92SBarry Smith . snes - SNES context 10192541af92SBarry Smith 10202541af92SBarry Smith Output Parameter: 10212541af92SBarry Smith . nfuncs - number of evaluations 10222541af92SBarry Smith 10232541af92SBarry Smith Level: intermediate 10242541af92SBarry Smith 10252541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 102658ebbce7SBarry Smith 1027e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 10282541af92SBarry Smith @*/ 10297087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 10302541af92SBarry Smith { 10312541af92SBarry Smith PetscFunctionBegin; 10320700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10332541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 10342541af92SBarry Smith *nfuncs = snes->nfuncs; 10352541af92SBarry Smith PetscFunctionReturn(0); 10362541af92SBarry Smith } 10372541af92SBarry Smith 10382541af92SBarry Smith #undef __FUNCT__ 10393d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 10403d4c4710SBarry Smith /*@ 10413d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 10423d4c4710SBarry Smith linear solvers. 10433d4c4710SBarry Smith 10443d4c4710SBarry Smith Not Collective 10453d4c4710SBarry Smith 10463d4c4710SBarry Smith Input Parameter: 10473d4c4710SBarry Smith . snes - SNES context 10483d4c4710SBarry Smith 10493d4c4710SBarry Smith Output Parameter: 10503d4c4710SBarry Smith . nfails - number of failed solves 10513d4c4710SBarry Smith 10523d4c4710SBarry Smith Notes: 10533d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 10543d4c4710SBarry Smith 10553d4c4710SBarry Smith Level: intermediate 10563d4c4710SBarry Smith 10573d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 105858ebbce7SBarry Smith 1059e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 10603d4c4710SBarry Smith @*/ 10617087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 10623d4c4710SBarry Smith { 10633d4c4710SBarry Smith PetscFunctionBegin; 10640700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10653d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 10663d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 10673d4c4710SBarry Smith PetscFunctionReturn(0); 10683d4c4710SBarry Smith } 10693d4c4710SBarry Smith 10703d4c4710SBarry Smith #undef __FUNCT__ 10713d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 10723d4c4710SBarry Smith /*@ 10733d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 10743d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 10753d4c4710SBarry Smith 10763f9fe445SBarry Smith Logically Collective on SNES 10773d4c4710SBarry Smith 10783d4c4710SBarry Smith Input Parameters: 10793d4c4710SBarry Smith + snes - SNES context 10803d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 10813d4c4710SBarry Smith 10823d4c4710SBarry Smith Level: intermediate 10833d4c4710SBarry Smith 1084a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 10853d4c4710SBarry Smith 10863d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 10873d4c4710SBarry Smith 108858ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 10893d4c4710SBarry Smith @*/ 10907087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 10913d4c4710SBarry Smith { 10923d4c4710SBarry Smith PetscFunctionBegin; 10930700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1094c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 10953d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 10963d4c4710SBarry Smith PetscFunctionReturn(0); 10973d4c4710SBarry Smith } 10983d4c4710SBarry Smith 10993d4c4710SBarry Smith #undef __FUNCT__ 11003d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 11013d4c4710SBarry Smith /*@ 11023d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 11033d4c4710SBarry Smith are allowed before SNES terminates 11043d4c4710SBarry Smith 11053d4c4710SBarry Smith Not Collective 11063d4c4710SBarry Smith 11073d4c4710SBarry Smith Input Parameter: 11083d4c4710SBarry Smith . snes - SNES context 11093d4c4710SBarry Smith 11103d4c4710SBarry Smith Output Parameter: 11113d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 11123d4c4710SBarry Smith 11133d4c4710SBarry Smith Level: intermediate 11143d4c4710SBarry Smith 11153d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 11163d4c4710SBarry Smith 11173d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 11183d4c4710SBarry Smith 1119e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 11203d4c4710SBarry Smith @*/ 11217087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 11223d4c4710SBarry Smith { 11233d4c4710SBarry Smith PetscFunctionBegin; 11240700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11253d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 11263d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 11273d4c4710SBarry Smith PetscFunctionReturn(0); 11283d4c4710SBarry Smith } 11293d4c4710SBarry Smith 11303d4c4710SBarry Smith #undef __FUNCT__ 1131b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1132c96a6f78SLois Curfman McInnes /*@ 1133b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1134c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1135c96a6f78SLois Curfman McInnes 1136c7afd0dbSLois Curfman McInnes Not Collective 1137c7afd0dbSLois Curfman McInnes 1138c96a6f78SLois Curfman McInnes Input Parameter: 1139c96a6f78SLois Curfman McInnes . snes - SNES context 1140c96a6f78SLois Curfman McInnes 1141c96a6f78SLois Curfman McInnes Output Parameter: 1142c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1143c96a6f78SLois Curfman McInnes 1144c96a6f78SLois Curfman McInnes Notes: 1145c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1146c96a6f78SLois Curfman McInnes 114736851e7fSLois Curfman McInnes Level: intermediate 114836851e7fSLois Curfman McInnes 1149c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 11502b668275SBarry Smith 11518c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1152c96a6f78SLois Curfman McInnes @*/ 11537087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1154c96a6f78SLois Curfman McInnes { 11553a40ed3dSBarry Smith PetscFunctionBegin; 11560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11574482741eSBarry Smith PetscValidIntPointer(lits,2); 1158c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 11593a40ed3dSBarry Smith PetscFunctionReturn(0); 1160c96a6f78SLois Curfman McInnes } 1161c96a6f78SLois Curfman McInnes 11624a2ae208SSatish Balay #undef __FUNCT__ 116394b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 116452baeb72SSatish Balay /*@ 116594b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 11669b94acceSBarry Smith 116794b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1168c7afd0dbSLois Curfman McInnes 11699b94acceSBarry Smith Input Parameter: 11709b94acceSBarry Smith . snes - the SNES context 11719b94acceSBarry Smith 11729b94acceSBarry Smith Output Parameter: 117394b7f48cSBarry Smith . ksp - the KSP context 11749b94acceSBarry Smith 11759b94acceSBarry Smith Notes: 117694b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 11779b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 11782999313aSBarry Smith PC contexts as well. 11799b94acceSBarry Smith 118036851e7fSLois Curfman McInnes Level: beginner 118136851e7fSLois Curfman McInnes 118294b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11839b94acceSBarry Smith 11842999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11859b94acceSBarry Smith @*/ 11867087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 11879b94acceSBarry Smith { 11881cee3971SBarry Smith PetscErrorCode ierr; 11891cee3971SBarry Smith 11903a40ed3dSBarry Smith PetscFunctionBegin; 11910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11924482741eSBarry Smith PetscValidPointer(ksp,2); 11931cee3971SBarry Smith 11941cee3971SBarry Smith if (!snes->ksp) { 11951cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 11961cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 11971cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 11981cee3971SBarry Smith } 119994b7f48cSBarry Smith *ksp = snes->ksp; 12003a40ed3dSBarry Smith PetscFunctionReturn(0); 12019b94acceSBarry Smith } 120282bf6240SBarry Smith 12034a2ae208SSatish Balay #undef __FUNCT__ 12042999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 12052999313aSBarry Smith /*@ 12062999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 12072999313aSBarry Smith 12082999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 12092999313aSBarry Smith 12102999313aSBarry Smith Input Parameters: 12112999313aSBarry Smith + snes - the SNES context 12122999313aSBarry Smith - ksp - the KSP context 12132999313aSBarry Smith 12142999313aSBarry Smith Notes: 12152999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 12162999313aSBarry Smith so this routine is rarely needed. 12172999313aSBarry Smith 12182999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 12192999313aSBarry Smith decreased by one. 12202999313aSBarry Smith 12212999313aSBarry Smith Level: developer 12222999313aSBarry Smith 12232999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 12242999313aSBarry Smith 12252999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 12262999313aSBarry Smith @*/ 12277087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 12282999313aSBarry Smith { 12292999313aSBarry Smith PetscErrorCode ierr; 12302999313aSBarry Smith 12312999313aSBarry Smith PetscFunctionBegin; 12320700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12330700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 12342999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 12357dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1236906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 12372999313aSBarry Smith snes->ksp = ksp; 12382999313aSBarry Smith PetscFunctionReturn(0); 12392999313aSBarry Smith } 12402999313aSBarry Smith 12417adad957SLisandro Dalcin #if 0 12422999313aSBarry Smith #undef __FUNCT__ 12434a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 12446849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1245e24b481bSBarry Smith { 1246e24b481bSBarry Smith PetscFunctionBegin; 1247e24b481bSBarry Smith PetscFunctionReturn(0); 1248e24b481bSBarry Smith } 12497adad957SLisandro Dalcin #endif 1250e24b481bSBarry Smith 12519b94acceSBarry Smith /* -----------------------------------------------------------*/ 12524a2ae208SSatish Balay #undef __FUNCT__ 12534a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 125452baeb72SSatish Balay /*@ 12559b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 12569b94acceSBarry Smith 1257c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1258c7afd0dbSLois Curfman McInnes 1259c7afd0dbSLois Curfman McInnes Input Parameters: 1260906ed7ccSBarry Smith . comm - MPI communicator 12619b94acceSBarry Smith 12629b94acceSBarry Smith Output Parameter: 12639b94acceSBarry Smith . outsnes - the new SNES context 12649b94acceSBarry Smith 1265c7afd0dbSLois Curfman McInnes Options Database Keys: 1266c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1267c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1268c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1269c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1270c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1271c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1272c1f60f51SBarry Smith 127336851e7fSLois Curfman McInnes Level: beginner 127436851e7fSLois Curfman McInnes 12759b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 12769b94acceSBarry Smith 1277a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1278a8054027SBarry Smith 12799b94acceSBarry Smith @*/ 12807087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 12819b94acceSBarry Smith { 1282dfbe8321SBarry Smith PetscErrorCode ierr; 12839b94acceSBarry Smith SNES snes; 1284fa9f3622SBarry Smith SNESKSPEW *kctx; 128537fcc0dbSBarry Smith 12863a40ed3dSBarry Smith PetscFunctionBegin; 1287ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 12888ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 12898ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 12908ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 12918ba1e511SMatthew Knepley #endif 12928ba1e511SMatthew Knepley 12933194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 12947adad957SLisandro Dalcin 129585385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 12962c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 129788976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 12989b94acceSBarry Smith snes->max_its = 50; 12999750a799SBarry Smith snes->max_funcs = 10000; 13009b94acceSBarry Smith snes->norm = 0.0; 1301fdacfa88SPeter Brune snes->normtype = SNES_NORM_FUNCTION; 1302b4874afaSBarry Smith snes->rtol = 1.e-8; 1303b4874afaSBarry Smith snes->ttol = 0.0; 130470441072SBarry Smith snes->abstol = 1.e-50; 1305c60f73f4SPeter Brune snes->stol = 1.e-8; 13064b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 13079b94acceSBarry Smith snes->nfuncs = 0; 130850ffb88aSMatthew Knepley snes->numFailures = 0; 130950ffb88aSMatthew Knepley snes->maxFailures = 1; 13107a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1311e35cf81dSBarry Smith snes->lagjacobian = 1; 1312a8054027SBarry Smith snes->lagpreconditioner = 1; 1313639f9d9dSBarry Smith snes->numbermonitors = 0; 13149b94acceSBarry Smith snes->data = 0; 13154dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1316186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 13176f24a144SLois Curfman McInnes snes->nwork = 0; 131858c9b817SLisandro Dalcin snes->work = 0; 131958c9b817SLisandro Dalcin snes->nvwork = 0; 132058c9b817SLisandro Dalcin snes->vwork = 0; 1321758f92a0SBarry Smith snes->conv_hist_len = 0; 1322758f92a0SBarry Smith snes->conv_hist_max = 0; 1323758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1324758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1325758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1326e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1327e4ed7901SPeter Brune snes->norm_init = 0.; 1328e4ed7901SPeter Brune snes->norm_init_set = PETSC_FALSE; 1329184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 133089b92e6fSPeter Brune snes->gssweeps = 1; 13319b94acceSBarry Smith 13323d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 13333d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 13343d4c4710SBarry Smith 13359b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 133638f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 13379b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 13389b94acceSBarry Smith kctx->version = 2; 13399b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 13409b94acceSBarry Smith this was too large for some test cases */ 134175567043SBarry Smith kctx->rtol_last = 0.0; 13429b94acceSBarry Smith kctx->rtol_max = .9; 13439b94acceSBarry Smith kctx->gamma = 1.0; 134462d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 134571f87433Sdalcinl kctx->alpha2 = kctx->alpha; 13469b94acceSBarry Smith kctx->threshold = .1; 134775567043SBarry Smith kctx->lresid_last = 0.0; 134875567043SBarry Smith kctx->norm_last = 0.0; 13499b94acceSBarry Smith 13509b94acceSBarry Smith *outsnes = snes; 13513a40ed3dSBarry Smith PetscFunctionReturn(0); 13529b94acceSBarry Smith } 13539b94acceSBarry Smith 13544a2ae208SSatish Balay #undef __FUNCT__ 13554a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 13569b94acceSBarry Smith /*@C 13579b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 13589b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 13599b94acceSBarry Smith equations. 13609b94acceSBarry Smith 13613f9fe445SBarry Smith Logically Collective on SNES 1362fee21e36SBarry Smith 1363c7afd0dbSLois Curfman McInnes Input Parameters: 1364c7afd0dbSLois Curfman McInnes + snes - the SNES context 1365c7afd0dbSLois Curfman McInnes . r - vector to store function value 1366de044059SHong Zhang . func - function evaluation routine 1367c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1368c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 13699b94acceSBarry Smith 1370c7afd0dbSLois Curfman McInnes Calling sequence of func: 13718d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1372c7afd0dbSLois Curfman McInnes 1373c586c404SJed Brown + snes - the SNES context 1374c586c404SJed Brown . x - state at which to evaluate residual 1375c586c404SJed Brown . f - vector to put residual 1376c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 13779b94acceSBarry Smith 13789b94acceSBarry Smith Notes: 13799b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 13809b94acceSBarry Smith $ f'(x) x = -f(x), 1381c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 13829b94acceSBarry Smith 138336851e7fSLois Curfman McInnes Level: beginner 138436851e7fSLois Curfman McInnes 13859b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 13869b94acceSBarry Smith 13878b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 13889b94acceSBarry Smith @*/ 13897087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 13909b94acceSBarry Smith { 139185385478SLisandro Dalcin PetscErrorCode ierr; 13926cab3a1bSJed Brown DM dm; 13936cab3a1bSJed Brown 13943a40ed3dSBarry Smith PetscFunctionBegin; 13950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1396d2a683ecSLisandro Dalcin if (r) { 1397d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1398d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 139985385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 14006bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 140185385478SLisandro Dalcin snes->vec_func = r; 1402d2a683ecSLisandro Dalcin } 14036cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 14046cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 14053a40ed3dSBarry Smith PetscFunctionReturn(0); 14069b94acceSBarry Smith } 14079b94acceSBarry Smith 1408646217ecSPeter Brune 1409646217ecSPeter Brune #undef __FUNCT__ 1410e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction" 1411e4ed7901SPeter Brune /*@C 1412e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1413e4ed7901SPeter Brune function norm at the initialization of the method. In some 1414e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1415e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1416e4ed7901SPeter Brune to SNESComputeFunction in that case. 1417e4ed7901SPeter Brune 1418e4ed7901SPeter Brune Logically Collective on SNES 1419e4ed7901SPeter Brune 1420e4ed7901SPeter Brune Input Parameters: 1421e4ed7901SPeter Brune + snes - the SNES context 1422e4ed7901SPeter Brune - f - vector to store function value 1423e4ed7901SPeter Brune 1424e4ed7901SPeter Brune Notes: 1425e4ed7901SPeter Brune This should not be modified during the solution procedure. 1426e4ed7901SPeter Brune 1427e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1428e4ed7901SPeter Brune 1429e4ed7901SPeter Brune Level: developer 1430e4ed7901SPeter Brune 1431e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function 1432e4ed7901SPeter Brune 1433e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1434e4ed7901SPeter Brune @*/ 1435e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1436e4ed7901SPeter Brune { 1437e4ed7901SPeter Brune PetscErrorCode ierr; 1438e4ed7901SPeter Brune Vec vec_func; 1439e4ed7901SPeter Brune 1440e4ed7901SPeter Brune PetscFunctionBegin; 1441e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1442e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1443e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 1444e4ed7901SPeter Brune ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1445e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1446217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1447e4ed7901SPeter Brune PetscFunctionReturn(0); 1448e4ed7901SPeter Brune } 1449e4ed7901SPeter Brune 1450e4ed7901SPeter Brune 1451e4ed7901SPeter Brune #undef __FUNCT__ 1452e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm" 1453e4ed7901SPeter Brune /*@C 1454e4ed7901SPeter Brune SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm 1455e4ed7901SPeter Brune at the initialization of the method. In some instances, the user has precomputed 1456e4ed7901SPeter Brune the function and its norm before calling SNESSolve. This function allows one to 1457e4ed7901SPeter Brune avoid a redundant call to SNESComputeFunction() and VecNorm() in that case. 1458e4ed7901SPeter Brune 1459e4ed7901SPeter Brune Logically Collective on SNES 1460e4ed7901SPeter Brune 1461e4ed7901SPeter Brune Input Parameters: 1462e4ed7901SPeter Brune + snes - the SNES context 1463e4ed7901SPeter Brune - fnorm - the norm of F as set by SNESSetInitialFunction() 1464e4ed7901SPeter Brune 1465e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1466e4ed7901SPeter Brune 1467e4ed7901SPeter Brune Level: developer 1468e4ed7901SPeter Brune 1469e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm 1470e4ed7901SPeter Brune 1471e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction() 1472e4ed7901SPeter Brune @*/ 1473e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm) 1474e4ed7901SPeter Brune { 1475e4ed7901SPeter Brune PetscFunctionBegin; 1476e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1477e4ed7901SPeter Brune snes->norm_init = fnorm; 1478e4ed7901SPeter Brune snes->norm_init_set = PETSC_TRUE; 1479e4ed7901SPeter Brune PetscFunctionReturn(0); 1480e4ed7901SPeter Brune } 1481e4ed7901SPeter Brune 1482e4ed7901SPeter Brune #undef __FUNCT__ 1483534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType" 1484534ebe21SPeter Brune /*@ 1485534ebe21SPeter Brune SNESSetNormType - Sets the SNESNormType used in covergence and monitoring 1486534ebe21SPeter Brune of the SNES method. 1487534ebe21SPeter Brune 1488534ebe21SPeter Brune Logically Collective on SNES 1489534ebe21SPeter Brune 1490534ebe21SPeter Brune Input Parameters: 1491534ebe21SPeter Brune + snes - the SNES context 1492534ebe21SPeter Brune - normtype - the type of the norm used 1493534ebe21SPeter Brune 1494534ebe21SPeter Brune Notes: 1495534ebe21SPeter Brune Only certain SNES methods support certain SNESNormTypes. Most require evaluation 1496534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1497534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1498534ebe21SPeter Brune (SNESGS) and the like do not require the norm of the function to be computed, and therfore 1499534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1500534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1501534ebe21SPeter Brune their solution. 1502534ebe21SPeter Brune 1503534ebe21SPeter Brune Level: developer 1504534ebe21SPeter Brune 1505534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1506534ebe21SPeter Brune 1507534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1508534ebe21SPeter Brune @*/ 1509534ebe21SPeter Brune PetscErrorCode SNESSetNormType(SNES snes, SNESNormType normtype) 1510534ebe21SPeter Brune { 1511534ebe21SPeter Brune PetscFunctionBegin; 1512534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1513534ebe21SPeter Brune snes->normtype = normtype; 1514534ebe21SPeter Brune PetscFunctionReturn(0); 1515534ebe21SPeter Brune } 1516534ebe21SPeter Brune 1517534ebe21SPeter Brune 1518534ebe21SPeter Brune #undef __FUNCT__ 1519534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType" 1520534ebe21SPeter Brune /*@ 1521534ebe21SPeter Brune SNESGetNormType - Gets the SNESNormType used in covergence and monitoring 1522534ebe21SPeter Brune of the SNES method. 1523534ebe21SPeter Brune 1524534ebe21SPeter Brune Logically Collective on SNES 1525534ebe21SPeter Brune 1526534ebe21SPeter Brune Input Parameters: 1527534ebe21SPeter Brune + snes - the SNES context 1528534ebe21SPeter Brune - normtype - the type of the norm used 1529534ebe21SPeter Brune 1530534ebe21SPeter Brune Level: advanced 1531534ebe21SPeter Brune 1532534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1533534ebe21SPeter Brune 1534534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1535534ebe21SPeter Brune @*/ 1536534ebe21SPeter Brune PetscErrorCode SNESGetNormType(SNES snes, SNESNormType *normtype) 1537534ebe21SPeter Brune { 1538534ebe21SPeter Brune PetscFunctionBegin; 1539534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1540534ebe21SPeter Brune *normtype = snes->normtype; 1541534ebe21SPeter Brune PetscFunctionReturn(0); 1542534ebe21SPeter Brune } 1543534ebe21SPeter Brune 1544534ebe21SPeter Brune #undef __FUNCT__ 1545646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1546c79ef259SPeter Brune /*@C 1547c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1548c79ef259SPeter Brune use with composed nonlinear solvers. 1549c79ef259SPeter Brune 1550c79ef259SPeter Brune Input Parameters: 1551c79ef259SPeter Brune + snes - the SNES context 1552c79ef259SPeter Brune . gsfunc - function evaluation routine 1553c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1554c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1555c79ef259SPeter Brune 1556c79ef259SPeter Brune Calling sequence of func: 1557c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1558c79ef259SPeter Brune 1559c79ef259SPeter Brune + X - solution vector 1560c79ef259SPeter Brune . B - RHS vector 1561d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1562c79ef259SPeter Brune 1563c79ef259SPeter Brune Notes: 1564c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1565c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1566c79ef259SPeter Brune 1567d28543b3SPeter Brune Level: intermediate 1568c79ef259SPeter Brune 1569d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1570c79ef259SPeter Brune 1571c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1572c79ef259SPeter Brune @*/ 15736cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 15746cab3a1bSJed Brown { 15756cab3a1bSJed Brown PetscErrorCode ierr; 15766cab3a1bSJed Brown DM dm; 15776cab3a1bSJed Brown 1578646217ecSPeter Brune PetscFunctionBegin; 15796cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15806cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 15816cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1582646217ecSPeter Brune PetscFunctionReturn(0); 1583646217ecSPeter Brune } 1584646217ecSPeter Brune 1585d25893d9SBarry Smith #undef __FUNCT__ 158689b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 158789b92e6fSPeter Brune /*@ 158889b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 158989b92e6fSPeter Brune 159089b92e6fSPeter Brune Input Parameters: 159189b92e6fSPeter Brune + snes - the SNES context 159289b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 159389b92e6fSPeter Brune 159489b92e6fSPeter Brune Level: intermediate 159589b92e6fSPeter Brune 159689b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 159789b92e6fSPeter Brune 159889b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 159989b92e6fSPeter Brune @*/ 160089b92e6fSPeter Brune 160189b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 160289b92e6fSPeter Brune PetscFunctionBegin; 160389b92e6fSPeter Brune snes->gssweeps = sweeps; 160489b92e6fSPeter Brune PetscFunctionReturn(0); 160589b92e6fSPeter Brune } 160689b92e6fSPeter Brune 160789b92e6fSPeter Brune 160889b92e6fSPeter Brune #undef __FUNCT__ 160989b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 161089b92e6fSPeter Brune /*@ 161189b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 161289b92e6fSPeter Brune 161389b92e6fSPeter Brune Input Parameters: 161489b92e6fSPeter Brune . snes - the SNES context 161589b92e6fSPeter Brune 161689b92e6fSPeter Brune Output Parameters: 161789b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 161889b92e6fSPeter Brune 161989b92e6fSPeter Brune Level: intermediate 162089b92e6fSPeter Brune 162189b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 162289b92e6fSPeter Brune 162389b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 162489b92e6fSPeter Brune @*/ 162589b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 162689b92e6fSPeter Brune PetscFunctionBegin; 162789b92e6fSPeter Brune *sweeps = snes->gssweeps; 162889b92e6fSPeter Brune PetscFunctionReturn(0); 162989b92e6fSPeter Brune } 163089b92e6fSPeter Brune 163189b92e6fSPeter Brune #undef __FUNCT__ 16328b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 16338b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 16348b0a5094SBarry Smith { 16358b0a5094SBarry Smith PetscErrorCode ierr; 16366cab3a1bSJed Brown void *functx,*jacctx; 16376cab3a1bSJed Brown 16388b0a5094SBarry Smith PetscFunctionBegin; 16396cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 16406cab3a1bSJed Brown ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr); 16418b0a5094SBarry Smith /* A(x)*x - b(x) */ 16426cab3a1bSJed Brown ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr); 16436cab3a1bSJed Brown ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr); 16448b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16458b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16468b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 16478b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 16488b0a5094SBarry Smith PetscFunctionReturn(0); 16498b0a5094SBarry Smith } 16508b0a5094SBarry Smith 16518b0a5094SBarry Smith #undef __FUNCT__ 16528b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 16538b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 16548b0a5094SBarry Smith { 16558b0a5094SBarry Smith PetscFunctionBegin; 16568b0a5094SBarry Smith *flag = snes->matstruct; 16578b0a5094SBarry Smith PetscFunctionReturn(0); 16588b0a5094SBarry Smith } 16598b0a5094SBarry Smith 16608b0a5094SBarry Smith #undef __FUNCT__ 16618b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 16628b0a5094SBarry Smith /*@C 16630d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 16648b0a5094SBarry Smith 16658b0a5094SBarry Smith Logically Collective on SNES 16668b0a5094SBarry Smith 16678b0a5094SBarry Smith Input Parameters: 16688b0a5094SBarry Smith + snes - the SNES context 16698b0a5094SBarry Smith . r - vector to store function value 16708b0a5094SBarry Smith . func - function evaluation routine 16718b0a5094SBarry Smith . jmat - normally the same as mat but you can pass another matrix for which you compute the Jacobian of A(x) x - b(x) (see jmat below) 16728b0a5094SBarry Smith . mat - matrix to store A 16738b0a5094SBarry Smith . mfunc - function to compute matrix value 16748b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 16758b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 16768b0a5094SBarry Smith 16778b0a5094SBarry Smith Calling sequence of func: 16788b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 16798b0a5094SBarry Smith 16808b0a5094SBarry Smith + f - function vector 16818b0a5094SBarry Smith - ctx - optional user-defined function context 16828b0a5094SBarry Smith 16838b0a5094SBarry Smith Calling sequence of mfunc: 16848b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 16858b0a5094SBarry Smith 16868b0a5094SBarry Smith + x - input vector 16878b0a5094SBarry Smith . jmat - Form Jacobian matrix of A(x) x - b(x) if available, not there is really no reason to use it in this way since then you can just use SNESSetJacobian(), 16888b0a5094SBarry Smith normally just pass mat in this location 16898b0a5094SBarry Smith . mat - form A(x) matrix 16908b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 16918b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 16928b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 16938b0a5094SBarry Smith 16948b0a5094SBarry Smith Notes: 16958b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 16968b0a5094SBarry Smith 16978b0a5094SBarry 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} 16988b0a5094SBarry 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. 16998b0a5094SBarry Smith 17008b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 17018b0a5094SBarry Smith 17020d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 17030d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 17048b0a5094SBarry Smith 17058b0a5094SBarry 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 17068b0a5094SBarry 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 17078b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 17088b0a5094SBarry Smith 17098b0a5094SBarry Smith Level: beginner 17108b0a5094SBarry Smith 17118b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 17128b0a5094SBarry Smith 17130d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 17148b0a5094SBarry Smith @*/ 17158b0a5094SBarry Smith PetscErrorCode SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),Mat jmat, Mat mat, PetscErrorCode (*mfunc)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 17168b0a5094SBarry Smith { 17178b0a5094SBarry Smith PetscErrorCode ierr; 17188b0a5094SBarry Smith PetscFunctionBegin; 17198b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17208b0a5094SBarry Smith snes->ops->computepfunction = func; 17218b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 17228b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 17238b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 17248b0a5094SBarry Smith PetscFunctionReturn(0); 17258b0a5094SBarry Smith } 17268b0a5094SBarry Smith 17278b0a5094SBarry Smith #undef __FUNCT__ 1728d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1729d25893d9SBarry Smith /*@C 1730d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1731d25893d9SBarry Smith 1732d25893d9SBarry Smith Logically Collective on SNES 1733d25893d9SBarry Smith 1734d25893d9SBarry Smith Input Parameters: 1735d25893d9SBarry Smith + snes - the SNES context 1736d25893d9SBarry Smith . func - function evaluation routine 1737d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1738d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1739d25893d9SBarry Smith 1740d25893d9SBarry Smith Calling sequence of func: 1741d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1742d25893d9SBarry Smith 1743d25893d9SBarry Smith . f - function vector 1744d25893d9SBarry Smith - ctx - optional user-defined function context 1745d25893d9SBarry Smith 1746d25893d9SBarry Smith Level: intermediate 1747d25893d9SBarry Smith 1748d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1749d25893d9SBarry Smith 1750d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1751d25893d9SBarry Smith @*/ 1752d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1753d25893d9SBarry Smith { 1754d25893d9SBarry Smith PetscFunctionBegin; 1755d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1756d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1757d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1758d25893d9SBarry Smith PetscFunctionReturn(0); 1759d25893d9SBarry Smith } 1760d25893d9SBarry Smith 17613ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 17623ab0aad5SBarry Smith #undef __FUNCT__ 17631096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 17641096aae1SMatthew Knepley /*@C 17651096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 17661096aae1SMatthew Knepley it assumes a zero right hand side. 17671096aae1SMatthew Knepley 17683f9fe445SBarry Smith Logically Collective on SNES 17691096aae1SMatthew Knepley 17701096aae1SMatthew Knepley Input Parameter: 17711096aae1SMatthew Knepley . snes - the SNES context 17721096aae1SMatthew Knepley 17731096aae1SMatthew Knepley Output Parameter: 1774bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 17751096aae1SMatthew Knepley 17761096aae1SMatthew Knepley Level: intermediate 17771096aae1SMatthew Knepley 17781096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 17791096aae1SMatthew Knepley 178085385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 17811096aae1SMatthew Knepley @*/ 17827087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 17831096aae1SMatthew Knepley { 17841096aae1SMatthew Knepley PetscFunctionBegin; 17850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17861096aae1SMatthew Knepley PetscValidPointer(rhs,2); 178785385478SLisandro Dalcin *rhs = snes->vec_rhs; 17881096aae1SMatthew Knepley PetscFunctionReturn(0); 17891096aae1SMatthew Knepley } 17901096aae1SMatthew Knepley 17911096aae1SMatthew Knepley #undef __FUNCT__ 17924a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 17939b94acceSBarry Smith /*@ 179436851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 17959b94acceSBarry Smith SNESSetFunction(). 17969b94acceSBarry Smith 1797c7afd0dbSLois Curfman McInnes Collective on SNES 1798c7afd0dbSLois Curfman McInnes 17999b94acceSBarry Smith Input Parameters: 1800c7afd0dbSLois Curfman McInnes + snes - the SNES context 1801c7afd0dbSLois Curfman McInnes - x - input vector 18029b94acceSBarry Smith 18039b94acceSBarry Smith Output Parameter: 18043638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 18059b94acceSBarry Smith 18061bffabb2SLois Curfman McInnes Notes: 180736851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 180836851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 180936851e7fSLois Curfman McInnes themselves. 181036851e7fSLois Curfman McInnes 181136851e7fSLois Curfman McInnes Level: developer 181236851e7fSLois Curfman McInnes 18139b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 18149b94acceSBarry Smith 1815a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 18169b94acceSBarry Smith @*/ 18177087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 18189b94acceSBarry Smith { 1819dfbe8321SBarry Smith PetscErrorCode ierr; 18206cab3a1bSJed Brown DM dm; 18216cab3a1bSJed Brown SNESDM sdm; 18229b94acceSBarry Smith 18233a40ed3dSBarry Smith PetscFunctionBegin; 18240700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18250700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 18260700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1827c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1828c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 18294ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1830184914b5SBarry Smith 18316cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18326cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1833d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18346cab3a1bSJed Brown if (sdm->computefunction) { 1835d64ed03dSBarry Smith PetscStackPush("SNES user function"); 18366cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1837d64ed03dSBarry Smith PetscStackPop; 183873250ac0SBarry Smith } else if (snes->dm) { 1839644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1840c90fad12SPeter Brune } else if (snes->vec_rhs) { 1841c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1842644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 184385385478SLisandro Dalcin if (snes->vec_rhs) { 184485385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 18453ab0aad5SBarry Smith } 1846ae3c334cSLois Curfman McInnes snes->nfuncs++; 1847d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18484ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 18493a40ed3dSBarry Smith PetscFunctionReturn(0); 18509b94acceSBarry Smith } 18519b94acceSBarry Smith 18524a2ae208SSatish Balay #undef __FUNCT__ 1853646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1854c79ef259SPeter Brune /*@ 1855c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1856c79ef259SPeter Brune SNESSetGS(). 1857c79ef259SPeter Brune 1858c79ef259SPeter Brune Collective on SNES 1859c79ef259SPeter Brune 1860c79ef259SPeter Brune Input Parameters: 1861c79ef259SPeter Brune + snes - the SNES context 1862c79ef259SPeter Brune . x - input vector 1863c79ef259SPeter Brune - b - rhs vector 1864c79ef259SPeter Brune 1865c79ef259SPeter Brune Output Parameter: 1866c79ef259SPeter Brune . x - new solution vector 1867c79ef259SPeter Brune 1868c79ef259SPeter Brune Notes: 1869c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1870c79ef259SPeter Brune implementations, so most users would not generally call this routine 1871c79ef259SPeter Brune themselves. 1872c79ef259SPeter Brune 1873c79ef259SPeter Brune Level: developer 1874c79ef259SPeter Brune 1875c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1876c79ef259SPeter Brune 1877c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1878c79ef259SPeter Brune @*/ 1879646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1880646217ecSPeter Brune { 1881646217ecSPeter Brune PetscErrorCode ierr; 188289b92e6fSPeter Brune PetscInt i; 18836cab3a1bSJed Brown DM dm; 18846cab3a1bSJed Brown SNESDM sdm; 1885646217ecSPeter Brune 1886646217ecSPeter Brune PetscFunctionBegin; 1887646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1888646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1889646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1890646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1891646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 18924ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1893701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 18946cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18956cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 18966cab3a1bSJed Brown if (sdm->computegs) { 189789b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1898646217ecSPeter Brune PetscStackPush("SNES user GS"); 18996cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1900646217ecSPeter Brune PetscStackPop; 190189b92e6fSPeter Brune } 1902646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1903701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 19044ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1905646217ecSPeter Brune PetscFunctionReturn(0); 1906646217ecSPeter Brune } 1907646217ecSPeter Brune 1908646217ecSPeter Brune 1909646217ecSPeter Brune #undef __FUNCT__ 19104a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 191162fef451SLois Curfman McInnes /*@ 191262fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 191362fef451SLois Curfman McInnes set with SNESSetJacobian(). 191462fef451SLois Curfman McInnes 1915c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1916c7afd0dbSLois Curfman McInnes 191762fef451SLois Curfman McInnes Input Parameters: 1918c7afd0dbSLois Curfman McInnes + snes - the SNES context 1919c7afd0dbSLois Curfman McInnes - x - input vector 192062fef451SLois Curfman McInnes 192162fef451SLois Curfman McInnes Output Parameters: 1922c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 192362fef451SLois Curfman McInnes . B - optional preconditioning matrix 19242b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1925fee21e36SBarry Smith 1926e35cf81dSBarry Smith Options Database Keys: 1927e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1928693365a8SJed Brown . -snes_lag_jacobian <lag> 1929693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1930693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1931693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 19324c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1933c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1934c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1935c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1936c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1937c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 19384c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1939c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1940c01495d3SJed Brown 1941e35cf81dSBarry Smith 194262fef451SLois Curfman McInnes Notes: 194362fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 194462fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 194562fef451SLois Curfman McInnes 194694b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1947dc5a77f8SLois Curfman McInnes flag parameter. 194862fef451SLois Curfman McInnes 194936851e7fSLois Curfman McInnes Level: developer 195036851e7fSLois Curfman McInnes 195162fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 195262fef451SLois Curfman McInnes 1953e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 195462fef451SLois Curfman McInnes @*/ 19557087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 19569b94acceSBarry Smith { 1957dfbe8321SBarry Smith PetscErrorCode ierr; 1958ace3abfcSBarry Smith PetscBool flag; 19596cab3a1bSJed Brown DM dm; 19606cab3a1bSJed Brown SNESDM sdm; 19613a40ed3dSBarry Smith 19623a40ed3dSBarry Smith PetscFunctionBegin; 19630700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 19640700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 19654482741eSBarry Smith PetscValidPointer(flg,5); 1966c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 19674ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 19686cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 19696cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 19706cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 1971ebd3b9afSBarry Smith 1972ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1973ebd3b9afSBarry Smith 1974fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1975fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1976fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1977fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1978e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1979e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1980251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1981ebd3b9afSBarry Smith if (flag) { 1982ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1983ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1984ebd3b9afSBarry Smith } 1985e35cf81dSBarry Smith PetscFunctionReturn(0); 1986e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1987e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1988e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1989251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1990ebd3b9afSBarry Smith if (flag) { 1991ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1992ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1993ebd3b9afSBarry Smith } 1994e35cf81dSBarry Smith PetscFunctionReturn(0); 1995e35cf81dSBarry Smith } 1996e35cf81dSBarry Smith 1997c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1998e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1999d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 20006cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 2001d64ed03dSBarry Smith PetscStackPop; 2002d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 2003a8054027SBarry Smith 20043b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 20053b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 20063b4f5425SBarry Smith snes->lagpreconditioner = -1; 20073b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 2008a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2009a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2010a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 2011a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2012a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2013a8054027SBarry Smith } 2014a8054027SBarry Smith 20156d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 20160700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 20170700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 2018693365a8SJed Brown { 2019693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 2020693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 2021693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 2022693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 2023693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 2024693365a8SJed Brown if (flag || flag_draw || flag_contour) { 2025693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 2026693365a8SJed Brown MatStructure mstruct; 2027693365a8SJed Brown PetscViewer vdraw,vstdout; 20286b3a5b13SJed Brown PetscBool flg; 2029693365a8SJed Brown if (flag_operator) { 2030693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 2031693365a8SJed Brown Bexp = Bexp_mine; 2032693365a8SJed Brown } else { 2033693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 2034251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 2035693365a8SJed Brown if (flg) Bexp = *B; 2036693365a8SJed Brown else { 2037693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 2038693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 2039693365a8SJed Brown Bexp = Bexp_mine; 2040693365a8SJed Brown } 2041693365a8SJed Brown } 2042693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2043693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 2044693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 2045693365a8SJed Brown if (flag_draw || flag_contour) { 2046693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2047693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 2048693365a8SJed Brown } else vdraw = PETSC_NULL; 2049693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 2050693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2051693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2052693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2053693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2054693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2055693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2056693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2057693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2058693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2059693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2060693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2061693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2062693365a8SJed Brown } 2063693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2064693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2065693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2066693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2067693365a8SJed Brown } 2068693365a8SJed Brown } 20694c30e9fbSJed Brown { 20706719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 20716719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 20724c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 20736719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 20744c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 20754c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 20766719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 20776719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 20786719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 20796719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 20804c30e9fbSJed Brown Mat Bfd; 20814c30e9fbSJed Brown MatStructure mstruct; 20824c30e9fbSJed Brown PetscViewer vdraw,vstdout; 20834c30e9fbSJed Brown ISColoring iscoloring; 20844c30e9fbSJed Brown MatFDColoring matfdcoloring; 20854c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 20864c30e9fbSJed Brown void *funcctx; 20876719d8e4SJed Brown PetscReal norm1,norm2,normmax; 20884c30e9fbSJed Brown 20894c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 20904c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 20914c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 20924c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 20934c30e9fbSJed Brown 20944c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 20954c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 20964c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 20974c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 20984c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 20994c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 21004c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 21014c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 21024c30e9fbSJed Brown 21034c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 21044c30e9fbSJed Brown if (flag_draw || flag_contour) { 21054c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 21064c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 21074c30e9fbSJed Brown } else vdraw = PETSC_NULL; 21084c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 21096719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 21104c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 21114c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 21126719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 21134c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 21144c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 21154c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 21166719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 21174c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 21186719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 21196719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 21204c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 21214c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 21224c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 21234c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 21244c30e9fbSJed Brown } 21254c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 21266719d8e4SJed Brown 21276719d8e4SJed Brown if (flag_threshold) { 21286719d8e4SJed Brown PetscInt bs,rstart,rend,i; 21296719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 21306719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 21316719d8e4SJed Brown for (i=rstart; i<rend; i++) { 21326719d8e4SJed Brown const PetscScalar *ba,*ca; 21336719d8e4SJed Brown const PetscInt *bj,*cj; 21346719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 21356719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 21366719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21376719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21386719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 21396719d8e4SJed Brown for (j=0; j<bn; j++) { 21406719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21416719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 21426719d8e4SJed Brown maxentrycol = bj[j]; 21436719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 21446719d8e4SJed Brown } 21456719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 21466719d8e4SJed Brown maxdiffcol = bj[j]; 21476719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 21486719d8e4SJed Brown } 21496719d8e4SJed Brown if (rdiff > maxrdiff) { 21506719d8e4SJed Brown maxrdiffcol = bj[j]; 21516719d8e4SJed Brown maxrdiff = rdiff; 21526719d8e4SJed Brown } 21536719d8e4SJed Brown } 21546719d8e4SJed Brown if (maxrdiff > 1) { 21556719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"row %D (maxentry=%G at %D, maxdiff=%G at %D, maxrdiff=%G at %D):",i,maxentry,maxentrycol,maxdiff,maxdiffcol,maxrdiff,maxrdiffcol);CHKERRQ(ierr); 21566719d8e4SJed Brown for (j=0; j<bn; j++) { 21576719d8e4SJed Brown PetscReal rdiff; 21586719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21596719d8e4SJed Brown if (rdiff > 1) { 21606719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 21616719d8e4SJed Brown } 21626719d8e4SJed Brown } 21636719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 21646719d8e4SJed Brown } 21656719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21666719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21676719d8e4SJed Brown } 21686719d8e4SJed Brown } 21694c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 21704c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 21714c30e9fbSJed Brown } 21724c30e9fbSJed Brown } 21733a40ed3dSBarry Smith PetscFunctionReturn(0); 21749b94acceSBarry Smith } 21759b94acceSBarry Smith 21764a2ae208SSatish Balay #undef __FUNCT__ 21774a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 21789b94acceSBarry Smith /*@C 21799b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2180044dda88SLois Curfman McInnes location to store the matrix. 21819b94acceSBarry Smith 21823f9fe445SBarry Smith Logically Collective on SNES and Mat 2183c7afd0dbSLois Curfman McInnes 21849b94acceSBarry Smith Input Parameters: 2185c7afd0dbSLois Curfman McInnes + snes - the SNES context 21869b94acceSBarry Smith . A - Jacobian matrix 21879b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2188efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2189c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2190efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 21919b94acceSBarry Smith 21929b94acceSBarry Smith Calling sequence of func: 21938d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 21949b94acceSBarry Smith 2195c7afd0dbSLois Curfman McInnes + x - input vector 21969b94acceSBarry Smith . A - Jacobian matrix 21979b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2198ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 21992b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2200c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 22019b94acceSBarry Smith 22029b94acceSBarry Smith Notes: 220394b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 22042cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2205ac21db08SLois Curfman McInnes 2206ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 22079b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 22089b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 22099b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 22109b94acceSBarry Smith throughout the global iterations. 22119b94acceSBarry Smith 221216913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 221316913363SBarry Smith each matrix. 221416913363SBarry Smith 2215a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2216a8a26c1eSJed Brown must be a MatFDColoring. 2217a8a26c1eSJed Brown 2218c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2219c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2220c3cc8fd1SJed Brown 222136851e7fSLois Curfman McInnes Level: beginner 222236851e7fSLois Curfman McInnes 22239b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 22249b94acceSBarry Smith 22253ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 22269b94acceSBarry Smith @*/ 22277087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 22289b94acceSBarry Smith { 2229dfbe8321SBarry Smith PetscErrorCode ierr; 22306cab3a1bSJed Brown DM dm; 22313a7fca6bSBarry Smith 22323a40ed3dSBarry Smith PetscFunctionBegin; 22330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 22340700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 22350700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2236c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 223706975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 22386cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22396cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 22403a7fca6bSBarry Smith if (A) { 22417dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 22426bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 22439b94acceSBarry Smith snes->jacobian = A; 22443a7fca6bSBarry Smith } 22453a7fca6bSBarry Smith if (B) { 22467dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 22476bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 22489b94acceSBarry Smith snes->jacobian_pre = B; 22493a7fca6bSBarry Smith } 22503a40ed3dSBarry Smith PetscFunctionReturn(0); 22519b94acceSBarry Smith } 225262fef451SLois Curfman McInnes 22534a2ae208SSatish Balay #undef __FUNCT__ 22544a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2255c2aafc4cSSatish Balay /*@C 2256b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2257b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2258b4fd4287SBarry Smith 2259c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2260c7afd0dbSLois Curfman McInnes 2261b4fd4287SBarry Smith Input Parameter: 2262b4fd4287SBarry Smith . snes - the nonlinear solver context 2263b4fd4287SBarry Smith 2264b4fd4287SBarry Smith Output Parameters: 2265c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2266b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 226770e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 226870e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2269fee21e36SBarry Smith 227036851e7fSLois Curfman McInnes Level: advanced 227136851e7fSLois Curfman McInnes 2272b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2273b4fd4287SBarry Smith @*/ 22747087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2275b4fd4287SBarry Smith { 22766cab3a1bSJed Brown PetscErrorCode ierr; 22776cab3a1bSJed Brown DM dm; 22786cab3a1bSJed Brown SNESDM sdm; 22796cab3a1bSJed Brown 22803a40ed3dSBarry Smith PetscFunctionBegin; 22810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2282b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2283b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 22846cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22856cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 22866cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 22876cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 22883a40ed3dSBarry Smith PetscFunctionReturn(0); 2289b4fd4287SBarry Smith } 2290b4fd4287SBarry Smith 22919b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 22929b94acceSBarry Smith 22934a2ae208SSatish Balay #undef __FUNCT__ 22944a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 22959b94acceSBarry Smith /*@ 22969b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2297272ac6f2SLois Curfman McInnes of a nonlinear solver. 22989b94acceSBarry Smith 2299fee21e36SBarry Smith Collective on SNES 2300fee21e36SBarry Smith 2301c7afd0dbSLois Curfman McInnes Input Parameters: 230270e92668SMatthew Knepley . snes - the SNES context 2303c7afd0dbSLois Curfman McInnes 2304272ac6f2SLois Curfman McInnes Notes: 2305272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2306272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2307272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2308272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2309272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2310272ac6f2SLois Curfman McInnes 231136851e7fSLois Curfman McInnes Level: advanced 231236851e7fSLois Curfman McInnes 23139b94acceSBarry Smith .keywords: SNES, nonlinear, setup 23149b94acceSBarry Smith 23159b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 23169b94acceSBarry Smith @*/ 23177087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 23189b94acceSBarry Smith { 2319dfbe8321SBarry Smith PetscErrorCode ierr; 23206cab3a1bSJed Brown DM dm; 23216cab3a1bSJed Brown SNESDM sdm; 23223a40ed3dSBarry Smith 23233a40ed3dSBarry Smith PetscFunctionBegin; 23240700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23254dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 23269b94acceSBarry Smith 23277adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 232885385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 232985385478SLisandro Dalcin } 233085385478SLisandro Dalcin 2331a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 233217186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 233358c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 233458c9b817SLisandro Dalcin 233558c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 233658c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 233758c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 233858c9b817SLisandro Dalcin } 233958c9b817SLisandro Dalcin 23406cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23416cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 23426cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 23436cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 23446cab3a1bSJed Brown if (!snes->vec_func) { 23456cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2346214df951SJed Brown } 2347efd51863SBarry Smith 2348b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2349b710008aSBarry Smith 2350f1c6b773SPeter Brune if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);} 23519e764e56SPeter Brune 2352d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2353d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2354d25893d9SBarry Smith } 2355d25893d9SBarry Smith 2356410397dcSLisandro Dalcin if (snes->ops->setup) { 2357410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2358410397dcSLisandro Dalcin } 235958c9b817SLisandro Dalcin 23607aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 23613a40ed3dSBarry Smith PetscFunctionReturn(0); 23629b94acceSBarry Smith } 23639b94acceSBarry Smith 23644a2ae208SSatish Balay #undef __FUNCT__ 236537596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 236637596af1SLisandro Dalcin /*@ 236737596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 236837596af1SLisandro Dalcin 236937596af1SLisandro Dalcin Collective on SNES 237037596af1SLisandro Dalcin 237137596af1SLisandro Dalcin Input Parameter: 237237596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 237337596af1SLisandro Dalcin 2374d25893d9SBarry Smith Level: intermediate 2375d25893d9SBarry Smith 2376d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 237737596af1SLisandro Dalcin 237837596af1SLisandro Dalcin .keywords: SNES, destroy 237937596af1SLisandro Dalcin 238037596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 238137596af1SLisandro Dalcin @*/ 238237596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 238337596af1SLisandro Dalcin { 238437596af1SLisandro Dalcin PetscErrorCode ierr; 238537596af1SLisandro Dalcin 238637596af1SLisandro Dalcin PetscFunctionBegin; 238737596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2388d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2389d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2390d25893d9SBarry Smith snes->user = PETSC_NULL; 2391d25893d9SBarry Smith } 23928a23116dSBarry Smith if (snes->pc) { 23938a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 23948a23116dSBarry Smith } 23958a23116dSBarry Smith 239637596af1SLisandro Dalcin if (snes->ops->reset) { 239737596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 239837596af1SLisandro Dalcin } 23999e764e56SPeter Brune if (snes->ksp) { 24009e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 24019e764e56SPeter Brune } 24029e764e56SPeter Brune 24039e764e56SPeter Brune if (snes->linesearch) { 2404f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 24059e764e56SPeter Brune } 24069e764e56SPeter Brune 24076bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 24086bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 24096bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 24106bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 24116bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 24126bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2413c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2414c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 241537596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 241637596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 241737596af1SLisandro Dalcin PetscFunctionReturn(0); 241837596af1SLisandro Dalcin } 241937596af1SLisandro Dalcin 242037596af1SLisandro Dalcin #undef __FUNCT__ 24214a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 242252baeb72SSatish Balay /*@ 24239b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 24249b94acceSBarry Smith with SNESCreate(). 24259b94acceSBarry Smith 2426c7afd0dbSLois Curfman McInnes Collective on SNES 2427c7afd0dbSLois Curfman McInnes 24289b94acceSBarry Smith Input Parameter: 24299b94acceSBarry Smith . snes - the SNES context 24309b94acceSBarry Smith 243136851e7fSLois Curfman McInnes Level: beginner 243236851e7fSLois Curfman McInnes 24339b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 24349b94acceSBarry Smith 243563a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 24369b94acceSBarry Smith @*/ 24376bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 24389b94acceSBarry Smith { 24396849ba73SBarry Smith PetscErrorCode ierr; 24403a40ed3dSBarry Smith 24413a40ed3dSBarry Smith PetscFunctionBegin; 24426bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 24436bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 24446bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2445d4bb536fSBarry Smith 24466bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 24478a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 24486b8b9a38SLisandro Dalcin 2449be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 24506bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 24516bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 24526d4c513bSLisandro Dalcin 24536bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 24546bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2455f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 24566b8b9a38SLisandro Dalcin 24576bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 24586bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 24596bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 24606b8b9a38SLisandro Dalcin } 24616bf464f9SBarry Smith if ((*snes)->conv_malloc) { 24626bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 24636bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 246458c9b817SLisandro Dalcin } 24656bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2466a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 24673a40ed3dSBarry Smith PetscFunctionReturn(0); 24689b94acceSBarry Smith } 24699b94acceSBarry Smith 24709b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 24719b94acceSBarry Smith 24724a2ae208SSatish Balay #undef __FUNCT__ 2473a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2474a8054027SBarry Smith /*@ 2475a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2476a8054027SBarry Smith 24773f9fe445SBarry Smith Logically Collective on SNES 2478a8054027SBarry Smith 2479a8054027SBarry Smith Input Parameters: 2480a8054027SBarry Smith + snes - the SNES context 2481a8054027SBarry 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 24823b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2483a8054027SBarry Smith 2484a8054027SBarry Smith Options Database Keys: 2485a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2486a8054027SBarry Smith 2487a8054027SBarry Smith Notes: 2488a8054027SBarry Smith The default is 1 2489a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2490a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2491a8054027SBarry Smith 2492a8054027SBarry Smith Level: intermediate 2493a8054027SBarry Smith 2494a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2495a8054027SBarry Smith 2496e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2497a8054027SBarry Smith 2498a8054027SBarry Smith @*/ 24997087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2500a8054027SBarry Smith { 2501a8054027SBarry Smith PetscFunctionBegin; 25020700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2503e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2504e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2505c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2506a8054027SBarry Smith snes->lagpreconditioner = lag; 2507a8054027SBarry Smith PetscFunctionReturn(0); 2508a8054027SBarry Smith } 2509a8054027SBarry Smith 2510a8054027SBarry Smith #undef __FUNCT__ 2511efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2512efd51863SBarry Smith /*@ 2513efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2514efd51863SBarry Smith 2515efd51863SBarry Smith Logically Collective on SNES 2516efd51863SBarry Smith 2517efd51863SBarry Smith Input Parameters: 2518efd51863SBarry Smith + snes - the SNES context 2519efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2520efd51863SBarry Smith 2521efd51863SBarry Smith Options Database Keys: 2522efd51863SBarry Smith . -snes_grid_sequence <steps> 2523efd51863SBarry Smith 2524efd51863SBarry Smith Level: intermediate 2525efd51863SBarry Smith 2526c0df2a02SJed Brown Notes: 2527c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2528c0df2a02SJed Brown 2529efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2530efd51863SBarry Smith 2531efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2532efd51863SBarry Smith 2533efd51863SBarry Smith @*/ 2534efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2535efd51863SBarry Smith { 2536efd51863SBarry Smith PetscFunctionBegin; 2537efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2538efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2539efd51863SBarry Smith snes->gridsequence = steps; 2540efd51863SBarry Smith PetscFunctionReturn(0); 2541efd51863SBarry Smith } 2542efd51863SBarry Smith 2543efd51863SBarry Smith #undef __FUNCT__ 2544a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2545a8054027SBarry Smith /*@ 2546a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2547a8054027SBarry Smith 25483f9fe445SBarry Smith Not Collective 2549a8054027SBarry Smith 2550a8054027SBarry Smith Input Parameter: 2551a8054027SBarry Smith . snes - the SNES context 2552a8054027SBarry Smith 2553a8054027SBarry Smith Output Parameter: 2554a8054027SBarry 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 25553b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2556a8054027SBarry Smith 2557a8054027SBarry Smith Options Database Keys: 2558a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2559a8054027SBarry Smith 2560a8054027SBarry Smith Notes: 2561a8054027SBarry Smith The default is 1 2562a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2563a8054027SBarry Smith 2564a8054027SBarry Smith Level: intermediate 2565a8054027SBarry Smith 2566a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2567a8054027SBarry Smith 2568a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2569a8054027SBarry Smith 2570a8054027SBarry Smith @*/ 25717087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2572a8054027SBarry Smith { 2573a8054027SBarry Smith PetscFunctionBegin; 25740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2575a8054027SBarry Smith *lag = snes->lagpreconditioner; 2576a8054027SBarry Smith PetscFunctionReturn(0); 2577a8054027SBarry Smith } 2578a8054027SBarry Smith 2579a8054027SBarry Smith #undef __FUNCT__ 2580e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2581e35cf81dSBarry Smith /*@ 2582e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2583e35cf81dSBarry Smith often the preconditioner is rebuilt. 2584e35cf81dSBarry Smith 25853f9fe445SBarry Smith Logically Collective on SNES 2586e35cf81dSBarry Smith 2587e35cf81dSBarry Smith Input Parameters: 2588e35cf81dSBarry Smith + snes - the SNES context 2589e35cf81dSBarry 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 2590fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2591e35cf81dSBarry Smith 2592e35cf81dSBarry Smith Options Database Keys: 2593e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2594e35cf81dSBarry Smith 2595e35cf81dSBarry Smith Notes: 2596e35cf81dSBarry Smith The default is 1 2597e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2598fe3ffe1eSBarry 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 2599fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2600e35cf81dSBarry Smith 2601e35cf81dSBarry Smith Level: intermediate 2602e35cf81dSBarry Smith 2603e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2604e35cf81dSBarry Smith 2605e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2606e35cf81dSBarry Smith 2607e35cf81dSBarry Smith @*/ 26087087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2609e35cf81dSBarry Smith { 2610e35cf81dSBarry Smith PetscFunctionBegin; 26110700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2612e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2613e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2614c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2615e35cf81dSBarry Smith snes->lagjacobian = lag; 2616e35cf81dSBarry Smith PetscFunctionReturn(0); 2617e35cf81dSBarry Smith } 2618e35cf81dSBarry Smith 2619e35cf81dSBarry Smith #undef __FUNCT__ 2620e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2621e35cf81dSBarry Smith /*@ 2622e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2623e35cf81dSBarry Smith 26243f9fe445SBarry Smith Not Collective 2625e35cf81dSBarry Smith 2626e35cf81dSBarry Smith Input Parameter: 2627e35cf81dSBarry Smith . snes - the SNES context 2628e35cf81dSBarry Smith 2629e35cf81dSBarry Smith Output Parameter: 2630e35cf81dSBarry 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 2631e35cf81dSBarry Smith the Jacobian is built etc. 2632e35cf81dSBarry Smith 2633e35cf81dSBarry Smith Options Database Keys: 2634e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2635e35cf81dSBarry Smith 2636e35cf81dSBarry Smith Notes: 2637e35cf81dSBarry Smith The default is 1 2638e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2639e35cf81dSBarry Smith 2640e35cf81dSBarry Smith Level: intermediate 2641e35cf81dSBarry Smith 2642e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2643e35cf81dSBarry Smith 2644e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2645e35cf81dSBarry Smith 2646e35cf81dSBarry Smith @*/ 26477087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2648e35cf81dSBarry Smith { 2649e35cf81dSBarry Smith PetscFunctionBegin; 26500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2651e35cf81dSBarry Smith *lag = snes->lagjacobian; 2652e35cf81dSBarry Smith PetscFunctionReturn(0); 2653e35cf81dSBarry Smith } 2654e35cf81dSBarry Smith 2655e35cf81dSBarry Smith #undef __FUNCT__ 26564a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 26579b94acceSBarry Smith /*@ 2658d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 26599b94acceSBarry Smith 26603f9fe445SBarry Smith Logically Collective on SNES 2661c7afd0dbSLois Curfman McInnes 26629b94acceSBarry Smith Input Parameters: 2663c7afd0dbSLois Curfman McInnes + snes - the SNES context 266470441072SBarry Smith . abstol - absolute convergence tolerance 266533174efeSLois Curfman McInnes . rtol - relative convergence tolerance 266633174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 266733174efeSLois Curfman McInnes of the change in the solution between steps 266833174efeSLois Curfman McInnes . maxit - maximum number of iterations 2669c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2670fee21e36SBarry Smith 267133174efeSLois Curfman McInnes Options Database Keys: 267270441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2673c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2674c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2675c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2676c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 26779b94acceSBarry Smith 2678d7a720efSLois Curfman McInnes Notes: 26799b94acceSBarry Smith The default maximum number of iterations is 50. 26809b94acceSBarry Smith The default maximum number of function evaluations is 1000. 26819b94acceSBarry Smith 268236851e7fSLois Curfman McInnes Level: intermediate 268336851e7fSLois Curfman McInnes 268433174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 26859b94acceSBarry Smith 26862492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 26879b94acceSBarry Smith @*/ 26887087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 26899b94acceSBarry Smith { 26903a40ed3dSBarry Smith PetscFunctionBegin; 26910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2692c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2693c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2694c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2695c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2696c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2697c5eb9154SBarry Smith 2698ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2699ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2700ab54825eSJed Brown snes->abstol = abstol; 2701ab54825eSJed Brown } 2702ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2703ab54825eSJed Brown if (rtol < 0.0 || 1.0 <= rtol) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Relative tolerance %G must be non-negative and less than 1.0",rtol); 2704ab54825eSJed Brown snes->rtol = rtol; 2705ab54825eSJed Brown } 2706ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2707ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2708c60f73f4SPeter Brune snes->stol = stol; 2709ab54825eSJed Brown } 2710ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2711ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2712ab54825eSJed Brown snes->max_its = maxit; 2713ab54825eSJed Brown } 2714ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2715ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2716ab54825eSJed Brown snes->max_funcs = maxf; 2717ab54825eSJed Brown } 271888976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 27193a40ed3dSBarry Smith PetscFunctionReturn(0); 27209b94acceSBarry Smith } 27219b94acceSBarry Smith 27224a2ae208SSatish Balay #undef __FUNCT__ 27234a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 27249b94acceSBarry Smith /*@ 272533174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 272633174efeSLois Curfman McInnes 2727c7afd0dbSLois Curfman McInnes Not Collective 2728c7afd0dbSLois Curfman McInnes 272933174efeSLois Curfman McInnes Input Parameters: 2730c7afd0dbSLois Curfman McInnes + snes - the SNES context 273185385478SLisandro Dalcin . atol - absolute convergence tolerance 273233174efeSLois Curfman McInnes . rtol - relative convergence tolerance 273333174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 273433174efeSLois Curfman McInnes of the change in the solution between steps 273533174efeSLois Curfman McInnes . maxit - maximum number of iterations 2736c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2737fee21e36SBarry Smith 273833174efeSLois Curfman McInnes Notes: 273933174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 274033174efeSLois Curfman McInnes 274136851e7fSLois Curfman McInnes Level: intermediate 274236851e7fSLois Curfman McInnes 274333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 274433174efeSLois Curfman McInnes 274533174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 274633174efeSLois Curfman McInnes @*/ 27477087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 274833174efeSLois Curfman McInnes { 27493a40ed3dSBarry Smith PetscFunctionBegin; 27500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 275185385478SLisandro Dalcin if (atol) *atol = snes->abstol; 275233174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 2753c60f73f4SPeter Brune if (stol) *stol = snes->stol; 275433174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 275533174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 27563a40ed3dSBarry Smith PetscFunctionReturn(0); 275733174efeSLois Curfman McInnes } 275833174efeSLois Curfman McInnes 27594a2ae208SSatish Balay #undef __FUNCT__ 27604a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 276133174efeSLois Curfman McInnes /*@ 27629b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 27639b94acceSBarry Smith 27643f9fe445SBarry Smith Logically Collective on SNES 2765fee21e36SBarry Smith 2766c7afd0dbSLois Curfman McInnes Input Parameters: 2767c7afd0dbSLois Curfman McInnes + snes - the SNES context 2768c7afd0dbSLois Curfman McInnes - tol - tolerance 2769c7afd0dbSLois Curfman McInnes 27709b94acceSBarry Smith Options Database Key: 2771c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 27729b94acceSBarry Smith 277336851e7fSLois Curfman McInnes Level: intermediate 277436851e7fSLois Curfman McInnes 27759b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 27769b94acceSBarry Smith 27772492ecdbSBarry Smith .seealso: SNESSetTolerances() 27789b94acceSBarry Smith @*/ 27797087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 27809b94acceSBarry Smith { 27813a40ed3dSBarry Smith PetscFunctionBegin; 27820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2783c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 27849b94acceSBarry Smith snes->deltatol = tol; 27853a40ed3dSBarry Smith PetscFunctionReturn(0); 27869b94acceSBarry Smith } 27879b94acceSBarry Smith 2788df9fa365SBarry Smith /* 2789df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2790df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2791df9fa365SBarry Smith macros instead of functions 2792df9fa365SBarry Smith */ 27934a2ae208SSatish Balay #undef __FUNCT__ 2794a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 27957087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2796ce1608b8SBarry Smith { 2797dfbe8321SBarry Smith PetscErrorCode ierr; 2798ce1608b8SBarry Smith 2799ce1608b8SBarry Smith PetscFunctionBegin; 28000700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2801a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2802ce1608b8SBarry Smith PetscFunctionReturn(0); 2803ce1608b8SBarry Smith } 2804ce1608b8SBarry Smith 28054a2ae208SSatish Balay #undef __FUNCT__ 2806a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 28077087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2808df9fa365SBarry Smith { 2809dfbe8321SBarry Smith PetscErrorCode ierr; 2810df9fa365SBarry Smith 2811df9fa365SBarry Smith PetscFunctionBegin; 2812a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2813df9fa365SBarry Smith PetscFunctionReturn(0); 2814df9fa365SBarry Smith } 2815df9fa365SBarry Smith 28164a2ae208SSatish Balay #undef __FUNCT__ 2817a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 28186bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2819df9fa365SBarry Smith { 2820dfbe8321SBarry Smith PetscErrorCode ierr; 2821df9fa365SBarry Smith 2822df9fa365SBarry Smith PetscFunctionBegin; 2823a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2824df9fa365SBarry Smith PetscFunctionReturn(0); 2825df9fa365SBarry Smith } 2826df9fa365SBarry Smith 28277087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2828b271bb04SBarry Smith #undef __FUNCT__ 2829b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 28307087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2831b271bb04SBarry Smith { 2832b271bb04SBarry Smith PetscDrawLG lg; 2833b271bb04SBarry Smith PetscErrorCode ierr; 2834b271bb04SBarry Smith PetscReal x,y,per; 2835b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2836b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2837b271bb04SBarry Smith PetscDraw draw; 2838b271bb04SBarry Smith PetscFunctionBegin; 2839b271bb04SBarry Smith if (!monctx) { 2840b271bb04SBarry Smith MPI_Comm comm; 2841b271bb04SBarry Smith 2842b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2843b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2844b271bb04SBarry Smith } 2845b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2846b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2847b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2848b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2849b271bb04SBarry Smith x = (PetscReal) n; 2850b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2851b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2852b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2853b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2854b271bb04SBarry Smith } 2855b271bb04SBarry Smith 2856b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2857b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2858b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2859b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2860b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2861b271bb04SBarry Smith x = (PetscReal) n; 2862b271bb04SBarry Smith y = 100.0*per; 2863b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2864b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2865b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2866b271bb04SBarry Smith } 2867b271bb04SBarry Smith 2868b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2869b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2870b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2871b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2872b271bb04SBarry Smith x = (PetscReal) n; 2873b271bb04SBarry Smith y = (prev - rnorm)/prev; 2874b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2875b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2876b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2877b271bb04SBarry Smith } 2878b271bb04SBarry Smith 2879b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2880b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2881b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2882b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2883b271bb04SBarry Smith x = (PetscReal) n; 2884b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2885b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2886b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2887b271bb04SBarry Smith } 2888b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2889b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2890b271bb04SBarry Smith } 2891b271bb04SBarry Smith prev = rnorm; 2892b271bb04SBarry Smith PetscFunctionReturn(0); 2893b271bb04SBarry Smith } 2894b271bb04SBarry Smith 2895b271bb04SBarry Smith #undef __FUNCT__ 2896b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 28977087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2898b271bb04SBarry Smith { 2899b271bb04SBarry Smith PetscErrorCode ierr; 2900b271bb04SBarry Smith 2901b271bb04SBarry Smith PetscFunctionBegin; 2902b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2903b271bb04SBarry Smith PetscFunctionReturn(0); 2904b271bb04SBarry Smith } 2905b271bb04SBarry Smith 2906b271bb04SBarry Smith #undef __FUNCT__ 2907b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 29086bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2909b271bb04SBarry Smith { 2910b271bb04SBarry Smith PetscErrorCode ierr; 2911b271bb04SBarry Smith 2912b271bb04SBarry Smith PetscFunctionBegin; 2913b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2914b271bb04SBarry Smith PetscFunctionReturn(0); 2915b271bb04SBarry Smith } 2916b271bb04SBarry Smith 29177a03ce2fSLisandro Dalcin #undef __FUNCT__ 29187a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2919228d79bcSJed Brown /*@ 2920228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2921228d79bcSJed Brown 2922228d79bcSJed Brown Collective on SNES 2923228d79bcSJed Brown 2924228d79bcSJed Brown Input Parameters: 2925228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2926228d79bcSJed Brown . iter - iteration number 2927228d79bcSJed Brown - rnorm - relative norm of the residual 2928228d79bcSJed Brown 2929228d79bcSJed Brown Notes: 2930228d79bcSJed Brown This routine is called by the SNES implementations. 2931228d79bcSJed Brown It does not typically need to be called by the user. 2932228d79bcSJed Brown 2933228d79bcSJed Brown Level: developer 2934228d79bcSJed Brown 2935228d79bcSJed Brown .seealso: SNESMonitorSet() 2936228d79bcSJed Brown @*/ 29377a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 29387a03ce2fSLisandro Dalcin { 29397a03ce2fSLisandro Dalcin PetscErrorCode ierr; 29407a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 29417a03ce2fSLisandro Dalcin 29427a03ce2fSLisandro Dalcin PetscFunctionBegin; 29437a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 29447a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 29457a03ce2fSLisandro Dalcin } 29467a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 29477a03ce2fSLisandro Dalcin } 29487a03ce2fSLisandro Dalcin 29499b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 29509b94acceSBarry Smith 29514a2ae208SSatish Balay #undef __FUNCT__ 2952a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 29539b94acceSBarry Smith /*@C 2954a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 29559b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 29569b94acceSBarry Smith progress. 29579b94acceSBarry Smith 29583f9fe445SBarry Smith Logically Collective on SNES 2959fee21e36SBarry Smith 2960c7afd0dbSLois Curfman McInnes Input Parameters: 2961c7afd0dbSLois Curfman McInnes + snes - the SNES context 2962c7afd0dbSLois Curfman McInnes . func - monitoring routine 2963b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2964e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2965b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2966b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 29679b94acceSBarry Smith 2968c7afd0dbSLois Curfman McInnes Calling sequence of func: 2969a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2970c7afd0dbSLois Curfman McInnes 2971c7afd0dbSLois Curfman McInnes + snes - the SNES context 2972c7afd0dbSLois Curfman McInnes . its - iteration number 2973c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 297440a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 29759b94acceSBarry Smith 29769665c990SLois Curfman McInnes Options Database Keys: 2977a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2978a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2979a6570f20SBarry Smith uses SNESMonitorLGCreate() 2980cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2981c7afd0dbSLois Curfman McInnes been hardwired into a code by 2982a6570f20SBarry Smith calls to SNESMonitorSet(), but 2983c7afd0dbSLois Curfman McInnes does not cancel those set via 2984c7afd0dbSLois Curfman McInnes the options database. 29859665c990SLois Curfman McInnes 2986639f9d9dSBarry Smith Notes: 29876bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 2988a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 29896bc08f3fSLois Curfman McInnes order in which they were set. 2990639f9d9dSBarry Smith 2991025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 2992025f1a04SBarry Smith 299336851e7fSLois Curfman McInnes Level: intermediate 299436851e7fSLois Curfman McInnes 29959b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 29969b94acceSBarry Smith 2997a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 29989b94acceSBarry Smith @*/ 2999c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 30009b94acceSBarry Smith { 3001b90d0a6eSBarry Smith PetscInt i; 3002649052a6SBarry Smith PetscErrorCode ierr; 3003b90d0a6eSBarry Smith 30043a40ed3dSBarry Smith PetscFunctionBegin; 30050700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 300617186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3007b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 3008649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 3009649052a6SBarry Smith if (monitordestroy) { 3010c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 3011649052a6SBarry Smith } 3012b90d0a6eSBarry Smith PetscFunctionReturn(0); 3013b90d0a6eSBarry Smith } 3014b90d0a6eSBarry Smith } 3015b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 3016b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3017639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 30183a40ed3dSBarry Smith PetscFunctionReturn(0); 30199b94acceSBarry Smith } 30209b94acceSBarry Smith 30214a2ae208SSatish Balay #undef __FUNCT__ 3022a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 30235cd90555SBarry Smith /*@C 3024a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 30255cd90555SBarry Smith 30263f9fe445SBarry Smith Logically Collective on SNES 3027c7afd0dbSLois Curfman McInnes 30285cd90555SBarry Smith Input Parameters: 30295cd90555SBarry Smith . snes - the SNES context 30305cd90555SBarry Smith 30311a480d89SAdministrator Options Database Key: 3032a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3033a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3034c7afd0dbSLois Curfman McInnes set via the options database 30355cd90555SBarry Smith 30365cd90555SBarry Smith Notes: 30375cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 30385cd90555SBarry Smith 303936851e7fSLois Curfman McInnes Level: intermediate 304036851e7fSLois Curfman McInnes 30415cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 30425cd90555SBarry Smith 3043a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 30445cd90555SBarry Smith @*/ 30457087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 30465cd90555SBarry Smith { 3047d952e501SBarry Smith PetscErrorCode ierr; 3048d952e501SBarry Smith PetscInt i; 3049d952e501SBarry Smith 30505cd90555SBarry Smith PetscFunctionBegin; 30510700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3052d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 3053d952e501SBarry Smith if (snes->monitordestroy[i]) { 30543c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3055d952e501SBarry Smith } 3056d952e501SBarry Smith } 30575cd90555SBarry Smith snes->numbermonitors = 0; 30585cd90555SBarry Smith PetscFunctionReturn(0); 30595cd90555SBarry Smith } 30605cd90555SBarry Smith 30614a2ae208SSatish Balay #undef __FUNCT__ 30624a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 30639b94acceSBarry Smith /*@C 30649b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 30659b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 30669b94acceSBarry Smith 30673f9fe445SBarry Smith Logically Collective on SNES 3068fee21e36SBarry Smith 3069c7afd0dbSLois Curfman McInnes Input Parameters: 3070c7afd0dbSLois Curfman McInnes + snes - the SNES context 3071c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 30727f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 30737f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 30749b94acceSBarry Smith 3075c7afd0dbSLois Curfman McInnes Calling sequence of func: 307606ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3077c7afd0dbSLois Curfman McInnes 3078c7afd0dbSLois Curfman McInnes + snes - the SNES context 307906ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3080c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 3081184914b5SBarry Smith . reason - reason for convergence/divergence 3082c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 30834b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 30844b27c08aSLois Curfman McInnes - f - 2-norm of function 30859b94acceSBarry Smith 308636851e7fSLois Curfman McInnes Level: advanced 308736851e7fSLois Curfman McInnes 30889b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 30899b94acceSBarry Smith 309085385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 30919b94acceSBarry Smith @*/ 30927087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 30939b94acceSBarry Smith { 30947f7931b9SBarry Smith PetscErrorCode ierr; 30957f7931b9SBarry Smith 30963a40ed3dSBarry Smith PetscFunctionBegin; 30970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 309885385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 30997f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 31007f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 31017f7931b9SBarry Smith } 310285385478SLisandro Dalcin snes->ops->converged = func; 31037f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 310485385478SLisandro Dalcin snes->cnvP = cctx; 31053a40ed3dSBarry Smith PetscFunctionReturn(0); 31069b94acceSBarry Smith } 31079b94acceSBarry Smith 31084a2ae208SSatish Balay #undef __FUNCT__ 31094a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 311052baeb72SSatish Balay /*@ 3111184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3112184914b5SBarry Smith 3113184914b5SBarry Smith Not Collective 3114184914b5SBarry Smith 3115184914b5SBarry Smith Input Parameter: 3116184914b5SBarry Smith . snes - the SNES context 3117184914b5SBarry Smith 3118184914b5SBarry Smith Output Parameter: 31194d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3120184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 3121184914b5SBarry Smith 3122184914b5SBarry Smith Level: intermediate 3123184914b5SBarry Smith 3124184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 3125184914b5SBarry Smith 3126184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 3127184914b5SBarry Smith 312885385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 3129184914b5SBarry Smith @*/ 31307087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3131184914b5SBarry Smith { 3132184914b5SBarry Smith PetscFunctionBegin; 31330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31344482741eSBarry Smith PetscValidPointer(reason,2); 3135184914b5SBarry Smith *reason = snes->reason; 3136184914b5SBarry Smith PetscFunctionReturn(0); 3137184914b5SBarry Smith } 3138184914b5SBarry Smith 31394a2ae208SSatish Balay #undef __FUNCT__ 31404a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 3141c9005455SLois Curfman McInnes /*@ 3142c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3143c9005455SLois Curfman McInnes 31443f9fe445SBarry Smith Logically Collective on SNES 3145fee21e36SBarry Smith 3146c7afd0dbSLois Curfman McInnes Input Parameters: 3147c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 31488c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3149cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3150758f92a0SBarry Smith . na - size of a and its 315164731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3152758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3153c7afd0dbSLois Curfman McInnes 3154308dcc3eSBarry Smith Notes: 3155308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3156308dcc3eSBarry Smith default array of length 10000 is allocated. 3157308dcc3eSBarry Smith 3158c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3159c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3160c9005455SLois Curfman McInnes during the section of code that is being timed. 3161c9005455SLois Curfman McInnes 316236851e7fSLois Curfman McInnes Level: intermediate 316336851e7fSLois Curfman McInnes 3164c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3165758f92a0SBarry Smith 316608405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3167758f92a0SBarry Smith 3168c9005455SLois Curfman McInnes @*/ 31697087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3170c9005455SLois Curfman McInnes { 3171308dcc3eSBarry Smith PetscErrorCode ierr; 3172308dcc3eSBarry Smith 31733a40ed3dSBarry Smith PetscFunctionBegin; 31740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31754482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 3176a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 3177308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3178308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3179308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3180308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3181308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3182308dcc3eSBarry Smith } 3183c9005455SLois Curfman McInnes snes->conv_hist = a; 3184758f92a0SBarry Smith snes->conv_hist_its = its; 3185758f92a0SBarry Smith snes->conv_hist_max = na; 3186a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3187758f92a0SBarry Smith snes->conv_hist_reset = reset; 3188758f92a0SBarry Smith PetscFunctionReturn(0); 3189758f92a0SBarry Smith } 3190758f92a0SBarry Smith 3191308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3192c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3193c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3194308dcc3eSBarry Smith EXTERN_C_BEGIN 3195308dcc3eSBarry Smith #undef __FUNCT__ 3196308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3197308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3198308dcc3eSBarry Smith { 3199308dcc3eSBarry Smith mxArray *mat; 3200308dcc3eSBarry Smith PetscInt i; 3201308dcc3eSBarry Smith PetscReal *ar; 3202308dcc3eSBarry Smith 3203308dcc3eSBarry Smith PetscFunctionBegin; 3204308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3205308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3206308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3207308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3208308dcc3eSBarry Smith } 3209308dcc3eSBarry Smith PetscFunctionReturn(mat); 3210308dcc3eSBarry Smith } 3211308dcc3eSBarry Smith EXTERN_C_END 3212308dcc3eSBarry Smith #endif 3213308dcc3eSBarry Smith 3214308dcc3eSBarry Smith 32154a2ae208SSatish Balay #undef __FUNCT__ 32164a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 32170c4c9dddSBarry Smith /*@C 3218758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3219758f92a0SBarry Smith 32203f9fe445SBarry Smith Not Collective 3221758f92a0SBarry Smith 3222758f92a0SBarry Smith Input Parameter: 3223758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3224758f92a0SBarry Smith 3225758f92a0SBarry Smith Output Parameters: 3226758f92a0SBarry Smith . a - array to hold history 3227758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3228758f92a0SBarry Smith negative if not converged) for each solve. 3229758f92a0SBarry Smith - na - size of a and its 3230758f92a0SBarry Smith 3231758f92a0SBarry Smith Notes: 3232758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3233758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3234758f92a0SBarry Smith 3235758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3236758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3237758f92a0SBarry Smith during the section of code that is being timed. 3238758f92a0SBarry Smith 3239758f92a0SBarry Smith Level: intermediate 3240758f92a0SBarry Smith 3241758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3242758f92a0SBarry Smith 3243758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3244758f92a0SBarry Smith 3245758f92a0SBarry Smith @*/ 32467087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3247758f92a0SBarry Smith { 3248758f92a0SBarry Smith PetscFunctionBegin; 32490700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3250758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3251758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3252758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 32533a40ed3dSBarry Smith PetscFunctionReturn(0); 3254c9005455SLois Curfman McInnes } 3255c9005455SLois Curfman McInnes 3256e74ef692SMatthew Knepley #undef __FUNCT__ 3257e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3258ac226902SBarry Smith /*@C 325976b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3260eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 32617e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 326276b2cf59SMatthew Knepley 32633f9fe445SBarry Smith Logically Collective on SNES 326476b2cf59SMatthew Knepley 326576b2cf59SMatthew Knepley Input Parameters: 326676b2cf59SMatthew Knepley . snes - The nonlinear solver context 326776b2cf59SMatthew Knepley . func - The function 326876b2cf59SMatthew Knepley 326976b2cf59SMatthew Knepley Calling sequence of func: 3270b5d30489SBarry Smith . func (SNES snes, PetscInt step); 327176b2cf59SMatthew Knepley 327276b2cf59SMatthew Knepley . step - The current step of the iteration 327376b2cf59SMatthew Knepley 3274fe97e370SBarry Smith Level: advanced 3275fe97e370SBarry Smith 3276fe97e370SBarry 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() 3277fe97e370SBarry Smith This is not used by most users. 327876b2cf59SMatthew Knepley 327976b2cf59SMatthew Knepley .keywords: SNES, update 3280b5d30489SBarry Smith 328185385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 328276b2cf59SMatthew Knepley @*/ 32837087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 328476b2cf59SMatthew Knepley { 328576b2cf59SMatthew Knepley PetscFunctionBegin; 32860700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3287e7788613SBarry Smith snes->ops->update = func; 328876b2cf59SMatthew Knepley PetscFunctionReturn(0); 328976b2cf59SMatthew Knepley } 329076b2cf59SMatthew Knepley 3291e74ef692SMatthew Knepley #undef __FUNCT__ 3292e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 329376b2cf59SMatthew Knepley /*@ 329476b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 329576b2cf59SMatthew Knepley 329676b2cf59SMatthew Knepley Not collective 329776b2cf59SMatthew Knepley 329876b2cf59SMatthew Knepley Input Parameters: 329976b2cf59SMatthew Knepley . snes - The nonlinear solver context 330076b2cf59SMatthew Knepley . step - The current step of the iteration 330176b2cf59SMatthew Knepley 3302205452f4SMatthew Knepley Level: intermediate 3303205452f4SMatthew Knepley 330476b2cf59SMatthew Knepley .keywords: SNES, update 3305a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 330676b2cf59SMatthew Knepley @*/ 33077087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 330876b2cf59SMatthew Knepley { 330976b2cf59SMatthew Knepley PetscFunctionBegin; 331076b2cf59SMatthew Knepley PetscFunctionReturn(0); 331176b2cf59SMatthew Knepley } 331276b2cf59SMatthew Knepley 33134a2ae208SSatish Balay #undef __FUNCT__ 33144a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 33159b94acceSBarry Smith /* 33169b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 33179b94acceSBarry Smith positive parameter delta. 33189b94acceSBarry Smith 33199b94acceSBarry Smith Input Parameters: 3320c7afd0dbSLois Curfman McInnes + snes - the SNES context 33219b94acceSBarry Smith . y - approximate solution of linear system 33229b94acceSBarry Smith . fnorm - 2-norm of current function 3323c7afd0dbSLois Curfman McInnes - delta - trust region size 33249b94acceSBarry Smith 33259b94acceSBarry Smith Output Parameters: 3326c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 33279b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 33289b94acceSBarry Smith region, and exceeds zero otherwise. 3329c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 33309b94acceSBarry Smith 33319b94acceSBarry Smith Note: 33324b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 33339b94acceSBarry Smith is set to be the maximum allowable step size. 33349b94acceSBarry Smith 33359b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 33369b94acceSBarry Smith */ 3337dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 33389b94acceSBarry Smith { 3339064f8208SBarry Smith PetscReal nrm; 3340ea709b57SSatish Balay PetscScalar cnorm; 3341dfbe8321SBarry Smith PetscErrorCode ierr; 33423a40ed3dSBarry Smith 33433a40ed3dSBarry Smith PetscFunctionBegin; 33440700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33450700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3346c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3347184914b5SBarry Smith 3348064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3349064f8208SBarry Smith if (nrm > *delta) { 3350064f8208SBarry Smith nrm = *delta/nrm; 3351064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3352064f8208SBarry Smith cnorm = nrm; 33532dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 33549b94acceSBarry Smith *ynorm = *delta; 33559b94acceSBarry Smith } else { 33569b94acceSBarry Smith *gpnorm = 0.0; 3357064f8208SBarry Smith *ynorm = nrm; 33589b94acceSBarry Smith } 33593a40ed3dSBarry Smith PetscFunctionReturn(0); 33609b94acceSBarry Smith } 33619b94acceSBarry Smith 33624a2ae208SSatish Balay #undef __FUNCT__ 33634a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 33646ce558aeSBarry Smith /*@C 3365f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3366f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 33679b94acceSBarry Smith 3368c7afd0dbSLois Curfman McInnes Collective on SNES 3369c7afd0dbSLois Curfman McInnes 3370b2002411SLois Curfman McInnes Input Parameters: 3371c7afd0dbSLois Curfman McInnes + snes - the SNES context 33723cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 337385385478SLisandro Dalcin - x - the solution vector. 33749b94acceSBarry Smith 3375b2002411SLois Curfman McInnes Notes: 33768ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 33778ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 33788ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 33798ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 33808ddd3da0SLois Curfman McInnes 338136851e7fSLois Curfman McInnes Level: beginner 338236851e7fSLois Curfman McInnes 33839b94acceSBarry Smith .keywords: SNES, nonlinear, solve 33849b94acceSBarry Smith 3385c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 33869b94acceSBarry Smith @*/ 33877087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 33889b94acceSBarry Smith { 3389dfbe8321SBarry Smith PetscErrorCode ierr; 3390ace3abfcSBarry Smith PetscBool flg; 3391eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3392eabae89aSBarry Smith PetscViewer viewer; 3393efd51863SBarry Smith PetscInt grid; 3394a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3395caa4e7f2SJed Brown DM dm; 3396052efed2SBarry Smith 33973a40ed3dSBarry Smith PetscFunctionBegin; 33980700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3399a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3400a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 34010700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 340285385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 340385385478SLisandro Dalcin 3404caa4e7f2SJed Brown if (!x) { 3405caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3406caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 3407a69afd8bSBarry Smith x = xcreated; 3408a69afd8bSBarry Smith } 3409a69afd8bSBarry Smith 3410a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3411efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3412efd51863SBarry Smith 341385385478SLisandro Dalcin /* set solution vector */ 3414efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 34156bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 341685385478SLisandro Dalcin snes->vec_sol = x; 3417caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3418caa4e7f2SJed Brown 3419caa4e7f2SJed Brown /* set affine vector if provided */ 342085385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 34216bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 342285385478SLisandro Dalcin snes->vec_rhs = b; 342385385478SLisandro Dalcin 342470e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 34253f149594SLisandro Dalcin 34267eee914bSBarry Smith if (!grid) { 34277eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3428d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3429dd568438SSatish Balay } else if (snes->dm) { 3430dd568438SSatish Balay PetscBool ig; 3431dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3432dd568438SSatish Balay if (ig) { 34337eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 34347eee914bSBarry Smith } 3435d25893d9SBarry Smith } 3436dd568438SSatish Balay } 3437d25893d9SBarry Smith 3438abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 343950ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3440d5e45103SBarry Smith 34413f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 34424936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 344385385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 34444936397dSBarry Smith if (snes->domainerror){ 34454936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 34464936397dSBarry Smith snes->domainerror = PETSC_FALSE; 34474936397dSBarry Smith } 344817186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 34493f149594SLisandro Dalcin 34507adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3451eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 34527adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 3453eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 34546bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3455eabae89aSBarry Smith } 3456eabae89aSBarry Smith 345790d69ab7SBarry Smith flg = PETSC_FALSE; 3458acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3459da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 34605968eb51SBarry Smith if (snes->printreason) { 3461a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 34625968eb51SBarry Smith if (snes->reason > 0) { 3463c7e7b494SJed Brown ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 34645968eb51SBarry Smith } else { 3465c7e7b494SJed Brown ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 34665968eb51SBarry Smith } 3467a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 34685968eb51SBarry Smith } 34695968eb51SBarry Smith 34708501fc72SJed Brown flg = PETSC_FALSE; 34718501fc72SJed Brown ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 34728501fc72SJed Brown if (flg) { 34738501fc72SJed Brown PetscViewer viewer; 34748501fc72SJed Brown ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 34758501fc72SJed Brown ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 34768501fc72SJed Brown ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 34778501fc72SJed Brown ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 34788501fc72SJed Brown ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 34798501fc72SJed Brown } 34808501fc72SJed Brown 3481e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3482efd51863SBarry Smith if (grid < snes->gridsequence) { 3483efd51863SBarry Smith DM fine; 3484efd51863SBarry Smith Vec xnew; 3485efd51863SBarry Smith Mat interp; 3486efd51863SBarry Smith 3487efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3488c5c77316SJed Brown if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 3489e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3490efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3491efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3492efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3493efd51863SBarry Smith x = xnew; 3494efd51863SBarry Smith 3495efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3496efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3497efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3498a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3499efd51863SBarry Smith } 3500efd51863SBarry Smith } 3501a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 35023a40ed3dSBarry Smith PetscFunctionReturn(0); 35039b94acceSBarry Smith } 35049b94acceSBarry Smith 35059b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 35069b94acceSBarry Smith 35074a2ae208SSatish Balay #undef __FUNCT__ 35084a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 350982bf6240SBarry Smith /*@C 35104b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 35119b94acceSBarry Smith 3512fee21e36SBarry Smith Collective on SNES 3513fee21e36SBarry Smith 3514c7afd0dbSLois Curfman McInnes Input Parameters: 3515c7afd0dbSLois Curfman McInnes + snes - the SNES context 3516454a90a3SBarry Smith - type - a known method 3517c7afd0dbSLois Curfman McInnes 3518c7afd0dbSLois Curfman McInnes Options Database Key: 3519454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3520c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3521ae12b187SLois Curfman McInnes 35229b94acceSBarry Smith Notes: 3523e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 35244b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3525c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 35264b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3527c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 35289b94acceSBarry Smith 3529ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3530ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3531ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3532ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3533ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3534ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3535ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3536ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3537ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3538b0a32e0cSBarry Smith appropriate method. 353936851e7fSLois Curfman McInnes 354036851e7fSLois Curfman McInnes Level: intermediate 3541a703fe33SLois Curfman McInnes 3542454a90a3SBarry Smith .keywords: SNES, set, type 3543435da068SBarry Smith 3544435da068SBarry Smith .seealso: SNESType, SNESCreate() 3545435da068SBarry Smith 35469b94acceSBarry Smith @*/ 35477087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 35489b94acceSBarry Smith { 3549dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3550ace3abfcSBarry Smith PetscBool match; 35513a40ed3dSBarry Smith 35523a40ed3dSBarry Smith PetscFunctionBegin; 35530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35544482741eSBarry Smith PetscValidCharPointer(type,2); 355582bf6240SBarry Smith 3556251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 35570f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 355892ff6ae8SBarry Smith 35594b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3560e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 356175396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3562b5c23020SJed Brown if (snes->ops->destroy) { 3563b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3564b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3565b5c23020SJed Brown } 356675396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 356775396ef9SLisandro Dalcin snes->ops->setup = 0; 356875396ef9SLisandro Dalcin snes->ops->solve = 0; 356975396ef9SLisandro Dalcin snes->ops->view = 0; 357075396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 357175396ef9SLisandro Dalcin snes->ops->destroy = 0; 357275396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 357375396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3574454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 357503bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 35769fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 35779fb22e1aSBarry Smith if (PetscAMSPublishAll) { 35789fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 35799fb22e1aSBarry Smith } 35809fb22e1aSBarry Smith #endif 35813a40ed3dSBarry Smith PetscFunctionReturn(0); 35829b94acceSBarry Smith } 35839b94acceSBarry Smith 3584a847f771SSatish Balay 35859b94acceSBarry Smith /* --------------------------------------------------------------------- */ 35864a2ae208SSatish Balay #undef __FUNCT__ 35874a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 358852baeb72SSatish Balay /*@ 35899b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3590f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 35919b94acceSBarry Smith 3592fee21e36SBarry Smith Not Collective 3593fee21e36SBarry Smith 359436851e7fSLois Curfman McInnes Level: advanced 359536851e7fSLois Curfman McInnes 35969b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 35979b94acceSBarry Smith 35989b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 35999b94acceSBarry Smith @*/ 36007087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 36019b94acceSBarry Smith { 3602dfbe8321SBarry Smith PetscErrorCode ierr; 360382bf6240SBarry Smith 36043a40ed3dSBarry Smith PetscFunctionBegin; 36051441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 36064c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 36073a40ed3dSBarry Smith PetscFunctionReturn(0); 36089b94acceSBarry Smith } 36099b94acceSBarry Smith 36104a2ae208SSatish Balay #undef __FUNCT__ 36114a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 36129b94acceSBarry Smith /*@C 36139a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 36149b94acceSBarry Smith 3615c7afd0dbSLois Curfman McInnes Not Collective 3616c7afd0dbSLois Curfman McInnes 36179b94acceSBarry Smith Input Parameter: 36184b0e389bSBarry Smith . snes - nonlinear solver context 36199b94acceSBarry Smith 36209b94acceSBarry Smith Output Parameter: 36213a7fca6bSBarry Smith . type - SNES method (a character string) 36229b94acceSBarry Smith 362336851e7fSLois Curfman McInnes Level: intermediate 362436851e7fSLois Curfman McInnes 3625454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 36269b94acceSBarry Smith @*/ 36277087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 36289b94acceSBarry Smith { 36293a40ed3dSBarry Smith PetscFunctionBegin; 36300700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36314482741eSBarry Smith PetscValidPointer(type,2); 36327adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 36333a40ed3dSBarry Smith PetscFunctionReturn(0); 36349b94acceSBarry Smith } 36359b94acceSBarry Smith 36364a2ae208SSatish Balay #undef __FUNCT__ 36374a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 363852baeb72SSatish Balay /*@ 36399b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3640c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 36419b94acceSBarry Smith 3642c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3643c7afd0dbSLois Curfman McInnes 36449b94acceSBarry Smith Input Parameter: 36459b94acceSBarry Smith . snes - the SNES context 36469b94acceSBarry Smith 36479b94acceSBarry Smith Output Parameter: 36489b94acceSBarry Smith . x - the solution 36499b94acceSBarry Smith 365070e92668SMatthew Knepley Level: intermediate 365136851e7fSLois Curfman McInnes 36529b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 36539b94acceSBarry Smith 365485385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 36559b94acceSBarry Smith @*/ 36567087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 36579b94acceSBarry Smith { 36583a40ed3dSBarry Smith PetscFunctionBegin; 36590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36604482741eSBarry Smith PetscValidPointer(x,2); 366185385478SLisandro Dalcin *x = snes->vec_sol; 366270e92668SMatthew Knepley PetscFunctionReturn(0); 366370e92668SMatthew Knepley } 366470e92668SMatthew Knepley 366570e92668SMatthew Knepley #undef __FUNCT__ 36664a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 366752baeb72SSatish Balay /*@ 36689b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 36699b94acceSBarry Smith stored. 36709b94acceSBarry Smith 3671c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3672c7afd0dbSLois Curfman McInnes 36739b94acceSBarry Smith Input Parameter: 36749b94acceSBarry Smith . snes - the SNES context 36759b94acceSBarry Smith 36769b94acceSBarry Smith Output Parameter: 36779b94acceSBarry Smith . x - the solution update 36789b94acceSBarry Smith 367936851e7fSLois Curfman McInnes Level: advanced 368036851e7fSLois Curfman McInnes 36819b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 36829b94acceSBarry Smith 368385385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 36849b94acceSBarry Smith @*/ 36857087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 36869b94acceSBarry Smith { 36873a40ed3dSBarry Smith PetscFunctionBegin; 36880700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36894482741eSBarry Smith PetscValidPointer(x,2); 369085385478SLisandro Dalcin *x = snes->vec_sol_update; 36913a40ed3dSBarry Smith PetscFunctionReturn(0); 36929b94acceSBarry Smith } 36939b94acceSBarry Smith 36944a2ae208SSatish Balay #undef __FUNCT__ 36954a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 36969b94acceSBarry Smith /*@C 36973638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 36989b94acceSBarry Smith 3699a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3700c7afd0dbSLois Curfman McInnes 37019b94acceSBarry Smith Input Parameter: 37029b94acceSBarry Smith . snes - the SNES context 37039b94acceSBarry Smith 37049b94acceSBarry Smith Output Parameter: 37057bf4e008SBarry Smith + r - the function (or PETSC_NULL) 370670e92668SMatthew Knepley . func - the function (or PETSC_NULL) 370770e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 37089b94acceSBarry Smith 370936851e7fSLois Curfman McInnes Level: advanced 371036851e7fSLois Curfman McInnes 3711a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 37129b94acceSBarry Smith 37134b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 37149b94acceSBarry Smith @*/ 37157087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 37169b94acceSBarry Smith { 3717a63bb30eSJed Brown PetscErrorCode ierr; 37186cab3a1bSJed Brown DM dm; 3719a63bb30eSJed Brown 37203a40ed3dSBarry Smith PetscFunctionBegin; 37210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3722a63bb30eSJed Brown if (r) { 3723a63bb30eSJed Brown if (!snes->vec_func) { 3724a63bb30eSJed Brown if (snes->vec_rhs) { 3725a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3726a63bb30eSJed Brown } else if (snes->vec_sol) { 3727a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3728a63bb30eSJed Brown } else if (snes->dm) { 3729a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3730a63bb30eSJed Brown } 3731a63bb30eSJed Brown } 3732a63bb30eSJed Brown *r = snes->vec_func; 3733a63bb30eSJed Brown } 37346cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 37356cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 37363a40ed3dSBarry Smith PetscFunctionReturn(0); 37379b94acceSBarry Smith } 37389b94acceSBarry Smith 3739c79ef259SPeter Brune /*@C 3740c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3741c79ef259SPeter Brune 3742c79ef259SPeter Brune Input Parameter: 3743c79ef259SPeter Brune . snes - the SNES context 3744c79ef259SPeter Brune 3745c79ef259SPeter Brune Output Parameter: 3746c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3747c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3748c79ef259SPeter Brune 3749c79ef259SPeter Brune Level: advanced 3750c79ef259SPeter Brune 3751c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3752c79ef259SPeter Brune 3753c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3754c79ef259SPeter Brune @*/ 3755c79ef259SPeter Brune 37564a2ae208SSatish Balay #undef __FUNCT__ 3757646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3758646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3759646217ecSPeter Brune { 37606cab3a1bSJed Brown PetscErrorCode ierr; 37616cab3a1bSJed Brown DM dm; 37626cab3a1bSJed Brown 3763646217ecSPeter Brune PetscFunctionBegin; 3764646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37656cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 37666cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3767646217ecSPeter Brune PetscFunctionReturn(0); 3768646217ecSPeter Brune } 3769646217ecSPeter Brune 37704a2ae208SSatish Balay #undef __FUNCT__ 37714a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 37723c7409f5SSatish Balay /*@C 37733c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3774d850072dSLois Curfman McInnes SNES options in the database. 37753c7409f5SSatish Balay 37763f9fe445SBarry Smith Logically Collective on SNES 3777fee21e36SBarry Smith 3778c7afd0dbSLois Curfman McInnes Input Parameter: 3779c7afd0dbSLois Curfman McInnes + snes - the SNES context 3780c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3781c7afd0dbSLois Curfman McInnes 3782d850072dSLois Curfman McInnes Notes: 3783a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3784c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3785d850072dSLois Curfman McInnes 378636851e7fSLois Curfman McInnes Level: advanced 378736851e7fSLois Curfman McInnes 37883c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3789a86d99e1SLois Curfman McInnes 3790a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 37913c7409f5SSatish Balay @*/ 37927087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 37933c7409f5SSatish Balay { 3794dfbe8321SBarry Smith PetscErrorCode ierr; 37953c7409f5SSatish Balay 37963a40ed3dSBarry Smith PetscFunctionBegin; 37970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3798639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 37991cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 380094b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 38013a40ed3dSBarry Smith PetscFunctionReturn(0); 38023c7409f5SSatish Balay } 38033c7409f5SSatish Balay 38044a2ae208SSatish Balay #undef __FUNCT__ 38054a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 38063c7409f5SSatish Balay /*@C 3807f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3808d850072dSLois Curfman McInnes SNES options in the database. 38093c7409f5SSatish Balay 38103f9fe445SBarry Smith Logically Collective on SNES 3811fee21e36SBarry Smith 3812c7afd0dbSLois Curfman McInnes Input Parameters: 3813c7afd0dbSLois Curfman McInnes + snes - the SNES context 3814c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3815c7afd0dbSLois Curfman McInnes 3816d850072dSLois Curfman McInnes Notes: 3817a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3818c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3819d850072dSLois Curfman McInnes 382036851e7fSLois Curfman McInnes Level: advanced 382136851e7fSLois Curfman McInnes 38223c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3823a86d99e1SLois Curfman McInnes 3824a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 38253c7409f5SSatish Balay @*/ 38267087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 38273c7409f5SSatish Balay { 3828dfbe8321SBarry Smith PetscErrorCode ierr; 38293c7409f5SSatish Balay 38303a40ed3dSBarry Smith PetscFunctionBegin; 38310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3832639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38331cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 383494b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 38353a40ed3dSBarry Smith PetscFunctionReturn(0); 38363c7409f5SSatish Balay } 38373c7409f5SSatish Balay 38384a2ae208SSatish Balay #undef __FUNCT__ 38394a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 38409ab63eb5SSatish Balay /*@C 38413c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 38423c7409f5SSatish Balay SNES options in the database. 38433c7409f5SSatish Balay 3844c7afd0dbSLois Curfman McInnes Not Collective 3845c7afd0dbSLois Curfman McInnes 38463c7409f5SSatish Balay Input Parameter: 38473c7409f5SSatish Balay . snes - the SNES context 38483c7409f5SSatish Balay 38493c7409f5SSatish Balay Output Parameter: 38503c7409f5SSatish Balay . prefix - pointer to the prefix string used 38513c7409f5SSatish Balay 38524ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 38539ab63eb5SSatish Balay sufficient length to hold the prefix. 38549ab63eb5SSatish Balay 385536851e7fSLois Curfman McInnes Level: advanced 385636851e7fSLois Curfman McInnes 38573c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3858a86d99e1SLois Curfman McInnes 3859a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 38603c7409f5SSatish Balay @*/ 38617087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 38623c7409f5SSatish Balay { 3863dfbe8321SBarry Smith PetscErrorCode ierr; 38643c7409f5SSatish Balay 38653a40ed3dSBarry Smith PetscFunctionBegin; 38660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3867639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38683a40ed3dSBarry Smith PetscFunctionReturn(0); 38693c7409f5SSatish Balay } 38703c7409f5SSatish Balay 3871b2002411SLois Curfman McInnes 38724a2ae208SSatish Balay #undef __FUNCT__ 38734a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 38743cea93caSBarry Smith /*@C 38753cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 38763cea93caSBarry Smith 38777f6c08e0SMatthew Knepley Level: advanced 38783cea93caSBarry Smith @*/ 38797087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3880b2002411SLois Curfman McInnes { 3881e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3882dfbe8321SBarry Smith PetscErrorCode ierr; 3883b2002411SLois Curfman McInnes 3884b2002411SLois Curfman McInnes PetscFunctionBegin; 3885b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3886c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3887b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3888b2002411SLois Curfman McInnes } 3889da9b6338SBarry Smith 3890da9b6338SBarry Smith #undef __FUNCT__ 3891da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 38927087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3893da9b6338SBarry Smith { 3894dfbe8321SBarry Smith PetscErrorCode ierr; 389577431f27SBarry Smith PetscInt N,i,j; 3896da9b6338SBarry Smith Vec u,uh,fh; 3897da9b6338SBarry Smith PetscScalar value; 3898da9b6338SBarry Smith PetscReal norm; 3899da9b6338SBarry Smith 3900da9b6338SBarry Smith PetscFunctionBegin; 3901da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3902da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3903da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3904da9b6338SBarry Smith 3905da9b6338SBarry Smith /* currently only works for sequential */ 3906da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3907da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3908da9b6338SBarry Smith for (i=0; i<N; i++) { 3909da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 391077431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3911da9b6338SBarry Smith for (j=-10; j<11; j++) { 3912ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3913da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 39143ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3915da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 391677431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3917da9b6338SBarry Smith value = -value; 3918da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3919da9b6338SBarry Smith } 3920da9b6338SBarry Smith } 39216bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 39226bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3923da9b6338SBarry Smith PetscFunctionReturn(0); 3924da9b6338SBarry Smith } 392571f87433Sdalcinl 392671f87433Sdalcinl #undef __FUNCT__ 3927fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 392871f87433Sdalcinl /*@ 3929fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 393071f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 393171f87433Sdalcinl Newton method. 393271f87433Sdalcinl 39333f9fe445SBarry Smith Logically Collective on SNES 393471f87433Sdalcinl 393571f87433Sdalcinl Input Parameters: 393671f87433Sdalcinl + snes - SNES context 393771f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 393871f87433Sdalcinl 393964ba62caSBarry Smith Options Database: 394064ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 394164ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 394264ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 394364ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 394464ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 394564ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 394664ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 394764ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 394864ba62caSBarry Smith 394971f87433Sdalcinl Notes: 395071f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 395171f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 395271f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 395371f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 395471f87433Sdalcinl solver. 395571f87433Sdalcinl 395671f87433Sdalcinl Level: advanced 395771f87433Sdalcinl 395871f87433Sdalcinl Reference: 395971f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 396071f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 396171f87433Sdalcinl 396271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 396371f87433Sdalcinl 3964fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 396571f87433Sdalcinl @*/ 39667087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 396771f87433Sdalcinl { 396871f87433Sdalcinl PetscFunctionBegin; 39690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3970acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 397171f87433Sdalcinl snes->ksp_ewconv = flag; 397271f87433Sdalcinl PetscFunctionReturn(0); 397371f87433Sdalcinl } 397471f87433Sdalcinl 397571f87433Sdalcinl #undef __FUNCT__ 3976fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 397771f87433Sdalcinl /*@ 3978fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 397971f87433Sdalcinl for computing relative tolerance for linear solvers within an 398071f87433Sdalcinl inexact Newton method. 398171f87433Sdalcinl 398271f87433Sdalcinl Not Collective 398371f87433Sdalcinl 398471f87433Sdalcinl Input Parameter: 398571f87433Sdalcinl . snes - SNES context 398671f87433Sdalcinl 398771f87433Sdalcinl Output Parameter: 398871f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 398971f87433Sdalcinl 399071f87433Sdalcinl Notes: 399171f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 399271f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 399371f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 399471f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 399571f87433Sdalcinl solver. 399671f87433Sdalcinl 399771f87433Sdalcinl Level: advanced 399871f87433Sdalcinl 399971f87433Sdalcinl Reference: 400071f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 400171f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 400271f87433Sdalcinl 400371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 400471f87433Sdalcinl 4005fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 400671f87433Sdalcinl @*/ 40077087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 400871f87433Sdalcinl { 400971f87433Sdalcinl PetscFunctionBegin; 40100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 401171f87433Sdalcinl PetscValidPointer(flag,2); 401271f87433Sdalcinl *flag = snes->ksp_ewconv; 401371f87433Sdalcinl PetscFunctionReturn(0); 401471f87433Sdalcinl } 401571f87433Sdalcinl 401671f87433Sdalcinl #undef __FUNCT__ 4017fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 401871f87433Sdalcinl /*@ 4019fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 402071f87433Sdalcinl convergence criteria for the linear solvers within an inexact 402171f87433Sdalcinl Newton method. 402271f87433Sdalcinl 40233f9fe445SBarry Smith Logically Collective on SNES 402471f87433Sdalcinl 402571f87433Sdalcinl Input Parameters: 402671f87433Sdalcinl + snes - SNES context 402771f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 402871f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 402971f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 403071f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 403171f87433Sdalcinl (0 <= gamma2 <= 1) 403271f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 403371f87433Sdalcinl . alpha2 - power for safeguard 403471f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 403571f87433Sdalcinl 403671f87433Sdalcinl Note: 403771f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 403871f87433Sdalcinl 403971f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 404071f87433Sdalcinl 404171f87433Sdalcinl Level: advanced 404271f87433Sdalcinl 404371f87433Sdalcinl Reference: 404471f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 404571f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 404671f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 404771f87433Sdalcinl 404871f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 404971f87433Sdalcinl 4050fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 405171f87433Sdalcinl @*/ 40527087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 405371f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 405471f87433Sdalcinl { 4055fa9f3622SBarry Smith SNESKSPEW *kctx; 405671f87433Sdalcinl PetscFunctionBegin; 40570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4058fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4059e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4060c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 4061c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4062c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4063c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 4064c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 4065c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 4066c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 406771f87433Sdalcinl 406871f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 406971f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 407071f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 407171f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 407271f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 407371f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 407471f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 407571f87433Sdalcinl 407671f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 4077e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 407871f87433Sdalcinl } 407971f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 4080e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 408171f87433Sdalcinl } 408271f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 4083e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 408471f87433Sdalcinl } 408571f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 4086e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 408771f87433Sdalcinl } 408871f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 4089e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 409071f87433Sdalcinl } 409171f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 4092e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 409371f87433Sdalcinl } 409471f87433Sdalcinl PetscFunctionReturn(0); 409571f87433Sdalcinl } 409671f87433Sdalcinl 409771f87433Sdalcinl #undef __FUNCT__ 4098fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 409971f87433Sdalcinl /*@ 4100fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 410171f87433Sdalcinl convergence criteria for the linear solvers within an inexact 410271f87433Sdalcinl Newton method. 410371f87433Sdalcinl 410471f87433Sdalcinl Not Collective 410571f87433Sdalcinl 410671f87433Sdalcinl Input Parameters: 410771f87433Sdalcinl snes - SNES context 410871f87433Sdalcinl 410971f87433Sdalcinl Output Parameters: 411071f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 411171f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 411271f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 411371f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 411471f87433Sdalcinl (0 <= gamma2 <= 1) 411571f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 411671f87433Sdalcinl . alpha2 - power for safeguard 411771f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 411871f87433Sdalcinl 411971f87433Sdalcinl Level: advanced 412071f87433Sdalcinl 412171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 412271f87433Sdalcinl 4123fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 412471f87433Sdalcinl @*/ 41257087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 412671f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 412771f87433Sdalcinl { 4128fa9f3622SBarry Smith SNESKSPEW *kctx; 412971f87433Sdalcinl PetscFunctionBegin; 41300700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4131fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4132e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 413371f87433Sdalcinl if(version) *version = kctx->version; 413471f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 413571f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 413671f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 413771f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 413871f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 413971f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 414071f87433Sdalcinl PetscFunctionReturn(0); 414171f87433Sdalcinl } 414271f87433Sdalcinl 414371f87433Sdalcinl #undef __FUNCT__ 4144fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 4145fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 414671f87433Sdalcinl { 414771f87433Sdalcinl PetscErrorCode ierr; 4148fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 414971f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 415071f87433Sdalcinl 415171f87433Sdalcinl PetscFunctionBegin; 4152e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 415371f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 415471f87433Sdalcinl rtol = kctx->rtol_0; 415571f87433Sdalcinl } else { 415671f87433Sdalcinl if (kctx->version == 1) { 415771f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 415871f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 415971f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 416071f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 416171f87433Sdalcinl } else if (kctx->version == 2) { 416271f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 416371f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 416471f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 416571f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 416671f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 416771f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 416871f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 416971f87433Sdalcinl stol = PetscMax(rtol,stol); 417071f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 417171f87433Sdalcinl /* safeguard: avoid oversolving */ 417271f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 417371f87433Sdalcinl stol = PetscMax(rtol,stol); 417471f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4175e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 417671f87433Sdalcinl } 417771f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 417871f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 417971f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 418071f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 418171f87433Sdalcinl PetscFunctionReturn(0); 418271f87433Sdalcinl } 418371f87433Sdalcinl 418471f87433Sdalcinl #undef __FUNCT__ 4185fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4186fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 418771f87433Sdalcinl { 418871f87433Sdalcinl PetscErrorCode ierr; 4189fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 419071f87433Sdalcinl PCSide pcside; 419171f87433Sdalcinl Vec lres; 419271f87433Sdalcinl 419371f87433Sdalcinl PetscFunctionBegin; 4194e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 419571f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 419671f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 419771f87433Sdalcinl if (kctx->version == 1) { 4198b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 419971f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 420071f87433Sdalcinl /* KSP residual is true linear residual */ 420171f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 420271f87433Sdalcinl } else { 420371f87433Sdalcinl /* KSP residual is preconditioned residual */ 420471f87433Sdalcinl /* compute true linear residual norm */ 420571f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 420671f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 420771f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 420871f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 42096bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 421071f87433Sdalcinl } 421171f87433Sdalcinl } 421271f87433Sdalcinl PetscFunctionReturn(0); 421371f87433Sdalcinl } 421471f87433Sdalcinl 421571f87433Sdalcinl #undef __FUNCT__ 421671f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 421771f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 421871f87433Sdalcinl { 421971f87433Sdalcinl PetscErrorCode ierr; 422071f87433Sdalcinl 422171f87433Sdalcinl PetscFunctionBegin; 4222fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 422371f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4224fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 422571f87433Sdalcinl PetscFunctionReturn(0); 422671f87433Sdalcinl } 42276c699258SBarry Smith 42286c699258SBarry Smith #undef __FUNCT__ 42296c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 42306c699258SBarry Smith /*@ 42316c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 42326c699258SBarry Smith 42333f9fe445SBarry Smith Logically Collective on SNES 42346c699258SBarry Smith 42356c699258SBarry Smith Input Parameters: 42366c699258SBarry Smith + snes - the preconditioner context 42376c699258SBarry Smith - dm - the dm 42386c699258SBarry Smith 42396c699258SBarry Smith Level: intermediate 42406c699258SBarry Smith 42416c699258SBarry Smith 42426c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 42436c699258SBarry Smith @*/ 42447087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 42456c699258SBarry Smith { 42466c699258SBarry Smith PetscErrorCode ierr; 4247345fed2cSBarry Smith KSP ksp; 42486cab3a1bSJed Brown SNESDM sdm; 42496c699258SBarry Smith 42506c699258SBarry Smith PetscFunctionBegin; 42510700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4252d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 42536cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 42546cab3a1bSJed Brown PetscContainer oldcontainer,container; 42556cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 42566cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 42576cab3a1bSJed Brown if (oldcontainer && !container) { 42586cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 42596cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 42606cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 42616cab3a1bSJed Brown sdm->originaldm = dm; 42626cab3a1bSJed Brown } 42636cab3a1bSJed Brown } 42646bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 42656cab3a1bSJed Brown } 42666c699258SBarry Smith snes->dm = dm; 4267345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4268345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4269f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 42702c155ee1SBarry Smith if (snes->pc) { 42712c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 42722c155ee1SBarry Smith } 42736c699258SBarry Smith PetscFunctionReturn(0); 42746c699258SBarry Smith } 42756c699258SBarry Smith 42766c699258SBarry Smith #undef __FUNCT__ 42776c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 42786c699258SBarry Smith /*@ 42796c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 42806c699258SBarry Smith 42813f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 42826c699258SBarry Smith 42836c699258SBarry Smith Input Parameter: 42846c699258SBarry Smith . snes - the preconditioner context 42856c699258SBarry Smith 42866c699258SBarry Smith Output Parameter: 42876c699258SBarry Smith . dm - the dm 42886c699258SBarry Smith 42896c699258SBarry Smith Level: intermediate 42906c699258SBarry Smith 42916c699258SBarry Smith 42926c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 42936c699258SBarry Smith @*/ 42947087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 42956c699258SBarry Smith { 42966cab3a1bSJed Brown PetscErrorCode ierr; 42976cab3a1bSJed Brown 42986c699258SBarry Smith PetscFunctionBegin; 42990700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 43006cab3a1bSJed Brown if (!snes->dm) { 43016cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 43026cab3a1bSJed Brown } 43036c699258SBarry Smith *dm = snes->dm; 43046c699258SBarry Smith PetscFunctionReturn(0); 43056c699258SBarry Smith } 43060807856dSBarry Smith 430731823bd8SMatthew G Knepley #undef __FUNCT__ 430831823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 430931823bd8SMatthew G Knepley /*@ 4310fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 431131823bd8SMatthew G Knepley 431231823bd8SMatthew G Knepley Collective on SNES 431331823bd8SMatthew G Knepley 431431823bd8SMatthew G Knepley Input Parameters: 431531823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 431631823bd8SMatthew G Knepley - pc - the preconditioner object 431731823bd8SMatthew G Knepley 431831823bd8SMatthew G Knepley Notes: 431931823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 432031823bd8SMatthew G Knepley to configure it using the API). 432131823bd8SMatthew G Knepley 432231823bd8SMatthew G Knepley Level: developer 432331823bd8SMatthew G Knepley 432431823bd8SMatthew G Knepley .keywords: SNES, set, precondition 432531823bd8SMatthew G Knepley .seealso: SNESGetPC() 432631823bd8SMatthew G Knepley @*/ 432731823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 432831823bd8SMatthew G Knepley { 432931823bd8SMatthew G Knepley PetscErrorCode ierr; 433031823bd8SMatthew G Knepley 433131823bd8SMatthew G Knepley PetscFunctionBegin; 433231823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 433331823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 433431823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 433531823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4336bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 433731823bd8SMatthew G Knepley snes->pc = pc; 433831823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 433931823bd8SMatthew G Knepley PetscFunctionReturn(0); 434031823bd8SMatthew G Knepley } 434131823bd8SMatthew G Knepley 434231823bd8SMatthew G Knepley #undef __FUNCT__ 434331823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 434431823bd8SMatthew G Knepley /*@ 4345fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 434631823bd8SMatthew G Knepley 434731823bd8SMatthew G Knepley Not Collective 434831823bd8SMatthew G Knepley 434931823bd8SMatthew G Knepley Input Parameter: 435031823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 435131823bd8SMatthew G Knepley 435231823bd8SMatthew G Knepley Output Parameter: 435331823bd8SMatthew G Knepley . pc - preconditioner context 435431823bd8SMatthew G Knepley 435531823bd8SMatthew G Knepley Level: developer 435631823bd8SMatthew G Knepley 435731823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 435831823bd8SMatthew G Knepley .seealso: SNESSetPC() 435931823bd8SMatthew G Knepley @*/ 436031823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 436131823bd8SMatthew G Knepley { 436231823bd8SMatthew G Knepley PetscErrorCode ierr; 436331823bd8SMatthew G Knepley 436431823bd8SMatthew G Knepley PetscFunctionBegin; 436531823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 436631823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 436731823bd8SMatthew G Knepley if (!snes->pc) { 436831823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 43694a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 437031823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 437131823bd8SMatthew G Knepley } 437231823bd8SMatthew G Knepley *pc = snes->pc; 437331823bd8SMatthew G Knepley PetscFunctionReturn(0); 437431823bd8SMatthew G Knepley } 437531823bd8SMatthew G Knepley 43769e764e56SPeter Brune #undef __FUNCT__ 4377f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch" 43789e764e56SPeter Brune /*@ 43798141a3b9SPeter Brune SNESSetSNESLineSearch - Sets the linesearch on the SNES instance. 43809e764e56SPeter Brune 43819e764e56SPeter Brune Collective on SNES 43829e764e56SPeter Brune 43839e764e56SPeter Brune Input Parameters: 43849e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 43859e764e56SPeter Brune - linesearch - the linesearch object 43869e764e56SPeter Brune 43879e764e56SPeter Brune Notes: 4388f1c6b773SPeter Brune Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example, 43899e764e56SPeter Brune to configure it using the API). 43909e764e56SPeter Brune 43919e764e56SPeter Brune Level: developer 43929e764e56SPeter Brune 43939e764e56SPeter Brune .keywords: SNES, set, linesearch 4394f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch() 43959e764e56SPeter Brune @*/ 4396f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch) 43979e764e56SPeter Brune { 43989e764e56SPeter Brune PetscErrorCode ierr; 43999e764e56SPeter Brune 44009e764e56SPeter Brune PetscFunctionBegin; 44019e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4402f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 44039e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 44049e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 4405f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 44069e764e56SPeter Brune snes->linesearch = linesearch; 44079e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 44089e764e56SPeter Brune PetscFunctionReturn(0); 44099e764e56SPeter Brune } 44109e764e56SPeter Brune 44119e764e56SPeter Brune #undef __FUNCT__ 4412f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch" 4413ea5d4fccSPeter Brune /*@C 44148141a3b9SPeter Brune SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 44158141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 44169e764e56SPeter Brune 44179e764e56SPeter Brune Not Collective 44189e764e56SPeter Brune 44199e764e56SPeter Brune Input Parameter: 44209e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 44219e764e56SPeter Brune 44229e764e56SPeter Brune Output Parameter: 44239e764e56SPeter Brune . linesearch - linesearch context 44249e764e56SPeter Brune 44259e764e56SPeter Brune Level: developer 44269e764e56SPeter Brune 44279e764e56SPeter Brune .keywords: SNES, get, linesearch 4428f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch() 44299e764e56SPeter Brune @*/ 4430f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch) 44319e764e56SPeter Brune { 44329e764e56SPeter Brune PetscErrorCode ierr; 44339e764e56SPeter Brune const char *optionsprefix; 44349e764e56SPeter Brune 44359e764e56SPeter Brune PetscFunctionBegin; 44369e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 44379e764e56SPeter Brune PetscValidPointer(linesearch, 2); 44389e764e56SPeter Brune if (!snes->linesearch) { 44399e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 4440f1c6b773SPeter Brune ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr); 4441f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 4442b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 44439e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 44449e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 44459e764e56SPeter Brune } 44469e764e56SPeter Brune *linesearch = snes->linesearch; 44479e764e56SPeter Brune PetscFunctionReturn(0); 44489e764e56SPeter Brune } 44499e764e56SPeter Brune 445069b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4451c6db04a5SJed Brown #include <mex.h> 445269b4f73cSBarry Smith 44538f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 44548f6e6473SBarry Smith 44550807856dSBarry Smith #undef __FUNCT__ 44560807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 44570807856dSBarry Smith /* 44580807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 44590807856dSBarry Smith SNESSetFunctionMatlab(). 44600807856dSBarry Smith 44610807856dSBarry Smith Collective on SNES 44620807856dSBarry Smith 44630807856dSBarry Smith Input Parameters: 44640807856dSBarry Smith + snes - the SNES context 44650807856dSBarry Smith - x - input vector 44660807856dSBarry Smith 44670807856dSBarry Smith Output Parameter: 44680807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 44690807856dSBarry Smith 44700807856dSBarry Smith Notes: 44710807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 44720807856dSBarry Smith implementations, so most users would not generally call this routine 44730807856dSBarry Smith themselves. 44740807856dSBarry Smith 44750807856dSBarry Smith Level: developer 44760807856dSBarry Smith 44770807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 44780807856dSBarry Smith 44790807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 448061b2408cSBarry Smith */ 44817087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 44820807856dSBarry Smith { 4483e650e774SBarry Smith PetscErrorCode ierr; 44848f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 44858f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 44868f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 448791621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4488e650e774SBarry Smith 44890807856dSBarry Smith PetscFunctionBegin; 44900807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 44910807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 44920807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 44930807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 44940807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 44950807856dSBarry Smith 44960807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4497e650e774SBarry Smith 449891621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4499e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4500e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 450191621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 450291621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 450391621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 45048f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 45058f6e6473SBarry Smith prhs[4] = sctx->ctx; 4506b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4507e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4508e650e774SBarry Smith mxDestroyArray(prhs[0]); 4509e650e774SBarry Smith mxDestroyArray(prhs[1]); 4510e650e774SBarry Smith mxDestroyArray(prhs[2]); 45118f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4512e650e774SBarry Smith mxDestroyArray(plhs[0]); 45130807856dSBarry Smith PetscFunctionReturn(0); 45140807856dSBarry Smith } 45150807856dSBarry Smith 45160807856dSBarry Smith 45170807856dSBarry Smith #undef __FUNCT__ 45180807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 451961b2408cSBarry Smith /* 45200807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 45210807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4522e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 45230807856dSBarry Smith 45240807856dSBarry Smith Logically Collective on SNES 45250807856dSBarry Smith 45260807856dSBarry Smith Input Parameters: 45270807856dSBarry Smith + snes - the SNES context 45280807856dSBarry Smith . r - vector to store function value 45290807856dSBarry Smith - func - function evaluation routine 45300807856dSBarry Smith 45310807856dSBarry Smith Calling sequence of func: 453261b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 45330807856dSBarry Smith 45340807856dSBarry Smith 45350807856dSBarry Smith Notes: 45360807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 45370807856dSBarry Smith $ f'(x) x = -f(x), 45380807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 45390807856dSBarry Smith 45400807856dSBarry Smith Level: beginner 45410807856dSBarry Smith 45420807856dSBarry Smith .keywords: SNES, nonlinear, set, function 45430807856dSBarry Smith 45440807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 454561b2408cSBarry Smith */ 45467087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 45470807856dSBarry Smith { 45480807856dSBarry Smith PetscErrorCode ierr; 45498f6e6473SBarry Smith SNESMatlabContext *sctx; 45500807856dSBarry Smith 45510807856dSBarry Smith PetscFunctionBegin; 45528f6e6473SBarry Smith /* currently sctx is memory bleed */ 45538f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 45548f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 45558f6e6473SBarry Smith /* 45568f6e6473SBarry Smith This should work, but it doesn't 45578f6e6473SBarry Smith sctx->ctx = ctx; 45588f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 45598f6e6473SBarry Smith */ 45608f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 45618f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 45620807856dSBarry Smith PetscFunctionReturn(0); 45630807856dSBarry Smith } 456469b4f73cSBarry Smith 456561b2408cSBarry Smith #undef __FUNCT__ 456661b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 456761b2408cSBarry Smith /* 456861b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 456961b2408cSBarry Smith SNESSetJacobianMatlab(). 457061b2408cSBarry Smith 457161b2408cSBarry Smith Collective on SNES 457261b2408cSBarry Smith 457361b2408cSBarry Smith Input Parameters: 457461b2408cSBarry Smith + snes - the SNES context 457561b2408cSBarry Smith . x - input vector 457661b2408cSBarry Smith . A, B - the matrices 457761b2408cSBarry Smith - ctx - user context 457861b2408cSBarry Smith 457961b2408cSBarry Smith Output Parameter: 458061b2408cSBarry Smith . flag - structure of the matrix 458161b2408cSBarry Smith 458261b2408cSBarry Smith Level: developer 458361b2408cSBarry Smith 458461b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 458561b2408cSBarry Smith 458661b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 458761b2408cSBarry Smith @*/ 45887087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 458961b2408cSBarry Smith { 459061b2408cSBarry Smith PetscErrorCode ierr; 459161b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 459261b2408cSBarry Smith int nlhs = 2,nrhs = 6; 459361b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 459461b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 459561b2408cSBarry Smith 459661b2408cSBarry Smith PetscFunctionBegin; 459761b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 459861b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 459961b2408cSBarry Smith 460061b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 460161b2408cSBarry Smith 460261b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 460361b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 460461b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 460561b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 460661b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 460761b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 460861b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 460961b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 461061b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 461161b2408cSBarry Smith prhs[5] = sctx->ctx; 4612b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 461361b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 461461b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 461561b2408cSBarry Smith mxDestroyArray(prhs[0]); 461661b2408cSBarry Smith mxDestroyArray(prhs[1]); 461761b2408cSBarry Smith mxDestroyArray(prhs[2]); 461861b2408cSBarry Smith mxDestroyArray(prhs[3]); 461961b2408cSBarry Smith mxDestroyArray(prhs[4]); 462061b2408cSBarry Smith mxDestroyArray(plhs[0]); 462161b2408cSBarry Smith mxDestroyArray(plhs[1]); 462261b2408cSBarry Smith PetscFunctionReturn(0); 462361b2408cSBarry Smith } 462461b2408cSBarry Smith 462561b2408cSBarry Smith 462661b2408cSBarry Smith #undef __FUNCT__ 462761b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 462861b2408cSBarry Smith /* 462961b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 463061b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4631e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 463261b2408cSBarry Smith 463361b2408cSBarry Smith Logically Collective on SNES 463461b2408cSBarry Smith 463561b2408cSBarry Smith Input Parameters: 463661b2408cSBarry Smith + snes - the SNES context 463761b2408cSBarry Smith . A,B - Jacobian matrices 463861b2408cSBarry Smith . func - function evaluation routine 463961b2408cSBarry Smith - ctx - user context 464061b2408cSBarry Smith 464161b2408cSBarry Smith Calling sequence of func: 464261b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 464361b2408cSBarry Smith 464461b2408cSBarry Smith 464561b2408cSBarry Smith Level: developer 464661b2408cSBarry Smith 464761b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 464861b2408cSBarry Smith 464961b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 465061b2408cSBarry Smith */ 46517087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 465261b2408cSBarry Smith { 465361b2408cSBarry Smith PetscErrorCode ierr; 465461b2408cSBarry Smith SNESMatlabContext *sctx; 465561b2408cSBarry Smith 465661b2408cSBarry Smith PetscFunctionBegin; 465761b2408cSBarry Smith /* currently sctx is memory bleed */ 465861b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 465961b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 466061b2408cSBarry Smith /* 466161b2408cSBarry Smith This should work, but it doesn't 466261b2408cSBarry Smith sctx->ctx = ctx; 466361b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 466461b2408cSBarry Smith */ 466561b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 466661b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 466761b2408cSBarry Smith PetscFunctionReturn(0); 466861b2408cSBarry Smith } 466969b4f73cSBarry Smith 4670f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4671f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4672f9eb7ae2SShri Abhyankar /* 4673f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4674f9eb7ae2SShri Abhyankar 4675f9eb7ae2SShri Abhyankar Collective on SNES 4676f9eb7ae2SShri Abhyankar 4677f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4678f9eb7ae2SShri Abhyankar @*/ 46797087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4680f9eb7ae2SShri Abhyankar { 4681f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 468248f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4683f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4684f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4685f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4686f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4687f9eb7ae2SShri Abhyankar 4688f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4689f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4690f9eb7ae2SShri Abhyankar 4691f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4692f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4693f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4694f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4695f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4696f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4697f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4698f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4699f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4700f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4701f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4702f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4703f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4704f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4705f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4706f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4707f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4708f9eb7ae2SShri Abhyankar } 4709f9eb7ae2SShri Abhyankar 4710f9eb7ae2SShri Abhyankar 4711f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4712f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4713f9eb7ae2SShri Abhyankar /* 4714e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4715f9eb7ae2SShri Abhyankar 4716f9eb7ae2SShri Abhyankar Level: developer 4717f9eb7ae2SShri Abhyankar 4718f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4719f9eb7ae2SShri Abhyankar 4720f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4721f9eb7ae2SShri Abhyankar */ 47227087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4723f9eb7ae2SShri Abhyankar { 4724f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4725f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4726f9eb7ae2SShri Abhyankar 4727f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4728f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4729f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4730f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4731f9eb7ae2SShri Abhyankar /* 4732f9eb7ae2SShri Abhyankar This should work, but it doesn't 4733f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4734f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4735f9eb7ae2SShri Abhyankar */ 4736f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4737f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4738f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4739f9eb7ae2SShri Abhyankar } 4740f9eb7ae2SShri Abhyankar 474169b4f73cSBarry Smith #endif 4742