19b94acceSBarry Smith 2c6db04a5SJed Brown #include <private/snesimpl.h> /*I "petscsnes.h" I*/ 3*6cab3a1bSJed 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; 10701cf23dSPeter Brune PetscLogEvent SNES_Solve, SNES_LineSearch, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval; 11a09944afSBarry Smith 12a09944afSBarry Smith #undef __FUNCT__ 13cab2e9ccSBarry Smith #define __FUNCT__ "SNESDMComputeJacobian" 14cab2e9ccSBarry Smith /* 15cab2e9ccSBarry Smith Translates from a SNES call to a DM call in computing a Jacobian 16cab2e9ccSBarry Smith */ 17cab2e9ccSBarry Smith PetscErrorCode SNESDMComputeJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr) 18cab2e9ccSBarry Smith { 19cab2e9ccSBarry Smith PetscErrorCode ierr; 20cab2e9ccSBarry Smith DM dm; 21cab2e9ccSBarry Smith 22cab2e9ccSBarry Smith PetscFunctionBegin; 23cab2e9ccSBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 24cab2e9ccSBarry Smith ierr = DMComputeJacobian(dm,X,*J,*B,flag);CHKERRQ(ierr); 25cab2e9ccSBarry Smith PetscFunctionReturn(0); 26cab2e9ccSBarry Smith } 27cab2e9ccSBarry Smith 28cab2e9ccSBarry Smith #undef __FUNCT__ 29e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged" 30e113a28aSBarry Smith /*@ 31e113a28aSBarry Smith SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 32e113a28aSBarry Smith 333f9fe445SBarry Smith Logically Collective on SNES 34e113a28aSBarry Smith 35e113a28aSBarry Smith Input Parameters: 36e113a28aSBarry Smith + snes - iterative context obtained from SNESCreate() 37e113a28aSBarry Smith - flg - PETSC_TRUE indicates you want the error generated 38e113a28aSBarry Smith 39e113a28aSBarry Smith Options database keys: 40e113a28aSBarry Smith . -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false) 41e113a28aSBarry Smith 42e113a28aSBarry Smith Level: intermediate 43e113a28aSBarry Smith 44e113a28aSBarry Smith Notes: 45e113a28aSBarry Smith Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 46e113a28aSBarry Smith to determine if it has converged. 47e113a28aSBarry Smith 48e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 49e113a28aSBarry Smith 50e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 51e113a28aSBarry Smith @*/ 527087cfbeSBarry Smith PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 53e113a28aSBarry Smith { 54e113a28aSBarry Smith PetscFunctionBegin; 55e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 56acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flg,2); 57e113a28aSBarry Smith snes->errorifnotconverged = flg; 58dd568438SSatish Balay 59e113a28aSBarry Smith PetscFunctionReturn(0); 60e113a28aSBarry Smith } 61e113a28aSBarry Smith 62e113a28aSBarry Smith #undef __FUNCT__ 63e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged" 64e113a28aSBarry Smith /*@ 65e113a28aSBarry Smith SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 66e113a28aSBarry Smith 67e113a28aSBarry Smith Not Collective 68e113a28aSBarry Smith 69e113a28aSBarry Smith Input Parameter: 70e113a28aSBarry Smith . snes - iterative context obtained from SNESCreate() 71e113a28aSBarry Smith 72e113a28aSBarry Smith Output Parameter: 73e113a28aSBarry Smith . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 74e113a28aSBarry Smith 75e113a28aSBarry Smith Level: intermediate 76e113a28aSBarry Smith 77e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 78e113a28aSBarry Smith 79e113a28aSBarry Smith .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 80e113a28aSBarry Smith @*/ 817087cfbeSBarry Smith PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 82e113a28aSBarry Smith { 83e113a28aSBarry Smith PetscFunctionBegin; 84e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 85e113a28aSBarry Smith PetscValidPointer(flag,2); 86e113a28aSBarry Smith *flag = snes->errorifnotconverged; 87e113a28aSBarry Smith PetscFunctionReturn(0); 88e113a28aSBarry Smith } 89e113a28aSBarry Smith 90e113a28aSBarry Smith #undef __FUNCT__ 914936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError" 92e725d27bSBarry Smith /*@ 934936397dSBarry Smith SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not 944936397dSBarry Smith in the functions domain. For example, negative pressure. 954936397dSBarry Smith 963f9fe445SBarry Smith Logically Collective on SNES 974936397dSBarry Smith 984936397dSBarry Smith Input Parameters: 994936397dSBarry Smith . SNES - the SNES context 1004936397dSBarry Smith 10128529972SSatish Balay Level: advanced 1024936397dSBarry Smith 1034936397dSBarry Smith .keywords: SNES, view 1044936397dSBarry Smith 1054936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction() 1064936397dSBarry Smith @*/ 1077087cfbeSBarry Smith PetscErrorCode SNESSetFunctionDomainError(SNES snes) 1084936397dSBarry Smith { 1094936397dSBarry Smith PetscFunctionBegin; 1100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1114936397dSBarry Smith snes->domainerror = PETSC_TRUE; 1124936397dSBarry Smith PetscFunctionReturn(0); 1134936397dSBarry Smith } 1144936397dSBarry Smith 1154936397dSBarry Smith #undef __FUNCT__ 1164a2ae208SSatish Balay #define __FUNCT__ "SNESView" 1177e2c5f70SBarry Smith /*@C 1189b94acceSBarry Smith SNESView - Prints the SNES data structure. 1199b94acceSBarry Smith 1204c49b128SBarry Smith Collective on SNES 121fee21e36SBarry Smith 122c7afd0dbSLois Curfman McInnes Input Parameters: 123c7afd0dbSLois Curfman McInnes + SNES - the SNES context 124c7afd0dbSLois Curfman McInnes - viewer - visualization context 125c7afd0dbSLois Curfman McInnes 1269b94acceSBarry Smith Options Database Key: 127c8a8ba5cSLois Curfman McInnes . -snes_view - Calls SNESView() at end of SNESSolve() 1289b94acceSBarry Smith 1299b94acceSBarry Smith Notes: 1309b94acceSBarry Smith The available visualization contexts include 131b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 132b0a32e0cSBarry Smith - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 133c8a8ba5cSLois Curfman McInnes output where only the first processor opens 134c8a8ba5cSLois Curfman McInnes the file. All other processors send their 135c8a8ba5cSLois Curfman McInnes data to the first processor to print. 1369b94acceSBarry Smith 1373e081fefSLois Curfman McInnes The user can open an alternative visualization context with 138b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 1399b94acceSBarry Smith 14036851e7fSLois Curfman McInnes Level: beginner 14136851e7fSLois Curfman McInnes 1429b94acceSBarry Smith .keywords: SNES, view 1439b94acceSBarry Smith 144b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen() 1459b94acceSBarry Smith @*/ 1467087cfbeSBarry Smith PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 1479b94acceSBarry Smith { 148fa9f3622SBarry Smith SNESKSPEW *kctx; 149dfbe8321SBarry Smith PetscErrorCode ierr; 15094b7f48cSBarry Smith KSP ksp; 151ace3abfcSBarry Smith PetscBool iascii,isstring; 1529b94acceSBarry Smith 1533a40ed3dSBarry Smith PetscFunctionBegin; 1540700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1553050cee2SBarry Smith if (!viewer) { 1567adad957SLisandro Dalcin ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 1573050cee2SBarry Smith } 1580700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 159c9780b6fSBarry Smith PetscCheckSameComm(snes,1,viewer,2); 16074679c65SBarry Smith 1612692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1622692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 16332077d6dSBarry Smith if (iascii) { 164317d6ea6SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr); 165e7788613SBarry Smith if (snes->ops->view) { 166b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 167e7788613SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 168b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1690ef38995SBarry Smith } 17077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 171a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n", 17270441072SBarry Smith snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr); 17377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 17477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 1759b94acceSBarry Smith if (snes->ksp_ewconv) { 176fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 1779b94acceSBarry Smith if (kctx) { 17877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 179a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr); 180a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr); 1819b94acceSBarry Smith } 1829b94acceSBarry Smith } 183eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 184eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 185eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 186eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 187eb1f6c34SBarry Smith } 188eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 189eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 190eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 19142f4f86dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 192eb1f6c34SBarry Smith } 1930f5bd95cSBarry Smith } else if (isstring) { 194317d6ea6SBarry Smith const char *type; 195454a90a3SBarry Smith ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 196b0a32e0cSBarry Smith ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 19719bcc07fSBarry Smith } 19842f4f86dSBarry Smith if (snes->pc && snes->usespc) { 1994a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2004a0c5b0cSMatthew G Knepley ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr); 2014a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2024a0c5b0cSMatthew G Knepley } 2032c155ee1SBarry Smith if (snes->usesksp) { 2042c155ee1SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 205b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 20694b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 207b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2082c155ee1SBarry Smith } 2093a40ed3dSBarry Smith PetscFunctionReturn(0); 2109b94acceSBarry Smith } 2119b94acceSBarry Smith 21276b2cf59SMatthew Knepley /* 21376b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 21476b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 21576b2cf59SMatthew Knepley */ 21676b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 217a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 2186849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 21976b2cf59SMatthew Knepley 220e74ef692SMatthew Knepley #undef __FUNCT__ 221e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker" 222ac226902SBarry Smith /*@C 22376b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 22476b2cf59SMatthew Knepley 22576b2cf59SMatthew Knepley Not Collective 22676b2cf59SMatthew Knepley 22776b2cf59SMatthew Knepley Input Parameter: 22876b2cf59SMatthew Knepley . snescheck - function that checks for options 22976b2cf59SMatthew Knepley 23076b2cf59SMatthew Knepley Level: developer 23176b2cf59SMatthew Knepley 23276b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 23376b2cf59SMatthew Knepley @*/ 2347087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 23576b2cf59SMatthew Knepley { 23676b2cf59SMatthew Knepley PetscFunctionBegin; 23776b2cf59SMatthew Knepley if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 238e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 23976b2cf59SMatthew Knepley } 24076b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 24176b2cf59SMatthew Knepley PetscFunctionReturn(0); 24276b2cf59SMatthew Knepley } 24376b2cf59SMatthew Knepley 2447087cfbeSBarry Smith extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 245aa3661deSLisandro Dalcin 246aa3661deSLisandro Dalcin #undef __FUNCT__ 247aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private" 248ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 249aa3661deSLisandro Dalcin { 250aa3661deSLisandro Dalcin Mat J; 251aa3661deSLisandro Dalcin KSP ksp; 252aa3661deSLisandro Dalcin PC pc; 253ace3abfcSBarry Smith PetscBool match; 254aa3661deSLisandro Dalcin PetscErrorCode ierr; 255aa3661deSLisandro Dalcin 256aa3661deSLisandro Dalcin PetscFunctionBegin; 2570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 258aa3661deSLisandro Dalcin 25998613b67SLisandro Dalcin if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 26098613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 26198613b67SLisandro Dalcin ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr); 26298613b67SLisandro Dalcin } 26398613b67SLisandro Dalcin 264aa3661deSLisandro Dalcin if (version == 1) { 265aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 26698613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2679c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 268aa3661deSLisandro Dalcin } else if (version == 2) { 269e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 27082a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 271aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 272aa3661deSLisandro Dalcin #else 273e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 274aa3661deSLisandro Dalcin #endif 275a8248277SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 276aa3661deSLisandro Dalcin 277aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 278d3462f78SMatthew Knepley if (hasOperator) { 279aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 280aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 281aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 282aa3661deSLisandro Dalcin } else { 283aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 284aa3661deSLisandro Dalcin provided preconditioner matrix with the default matrix free version. */ 285*6cab3a1bSJed Brown void *functx; 286*6cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 287*6cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 288aa3661deSLisandro Dalcin /* Force no preconditioner */ 289aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 290aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 291aa3661deSLisandro Dalcin ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 292aa3661deSLisandro Dalcin if (!match) { 293aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 294aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 295aa3661deSLisandro Dalcin } 296aa3661deSLisandro Dalcin } 2976bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 298aa3661deSLisandro Dalcin PetscFunctionReturn(0); 299aa3661deSLisandro Dalcin } 300aa3661deSLisandro Dalcin 3014a2ae208SSatish Balay #undef __FUNCT__ 302*6cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices" 303*6cab3a1bSJed Brown /*@ 304*6cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 305*6cab3a1bSJed Brown 306*6cab3a1bSJed Brown Collective 307*6cab3a1bSJed Brown 308*6cab3a1bSJed Brown Input Arguments: 309*6cab3a1bSJed Brown . snes - snes to configure 310*6cab3a1bSJed Brown 311*6cab3a1bSJed Brown Level: developer 312*6cab3a1bSJed Brown 313*6cab3a1bSJed Brown .seealso: SNESSetUp() 314*6cab3a1bSJed Brown @*/ 315*6cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 316*6cab3a1bSJed Brown { 317*6cab3a1bSJed Brown PetscErrorCode ierr; 318*6cab3a1bSJed Brown DM dm; 319*6cab3a1bSJed Brown SNESDM sdm; 320*6cab3a1bSJed Brown 321*6cab3a1bSJed Brown PetscFunctionBegin; 322*6cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 323*6cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 324*6cab3a1bSJed Brown if (!sdm->computejacobian && snes->dm) { 325*6cab3a1bSJed Brown Mat J,B; 326*6cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 327*6cab3a1bSJed Brown if (snes->mf_operator) { 328*6cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 329*6cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 330*6cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 331*6cab3a1bSJed Brown } else { 332*6cab3a1bSJed Brown J = B; 333*6cab3a1bSJed Brown ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr); 334*6cab3a1bSJed Brown } 335*6cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr); 336*6cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 337*6cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 338*6cab3a1bSJed Brown } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) { 339*6cab3a1bSJed Brown Mat J; 340*6cab3a1bSJed Brown void *functx; 341*6cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 342*6cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 343*6cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 344*6cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 345*6cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 346*6cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 347*6cab3a1bSJed Brown } else if (snes->dm && snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 348*6cab3a1bSJed Brown Mat J,B; 349*6cab3a1bSJed Brown void *functx; 350*6cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 351*6cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 352*6cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 353*6cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 354*6cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 355*6cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr); 356*6cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 357*6cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 358*6cab3a1bSJed Brown } else if (snes->dm && !snes->jacobian_pre) { 359*6cab3a1bSJed Brown Mat J,B; 360*6cab3a1bSJed Brown J = snes->jacobian; 361*6cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 362*6cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 363*6cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 364*6cab3a1bSJed Brown } 365*6cab3a1bSJed Brown PetscFunctionReturn(0); 366*6cab3a1bSJed Brown } 367*6cab3a1bSJed Brown 368*6cab3a1bSJed Brown #undef __FUNCT__ 3694a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 3709b94acceSBarry Smith /*@ 37194b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 3729b94acceSBarry Smith 373c7afd0dbSLois Curfman McInnes Collective on SNES 374c7afd0dbSLois Curfman McInnes 3759b94acceSBarry Smith Input Parameter: 3769b94acceSBarry Smith . snes - the SNES context 3779b94acceSBarry Smith 37836851e7fSLois Curfman McInnes Options Database Keys: 379ea630c6eSPeter Brune + -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas 38082738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 38182738288SBarry Smith of the change in the solution between steps 38270441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 383b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 384b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 385b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 3864839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 387ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 388a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 389e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 390b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 3912492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 39282738288SBarry Smith solver; hence iterations will continue until max_it 3931fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 39482738288SBarry Smith of convergence test 395e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 396e8105e01SRichard Katz filename given prints to stdout 397a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 398a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 399a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 400a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 401e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 4025968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 403fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 40482738288SBarry Smith 40582738288SBarry Smith Options Database for Eisenstat-Walker method: 406fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 4074b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 40836851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 40936851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 41036851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 41136851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 41236851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 41336851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 41482738288SBarry Smith 41511ca99fdSLois Curfman McInnes Notes: 41611ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 4170598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 41883e2fdc7SBarry Smith 41936851e7fSLois Curfman McInnes Level: beginner 42036851e7fSLois Curfman McInnes 4219b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 4229b94acceSBarry Smith 42369ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 4249b94acceSBarry Smith @*/ 4257087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 4269b94acceSBarry Smith { 427ea630c6eSPeter Brune PetscBool flg,set,mf,mf_operator,pcset; 428efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 429aa3661deSLisandro Dalcin MatStructure matflag; 43085385478SLisandro Dalcin const char *deft = SNESLS; 43185385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 43285385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 433e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 43451e86f29SPeter Brune const char *optionsprefix; 435649052a6SBarry Smith PetscViewer monviewer; 43685385478SLisandro Dalcin PetscErrorCode ierr; 4379b94acceSBarry Smith 4383a40ed3dSBarry Smith PetscFunctionBegin; 4390700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 440ca161407SBarry Smith 441186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 4423194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 4437adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 444b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 445d64ed03dSBarry Smith if (flg) { 446186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 4477adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 448186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 449d64ed03dSBarry Smith } 45090d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 451909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 45293c39befSBarry Smith 45357034d6fSHong Zhang ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr); 45457034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 455186905e3SBarry Smith 45657034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 457b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 458b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 45950ffb88aSMatthew Knepley ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 460ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 461acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 46285385478SLisandro Dalcin 463a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 464a8054027SBarry Smith if (flg) { 465a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 466a8054027SBarry Smith } 467e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 468e35cf81dSBarry Smith if (flg) { 469e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 470e35cf81dSBarry Smith } 471efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 472efd51863SBarry Smith if (flg) { 473efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 474efd51863SBarry Smith } 475a8054027SBarry Smith 47685385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 47785385478SLisandro Dalcin if (flg) { 47885385478SLisandro Dalcin switch (indx) { 4797f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 4807f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 48185385478SLisandro Dalcin } 48285385478SLisandro Dalcin } 48385385478SLisandro Dalcin 484acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 485186905e3SBarry Smith 48685385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 48785385478SLisandro Dalcin 488acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 489186905e3SBarry Smith 490fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 491fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 492fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 493fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 494fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 495fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 496fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 497186905e3SBarry Smith 49890d69ab7SBarry Smith flg = PETSC_FALSE; 499acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 500a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 501eabae89aSBarry Smith 502a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 503e8105e01SRichard Katz if (flg) { 504649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 505649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 506e8105e01SRichard Katz } 507eabae89aSBarry Smith 508b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 509b271bb04SBarry Smith if (flg) { 510b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 511b271bb04SBarry Smith } 512b271bb04SBarry Smith 513a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 514eabae89aSBarry Smith if (flg) { 515649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 516f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 517e8105e01SRichard Katz } 518eabae89aSBarry Smith 519a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 520eabae89aSBarry Smith if (flg) { 521649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 522649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 523eabae89aSBarry Smith } 524eabae89aSBarry Smith 5255180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 5265180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 5275180491cSLisandro Dalcin 52890d69ab7SBarry Smith flg = PETSC_FALSE; 529acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 530a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 53190d69ab7SBarry Smith flg = PETSC_FALSE; 532acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 533a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 53490d69ab7SBarry Smith flg = PETSC_FALSE; 535acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 536a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 53790d69ab7SBarry Smith flg = PETSC_FALSE; 538acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 539a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 54090d69ab7SBarry Smith flg = PETSC_FALSE; 541acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 542b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 543e24b481bSBarry Smith 54490d69ab7SBarry Smith flg = PETSC_FALSE; 545acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 5464b27c08aSLois Curfman McInnes if (flg) { 547*6cab3a1bSJed Brown void *functx; 548*6cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 549*6cab3a1bSJed Brown ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr); 550ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 5519b94acceSBarry Smith } 552639f9d9dSBarry Smith 553aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 554aa3661deSLisandro Dalcin flg = PETSC_FALSE; 555acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 556a8248277SBarry Smith if (flg && mf_operator) { 557a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 558a8248277SBarry Smith mf = PETSC_TRUE; 559a8248277SBarry Smith } 560aa3661deSLisandro Dalcin flg = PETSC_FALSE; 561acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 562aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 563aa3661deSLisandro Dalcin mf_version = 1; 564aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 565aa3661deSLisandro Dalcin 566d28543b3SPeter Brune 56789b92e6fSPeter Brune /* GS Options */ 56889b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 56989b92e6fSPeter Brune 570ea630c6eSPeter Brune /* line search options */ 571ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_alpha","Constant function norm must decrease by","None",snes->ls_alpha,&snes->ls_alpha,0);CHKERRQ(ierr); 572ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_maxstep","Step must be less than","None",snes->maxstep,&snes->maxstep,0);CHKERRQ(ierr); 573ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_steptol","Minimum lambda allowed","None",snes->steptol,&snes->steptol,0);CHKERRQ(ierr); 574ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_damping","Damping parameter","SNES",snes->damping,&snes->damping,&flg);CHKERRQ(ierr); 575af60355fSPeter Brune ierr = PetscOptionsInt("-snes_ls_it" ,"Line search iterations","SNES",snes->ls_its,&snes->ls_its,&flg);CHKERRQ(ierr); 576ea630c6eSPeter Brune ierr = PetscOptionsBool("-snes_ls_monitor","Print progress of line searches","SNESLineSearchSetMonitor",snes->ls_monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr); 577ea630c6eSPeter Brune if (set) {ierr = SNESLineSearchSetMonitor(snes,flg);CHKERRQ(ierr);} 57815f5eeeaSPeter Brune ierr = PetscOptionsEnum("-snes_ls","Line search used","SNESLineSearchSet",SNESLineSearchTypes,(PetscEnum)snes->ls_type,(PetscEnum*)&indx,&flg);CHKERRQ(ierr); 57915f5eeeaSPeter Brune if (flg) { 580ea630c6eSPeter Brune ierr = SNESLineSearchSetType(snes,(SNESLineSearchType)indx);CHKERRQ(ierr); 58115f5eeeaSPeter Brune } 5828e3fc8c0SJed Brown flg = snes->ops->precheckstep == SNESLineSearchPreCheckPicard ? PETSC_TRUE : PETSC_FALSE; 5838e3fc8c0SJed Brown ierr = PetscOptionsBool("-snes_ls_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);CHKERRQ(ierr); 5848e3fc8c0SJed Brown if (set) { 5858e3fc8c0SJed Brown if (flg) { 5868e3fc8c0SJed Brown snes->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */ 5878e3fc8c0SJed Brown ierr = PetscOptionsReal("-snes_ls_precheck_picard_angle","Maximum angle at which to activate the correction","none",snes->precheck_picard_angle,&snes->precheck_picard_angle,PETSC_NULL);CHKERRQ(ierr); 5888e3fc8c0SJed Brown ierr = SNESLineSearchSetPreCheck(snes,SNESLineSearchPreCheckPicard,&snes->precheck_picard_angle);CHKERRQ(ierr); 5898e3fc8c0SJed Brown } else { 5908e3fc8c0SJed Brown ierr = SNESLineSearchSetPreCheck(snes,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 5918e3fc8c0SJed Brown } 5928e3fc8c0SJed Brown } 5938e3fc8c0SJed Brown 59476b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 59576b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 59676b2cf59SMatthew Knepley } 59776b2cf59SMatthew Knepley 598e7788613SBarry Smith if (snes->ops->setfromoptions) { 599e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 600639f9d9dSBarry Smith } 6015d973c19SBarry Smith 6025d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 6035d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 604b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 6054bbc92c1SBarry Smith 606aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 6071cee3971SBarry Smith 6081cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 609aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 610aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 61185385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 61293993e2dSLois Curfman McInnes 61351e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 61451e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 61551e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 61651e86f29SPeter Brune if (pcset && (!snes->pc)) { 61751e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 61851e86f29SPeter Brune } 6194a0c5b0cSMatthew G Knepley if (snes->pc) { 620fde0ff24SPeter Brune ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr); 621fde0ff24SPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr); 6224a0c5b0cSMatthew G Knepley ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 6234a0c5b0cSMatthew G Knepley ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 6244a0c5b0cSMatthew G Knepley } 6253a40ed3dSBarry Smith PetscFunctionReturn(0); 6269b94acceSBarry Smith } 6279b94acceSBarry Smith 628d25893d9SBarry Smith #undef __FUNCT__ 629d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 630d25893d9SBarry Smith /*@ 631d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 632d25893d9SBarry Smith the nonlinear solvers. 633d25893d9SBarry Smith 634d25893d9SBarry Smith Logically Collective on SNES 635d25893d9SBarry Smith 636d25893d9SBarry Smith Input Parameters: 637d25893d9SBarry Smith + snes - the SNES context 638d25893d9SBarry Smith . compute - function to compute the context 639d25893d9SBarry Smith - destroy - function to destroy the context 640d25893d9SBarry Smith 641d25893d9SBarry Smith Level: intermediate 642d25893d9SBarry Smith 643d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 644d25893d9SBarry Smith 645d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 646d25893d9SBarry Smith @*/ 647d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 648d25893d9SBarry Smith { 649d25893d9SBarry Smith PetscFunctionBegin; 650d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 651d25893d9SBarry Smith snes->ops->usercompute = compute; 652d25893d9SBarry Smith snes->ops->userdestroy = destroy; 653d25893d9SBarry Smith PetscFunctionReturn(0); 654d25893d9SBarry Smith } 655a847f771SSatish Balay 6564a2ae208SSatish Balay #undef __FUNCT__ 6574a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 658b07ff414SBarry Smith /*@ 6599b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 6609b94acceSBarry Smith the nonlinear solvers. 6619b94acceSBarry Smith 6623f9fe445SBarry Smith Logically Collective on SNES 663fee21e36SBarry Smith 664c7afd0dbSLois Curfman McInnes Input Parameters: 665c7afd0dbSLois Curfman McInnes + snes - the SNES context 666c7afd0dbSLois Curfman McInnes - usrP - optional user context 667c7afd0dbSLois Curfman McInnes 66836851e7fSLois Curfman McInnes Level: intermediate 66936851e7fSLois Curfman McInnes 6709b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 6719b94acceSBarry Smith 672d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext() 6739b94acceSBarry Smith @*/ 6747087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 6759b94acceSBarry Smith { 6761b2093e4SBarry Smith PetscErrorCode ierr; 677b07ff414SBarry Smith KSP ksp; 6781b2093e4SBarry Smith 6793a40ed3dSBarry Smith PetscFunctionBegin; 6800700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 681b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 682b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 6839b94acceSBarry Smith snes->user = usrP; 6843a40ed3dSBarry Smith PetscFunctionReturn(0); 6859b94acceSBarry Smith } 68674679c65SBarry Smith 6874a2ae208SSatish Balay #undef __FUNCT__ 6884a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 689b07ff414SBarry Smith /*@ 6909b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 6919b94acceSBarry Smith nonlinear solvers. 6929b94acceSBarry Smith 693c7afd0dbSLois Curfman McInnes Not Collective 694c7afd0dbSLois Curfman McInnes 6959b94acceSBarry Smith Input Parameter: 6969b94acceSBarry Smith . snes - SNES context 6979b94acceSBarry Smith 6989b94acceSBarry Smith Output Parameter: 6999b94acceSBarry Smith . usrP - user context 7009b94acceSBarry Smith 70136851e7fSLois Curfman McInnes Level: intermediate 70236851e7fSLois Curfman McInnes 7039b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 7049b94acceSBarry Smith 7059b94acceSBarry Smith .seealso: SNESSetApplicationContext() 7069b94acceSBarry Smith @*/ 707e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 7089b94acceSBarry Smith { 7093a40ed3dSBarry Smith PetscFunctionBegin; 7100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 711e71120c6SJed Brown *(void**)usrP = snes->user; 7123a40ed3dSBarry Smith PetscFunctionReturn(0); 7139b94acceSBarry Smith } 71474679c65SBarry Smith 7154a2ae208SSatish Balay #undef __FUNCT__ 7164a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 7179b94acceSBarry Smith /*@ 718c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 719c8228a4eSBarry Smith at this time. 7209b94acceSBarry Smith 721c7afd0dbSLois Curfman McInnes Not Collective 722c7afd0dbSLois Curfman McInnes 7239b94acceSBarry Smith Input Parameter: 7249b94acceSBarry Smith . snes - SNES context 7259b94acceSBarry Smith 7269b94acceSBarry Smith Output Parameter: 7279b94acceSBarry Smith . iter - iteration number 7289b94acceSBarry Smith 729c8228a4eSBarry Smith Notes: 730c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 731c8228a4eSBarry Smith 732c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 73308405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 73408405cd6SLois Curfman McInnes .vb 73508405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 73608405cd6SLois Curfman McInnes if (!(it % 2)) { 73708405cd6SLois Curfman McInnes [compute Jacobian here] 73808405cd6SLois Curfman McInnes } 73908405cd6SLois Curfman McInnes .ve 740c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 74108405cd6SLois Curfman McInnes recomputed every second SNES iteration. 742c8228a4eSBarry Smith 74336851e7fSLois Curfman McInnes Level: intermediate 74436851e7fSLois Curfman McInnes 7452b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 7462b668275SBarry Smith 747b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 7489b94acceSBarry Smith @*/ 7497087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 7509b94acceSBarry Smith { 7513a40ed3dSBarry Smith PetscFunctionBegin; 7520700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7534482741eSBarry Smith PetscValidIntPointer(iter,2); 7549b94acceSBarry Smith *iter = snes->iter; 7553a40ed3dSBarry Smith PetscFunctionReturn(0); 7569b94acceSBarry Smith } 75774679c65SBarry Smith 7584a2ae208SSatish Balay #undef __FUNCT__ 759360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 760360c497dSPeter Brune /*@ 761360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 762360c497dSPeter Brune 763360c497dSPeter Brune Not Collective 764360c497dSPeter Brune 765360c497dSPeter Brune Input Parameter: 766360c497dSPeter Brune . snes - SNES context 767360c497dSPeter Brune . iter - iteration number 768360c497dSPeter Brune 769360c497dSPeter Brune Level: developer 770360c497dSPeter Brune 771360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 772360c497dSPeter Brune 773360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 774360c497dSPeter Brune @*/ 775360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 776360c497dSPeter Brune { 777360c497dSPeter Brune PetscErrorCode ierr; 778360c497dSPeter Brune 779360c497dSPeter Brune PetscFunctionBegin; 780360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 781360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 782360c497dSPeter Brune snes->iter = iter; 783360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 784360c497dSPeter Brune PetscFunctionReturn(0); 785360c497dSPeter Brune } 786360c497dSPeter Brune 787360c497dSPeter Brune #undef __FUNCT__ 7884a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 7899b94acceSBarry Smith /*@ 7909b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 7919b94acceSBarry Smith with SNESSSetFunction(). 7929b94acceSBarry Smith 793c7afd0dbSLois Curfman McInnes Collective on SNES 794c7afd0dbSLois Curfman McInnes 7959b94acceSBarry Smith Input Parameter: 7969b94acceSBarry Smith . snes - SNES context 7979b94acceSBarry Smith 7989b94acceSBarry Smith Output Parameter: 7999b94acceSBarry Smith . fnorm - 2-norm of function 8009b94acceSBarry Smith 80136851e7fSLois Curfman McInnes Level: intermediate 80236851e7fSLois Curfman McInnes 8039b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 804a86d99e1SLois Curfman McInnes 805b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 8069b94acceSBarry Smith @*/ 8077087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 8089b94acceSBarry Smith { 8093a40ed3dSBarry Smith PetscFunctionBegin; 8100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8114482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 8129b94acceSBarry Smith *fnorm = snes->norm; 8133a40ed3dSBarry Smith PetscFunctionReturn(0); 8149b94acceSBarry Smith } 81574679c65SBarry Smith 816360c497dSPeter Brune 817360c497dSPeter Brune #undef __FUNCT__ 818360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 819360c497dSPeter Brune /*@ 820360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 821360c497dSPeter Brune 822360c497dSPeter Brune Collective on SNES 823360c497dSPeter Brune 824360c497dSPeter Brune Input Parameter: 825360c497dSPeter Brune . snes - SNES context 826360c497dSPeter Brune . fnorm - 2-norm of function 827360c497dSPeter Brune 828360c497dSPeter Brune Level: developer 829360c497dSPeter Brune 830360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 831360c497dSPeter Brune 832360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 833360c497dSPeter Brune @*/ 834360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 835360c497dSPeter Brune { 836360c497dSPeter Brune 837360c497dSPeter Brune PetscErrorCode ierr; 838360c497dSPeter Brune 839360c497dSPeter Brune PetscFunctionBegin; 840360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 841360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 842360c497dSPeter Brune snes->norm = fnorm; 843360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 844360c497dSPeter Brune PetscFunctionReturn(0); 845360c497dSPeter Brune } 846360c497dSPeter Brune 8474a2ae208SSatish Balay #undef __FUNCT__ 848b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 8499b94acceSBarry Smith /*@ 850b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 8519b94acceSBarry Smith attempted by the nonlinear solver. 8529b94acceSBarry Smith 853c7afd0dbSLois Curfman McInnes Not Collective 854c7afd0dbSLois Curfman McInnes 8559b94acceSBarry Smith Input Parameter: 8569b94acceSBarry Smith . snes - SNES context 8579b94acceSBarry Smith 8589b94acceSBarry Smith Output Parameter: 8599b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 8609b94acceSBarry Smith 861c96a6f78SLois Curfman McInnes Notes: 862c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 863c96a6f78SLois Curfman McInnes 86436851e7fSLois Curfman McInnes Level: intermediate 86536851e7fSLois Curfman McInnes 8669b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 86758ebbce7SBarry Smith 868e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 86958ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 8709b94acceSBarry Smith @*/ 8717087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 8729b94acceSBarry Smith { 8733a40ed3dSBarry Smith PetscFunctionBegin; 8740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8754482741eSBarry Smith PetscValidIntPointer(nfails,2); 87650ffb88aSMatthew Knepley *nfails = snes->numFailures; 87750ffb88aSMatthew Knepley PetscFunctionReturn(0); 87850ffb88aSMatthew Knepley } 87950ffb88aSMatthew Knepley 88050ffb88aSMatthew Knepley #undef __FUNCT__ 881b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 88250ffb88aSMatthew Knepley /*@ 883b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 88450ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 88550ffb88aSMatthew Knepley 88650ffb88aSMatthew Knepley Not Collective 88750ffb88aSMatthew Knepley 88850ffb88aSMatthew Knepley Input Parameters: 88950ffb88aSMatthew Knepley + snes - SNES context 89050ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 89150ffb88aSMatthew Knepley 89250ffb88aSMatthew Knepley Level: intermediate 89350ffb88aSMatthew Knepley 89450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 89558ebbce7SBarry Smith 896e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 89758ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 89850ffb88aSMatthew Knepley @*/ 8997087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 90050ffb88aSMatthew Knepley { 90150ffb88aSMatthew Knepley PetscFunctionBegin; 9020700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 90350ffb88aSMatthew Knepley snes->maxFailures = maxFails; 90450ffb88aSMatthew Knepley PetscFunctionReturn(0); 90550ffb88aSMatthew Knepley } 90650ffb88aSMatthew Knepley 90750ffb88aSMatthew Knepley #undef __FUNCT__ 908b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 90950ffb88aSMatthew Knepley /*@ 910b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 91150ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 91250ffb88aSMatthew Knepley 91350ffb88aSMatthew Knepley Not Collective 91450ffb88aSMatthew Knepley 91550ffb88aSMatthew Knepley Input Parameter: 91650ffb88aSMatthew Knepley . snes - SNES context 91750ffb88aSMatthew Knepley 91850ffb88aSMatthew Knepley Output Parameter: 91950ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 92050ffb88aSMatthew Knepley 92150ffb88aSMatthew Knepley Level: intermediate 92250ffb88aSMatthew Knepley 92350ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 92458ebbce7SBarry Smith 925e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 92658ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 92758ebbce7SBarry Smith 92850ffb88aSMatthew Knepley @*/ 9297087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 93050ffb88aSMatthew Knepley { 93150ffb88aSMatthew Knepley PetscFunctionBegin; 9320700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9334482741eSBarry Smith PetscValidIntPointer(maxFails,2); 93450ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 9353a40ed3dSBarry Smith PetscFunctionReturn(0); 9369b94acceSBarry Smith } 937a847f771SSatish Balay 9384a2ae208SSatish Balay #undef __FUNCT__ 9392541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 9402541af92SBarry Smith /*@ 9412541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 9422541af92SBarry Smith done by SNES. 9432541af92SBarry Smith 9442541af92SBarry Smith Not Collective 9452541af92SBarry Smith 9462541af92SBarry Smith Input Parameter: 9472541af92SBarry Smith . snes - SNES context 9482541af92SBarry Smith 9492541af92SBarry Smith Output Parameter: 9502541af92SBarry Smith . nfuncs - number of evaluations 9512541af92SBarry Smith 9522541af92SBarry Smith Level: intermediate 9532541af92SBarry Smith 9542541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 95558ebbce7SBarry Smith 956e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 9572541af92SBarry Smith @*/ 9587087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 9592541af92SBarry Smith { 9602541af92SBarry Smith PetscFunctionBegin; 9610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9622541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 9632541af92SBarry Smith *nfuncs = snes->nfuncs; 9642541af92SBarry Smith PetscFunctionReturn(0); 9652541af92SBarry Smith } 9662541af92SBarry Smith 9672541af92SBarry Smith #undef __FUNCT__ 9683d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 9693d4c4710SBarry Smith /*@ 9703d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 9713d4c4710SBarry Smith linear solvers. 9723d4c4710SBarry Smith 9733d4c4710SBarry Smith Not Collective 9743d4c4710SBarry Smith 9753d4c4710SBarry Smith Input Parameter: 9763d4c4710SBarry Smith . snes - SNES context 9773d4c4710SBarry Smith 9783d4c4710SBarry Smith Output Parameter: 9793d4c4710SBarry Smith . nfails - number of failed solves 9803d4c4710SBarry Smith 9813d4c4710SBarry Smith Notes: 9823d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 9833d4c4710SBarry Smith 9843d4c4710SBarry Smith Level: intermediate 9853d4c4710SBarry Smith 9863d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 98758ebbce7SBarry Smith 988e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 9893d4c4710SBarry Smith @*/ 9907087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 9913d4c4710SBarry Smith { 9923d4c4710SBarry Smith PetscFunctionBegin; 9930700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9943d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 9953d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 9963d4c4710SBarry Smith PetscFunctionReturn(0); 9973d4c4710SBarry Smith } 9983d4c4710SBarry Smith 9993d4c4710SBarry Smith #undef __FUNCT__ 10003d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 10013d4c4710SBarry Smith /*@ 10023d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 10033d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 10043d4c4710SBarry Smith 10053f9fe445SBarry Smith Logically Collective on SNES 10063d4c4710SBarry Smith 10073d4c4710SBarry Smith Input Parameters: 10083d4c4710SBarry Smith + snes - SNES context 10093d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 10103d4c4710SBarry Smith 10113d4c4710SBarry Smith Level: intermediate 10123d4c4710SBarry Smith 1013a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 10143d4c4710SBarry Smith 10153d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 10163d4c4710SBarry Smith 101758ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 10183d4c4710SBarry Smith @*/ 10197087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 10203d4c4710SBarry Smith { 10213d4c4710SBarry Smith PetscFunctionBegin; 10220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1023c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 10243d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 10253d4c4710SBarry Smith PetscFunctionReturn(0); 10263d4c4710SBarry Smith } 10273d4c4710SBarry Smith 10283d4c4710SBarry Smith #undef __FUNCT__ 10293d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 10303d4c4710SBarry Smith /*@ 10313d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 10323d4c4710SBarry Smith are allowed before SNES terminates 10333d4c4710SBarry Smith 10343d4c4710SBarry Smith Not Collective 10353d4c4710SBarry Smith 10363d4c4710SBarry Smith Input Parameter: 10373d4c4710SBarry Smith . snes - SNES context 10383d4c4710SBarry Smith 10393d4c4710SBarry Smith Output Parameter: 10403d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 10413d4c4710SBarry Smith 10423d4c4710SBarry Smith Level: intermediate 10433d4c4710SBarry Smith 10443d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 10453d4c4710SBarry Smith 10463d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 10473d4c4710SBarry Smith 1048e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 10493d4c4710SBarry Smith @*/ 10507087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 10513d4c4710SBarry Smith { 10523d4c4710SBarry Smith PetscFunctionBegin; 10530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10543d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 10553d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 10563d4c4710SBarry Smith PetscFunctionReturn(0); 10573d4c4710SBarry Smith } 10583d4c4710SBarry Smith 10593d4c4710SBarry Smith #undef __FUNCT__ 1060b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1061c96a6f78SLois Curfman McInnes /*@ 1062b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1063c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1064c96a6f78SLois Curfman McInnes 1065c7afd0dbSLois Curfman McInnes Not Collective 1066c7afd0dbSLois Curfman McInnes 1067c96a6f78SLois Curfman McInnes Input Parameter: 1068c96a6f78SLois Curfman McInnes . snes - SNES context 1069c96a6f78SLois Curfman McInnes 1070c96a6f78SLois Curfman McInnes Output Parameter: 1071c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1072c96a6f78SLois Curfman McInnes 1073c96a6f78SLois Curfman McInnes Notes: 1074c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1075c96a6f78SLois Curfman McInnes 107636851e7fSLois Curfman McInnes Level: intermediate 107736851e7fSLois Curfman McInnes 1078c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 10792b668275SBarry Smith 10808c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1081c96a6f78SLois Curfman McInnes @*/ 10827087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1083c96a6f78SLois Curfman McInnes { 10843a40ed3dSBarry Smith PetscFunctionBegin; 10850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10864482741eSBarry Smith PetscValidIntPointer(lits,2); 1087c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 10883a40ed3dSBarry Smith PetscFunctionReturn(0); 1089c96a6f78SLois Curfman McInnes } 1090c96a6f78SLois Curfman McInnes 10914a2ae208SSatish Balay #undef __FUNCT__ 109294b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 109352baeb72SSatish Balay /*@ 109494b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 10959b94acceSBarry Smith 109694b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1097c7afd0dbSLois Curfman McInnes 10989b94acceSBarry Smith Input Parameter: 10999b94acceSBarry Smith . snes - the SNES context 11009b94acceSBarry Smith 11019b94acceSBarry Smith Output Parameter: 110294b7f48cSBarry Smith . ksp - the KSP context 11039b94acceSBarry Smith 11049b94acceSBarry Smith Notes: 110594b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 11069b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 11072999313aSBarry Smith PC contexts as well. 11089b94acceSBarry Smith 110936851e7fSLois Curfman McInnes Level: beginner 111036851e7fSLois Curfman McInnes 111194b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11129b94acceSBarry Smith 11132999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11149b94acceSBarry Smith @*/ 11157087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 11169b94acceSBarry Smith { 11171cee3971SBarry Smith PetscErrorCode ierr; 11181cee3971SBarry Smith 11193a40ed3dSBarry Smith PetscFunctionBegin; 11200700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11214482741eSBarry Smith PetscValidPointer(ksp,2); 11221cee3971SBarry Smith 11231cee3971SBarry Smith if (!snes->ksp) { 11241cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 11251cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 11261cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 11271cee3971SBarry Smith } 112894b7f48cSBarry Smith *ksp = snes->ksp; 11293a40ed3dSBarry Smith PetscFunctionReturn(0); 11309b94acceSBarry Smith } 113182bf6240SBarry Smith 11324a2ae208SSatish Balay #undef __FUNCT__ 11332999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 11342999313aSBarry Smith /*@ 11352999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 11362999313aSBarry Smith 11372999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 11382999313aSBarry Smith 11392999313aSBarry Smith Input Parameters: 11402999313aSBarry Smith + snes - the SNES context 11412999313aSBarry Smith - ksp - the KSP context 11422999313aSBarry Smith 11432999313aSBarry Smith Notes: 11442999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 11452999313aSBarry Smith so this routine is rarely needed. 11462999313aSBarry Smith 11472999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 11482999313aSBarry Smith decreased by one. 11492999313aSBarry Smith 11502999313aSBarry Smith Level: developer 11512999313aSBarry Smith 11522999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11532999313aSBarry Smith 11542999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11552999313aSBarry Smith @*/ 11567087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 11572999313aSBarry Smith { 11582999313aSBarry Smith PetscErrorCode ierr; 11592999313aSBarry Smith 11602999313aSBarry Smith PetscFunctionBegin; 11610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11620700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 11632999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 11647dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1165906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 11662999313aSBarry Smith snes->ksp = ksp; 11672999313aSBarry Smith PetscFunctionReturn(0); 11682999313aSBarry Smith } 11692999313aSBarry Smith 11707adad957SLisandro Dalcin #if 0 11712999313aSBarry Smith #undef __FUNCT__ 11724a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 11736849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1174e24b481bSBarry Smith { 1175e24b481bSBarry Smith PetscFunctionBegin; 1176e24b481bSBarry Smith PetscFunctionReturn(0); 1177e24b481bSBarry Smith } 11787adad957SLisandro Dalcin #endif 1179e24b481bSBarry Smith 11809b94acceSBarry Smith /* -----------------------------------------------------------*/ 11814a2ae208SSatish Balay #undef __FUNCT__ 11824a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 118352baeb72SSatish Balay /*@ 11849b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 11859b94acceSBarry Smith 1186c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1187c7afd0dbSLois Curfman McInnes 1188c7afd0dbSLois Curfman McInnes Input Parameters: 1189906ed7ccSBarry Smith . comm - MPI communicator 11909b94acceSBarry Smith 11919b94acceSBarry Smith Output Parameter: 11929b94acceSBarry Smith . outsnes - the new SNES context 11939b94acceSBarry Smith 1194c7afd0dbSLois Curfman McInnes Options Database Keys: 1195c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1196c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1197c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1198c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1199c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1200c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1201c1f60f51SBarry Smith 120236851e7fSLois Curfman McInnes Level: beginner 120336851e7fSLois Curfman McInnes 12049b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 12059b94acceSBarry Smith 1206a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1207a8054027SBarry Smith 12089b94acceSBarry Smith @*/ 12097087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 12109b94acceSBarry Smith { 1211dfbe8321SBarry Smith PetscErrorCode ierr; 12129b94acceSBarry Smith SNES snes; 1213fa9f3622SBarry Smith SNESKSPEW *kctx; 121437fcc0dbSBarry Smith 12153a40ed3dSBarry Smith PetscFunctionBegin; 1216ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 12178ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 12188ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 12198ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 12208ba1e511SMatthew Knepley #endif 12218ba1e511SMatthew Knepley 12223194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 12237adad957SLisandro Dalcin 122485385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 12252c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 12269b94acceSBarry Smith snes->max_its = 50; 12279750a799SBarry Smith snes->max_funcs = 10000; 12289b94acceSBarry Smith snes->norm = 0.0; 1229b4874afaSBarry Smith snes->rtol = 1.e-8; 1230b4874afaSBarry Smith snes->ttol = 0.0; 123170441072SBarry Smith snes->abstol = 1.e-50; 12329b94acceSBarry Smith snes->xtol = 1.e-8; 12334b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 12349b94acceSBarry Smith snes->nfuncs = 0; 123550ffb88aSMatthew Knepley snes->numFailures = 0; 123650ffb88aSMatthew Knepley snes->maxFailures = 1; 12377a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1238e35cf81dSBarry Smith snes->lagjacobian = 1; 1239a8054027SBarry Smith snes->lagpreconditioner = 1; 1240639f9d9dSBarry Smith snes->numbermonitors = 0; 12419b94acceSBarry Smith snes->data = 0; 12424dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1243186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 12446f24a144SLois Curfman McInnes snes->nwork = 0; 124558c9b817SLisandro Dalcin snes->work = 0; 124658c9b817SLisandro Dalcin snes->nvwork = 0; 124758c9b817SLisandro Dalcin snes->vwork = 0; 1248758f92a0SBarry Smith snes->conv_hist_len = 0; 1249758f92a0SBarry Smith snes->conv_hist_max = 0; 1250758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1251758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1252758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1253184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 125489b92e6fSPeter Brune snes->gssweeps = 1; 12559b94acceSBarry Smith 1256ea630c6eSPeter Brune /* initialize the line search options */ 1257ea630c6eSPeter Brune snes->ls_type = SNES_LS_BASIC; 1258af60355fSPeter Brune snes->ls_its = 1; 1259ea630c6eSPeter Brune snes->damping = 1.0; 1260ea630c6eSPeter Brune snes->maxstep = 1e8; 1261ea630c6eSPeter Brune snes->steptol = 1e-12; 1262ea630c6eSPeter Brune snes->ls_alpha = 1e-4; 1263ea630c6eSPeter Brune snes->ls_monitor = PETSC_NULL; 1264ea630c6eSPeter Brune 1265ea630c6eSPeter Brune snes->ops->linesearch = PETSC_NULL; 1266ea630c6eSPeter Brune snes->precheck = PETSC_NULL; 1267ea630c6eSPeter Brune snes->ops->precheckstep = PETSC_NULL; 1268ea630c6eSPeter Brune snes->postcheck = PETSC_NULL; 1269ea630c6eSPeter Brune snes->ops->postcheckstep= PETSC_NULL; 1270ea630c6eSPeter Brune 12713d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 12723d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 12733d4c4710SBarry Smith 12749b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 127538f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 12769b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 12779b94acceSBarry Smith kctx->version = 2; 12789b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 12799b94acceSBarry Smith this was too large for some test cases */ 128075567043SBarry Smith kctx->rtol_last = 0.0; 12819b94acceSBarry Smith kctx->rtol_max = .9; 12829b94acceSBarry Smith kctx->gamma = 1.0; 128362d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 128471f87433Sdalcinl kctx->alpha2 = kctx->alpha; 12859b94acceSBarry Smith kctx->threshold = .1; 128675567043SBarry Smith kctx->lresid_last = 0.0; 128775567043SBarry Smith kctx->norm_last = 0.0; 12889b94acceSBarry Smith 12899b94acceSBarry Smith *outsnes = snes; 12903a40ed3dSBarry Smith PetscFunctionReturn(0); 12919b94acceSBarry Smith } 12929b94acceSBarry Smith 12934a2ae208SSatish Balay #undef __FUNCT__ 12944a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 12959b94acceSBarry Smith /*@C 12969b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 12979b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 12989b94acceSBarry Smith equations. 12999b94acceSBarry Smith 13003f9fe445SBarry Smith Logically Collective on SNES 1301fee21e36SBarry Smith 1302c7afd0dbSLois Curfman McInnes Input Parameters: 1303c7afd0dbSLois Curfman McInnes + snes - the SNES context 1304c7afd0dbSLois Curfman McInnes . r - vector to store function value 1305de044059SHong Zhang . func - function evaluation routine 1306c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1307c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 13089b94acceSBarry Smith 1309c7afd0dbSLois Curfman McInnes Calling sequence of func: 13108d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1311c7afd0dbSLois Curfman McInnes 1312313e4042SLois Curfman McInnes . f - function vector 1313c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 13149b94acceSBarry Smith 13159b94acceSBarry Smith Notes: 13169b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 13179b94acceSBarry Smith $ f'(x) x = -f(x), 1318c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 13199b94acceSBarry Smith 132036851e7fSLois Curfman McInnes Level: beginner 132136851e7fSLois Curfman McInnes 13229b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 13239b94acceSBarry Smith 13248b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 13259b94acceSBarry Smith @*/ 13267087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 13279b94acceSBarry Smith { 132885385478SLisandro Dalcin PetscErrorCode ierr; 1329*6cab3a1bSJed Brown DM dm; 1330*6cab3a1bSJed Brown 13313a40ed3dSBarry Smith PetscFunctionBegin; 13320700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1333d2a683ecSLisandro Dalcin if (r) { 1334d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1335d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 133685385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 13376bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 133885385478SLisandro Dalcin snes->vec_func = r; 1339d2a683ecSLisandro Dalcin } else if (!snes->vec_func && snes->dm) { 1340d2a683ecSLisandro Dalcin ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1341d2a683ecSLisandro Dalcin } 1342*6cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1343*6cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 13443a40ed3dSBarry Smith PetscFunctionReturn(0); 13459b94acceSBarry Smith } 13469b94acceSBarry Smith 1347646217ecSPeter Brune 1348646217ecSPeter Brune #undef __FUNCT__ 1349646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1350c79ef259SPeter Brune /*@C 1351c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1352c79ef259SPeter Brune use with composed nonlinear solvers. 1353c79ef259SPeter Brune 1354c79ef259SPeter Brune Input Parameters: 1355c79ef259SPeter Brune + snes - the SNES context 1356c79ef259SPeter Brune . gsfunc - function evaluation routine 1357c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1358c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1359c79ef259SPeter Brune 1360c79ef259SPeter Brune Calling sequence of func: 1361c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1362c79ef259SPeter Brune 1363c79ef259SPeter Brune + X - solution vector 1364c79ef259SPeter Brune . B - RHS vector 1365d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1366c79ef259SPeter Brune 1367c79ef259SPeter Brune Notes: 1368c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1369c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1370c79ef259SPeter Brune 1371d28543b3SPeter Brune Level: intermediate 1372c79ef259SPeter Brune 1373d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1374c79ef259SPeter Brune 1375c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1376c79ef259SPeter Brune @*/ 1377*6cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 1378*6cab3a1bSJed Brown { 1379*6cab3a1bSJed Brown PetscErrorCode ierr; 1380*6cab3a1bSJed Brown DM dm; 1381*6cab3a1bSJed Brown 1382646217ecSPeter Brune PetscFunctionBegin; 1383*6cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1384*6cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1385*6cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1386646217ecSPeter Brune PetscFunctionReturn(0); 1387646217ecSPeter Brune } 1388646217ecSPeter Brune 1389d25893d9SBarry Smith #undef __FUNCT__ 139089b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 139189b92e6fSPeter Brune /*@ 139289b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 139389b92e6fSPeter Brune 139489b92e6fSPeter Brune Input Parameters: 139589b92e6fSPeter Brune + snes - the SNES context 139689b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 139789b92e6fSPeter Brune 139889b92e6fSPeter Brune Level: intermediate 139989b92e6fSPeter Brune 140089b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 140189b92e6fSPeter Brune 140289b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 140389b92e6fSPeter Brune @*/ 140489b92e6fSPeter Brune 140589b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 140689b92e6fSPeter Brune PetscFunctionBegin; 140789b92e6fSPeter Brune snes->gssweeps = sweeps; 140889b92e6fSPeter Brune PetscFunctionReturn(0); 140989b92e6fSPeter Brune } 141089b92e6fSPeter Brune 141189b92e6fSPeter Brune 141289b92e6fSPeter Brune #undef __FUNCT__ 141389b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 141489b92e6fSPeter Brune /*@ 141589b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 141689b92e6fSPeter Brune 141789b92e6fSPeter Brune Input Parameters: 141889b92e6fSPeter Brune . snes - the SNES context 141989b92e6fSPeter Brune 142089b92e6fSPeter Brune Output Parameters: 142189b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 142289b92e6fSPeter Brune 142389b92e6fSPeter Brune Level: intermediate 142489b92e6fSPeter Brune 142589b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 142689b92e6fSPeter Brune 142789b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 142889b92e6fSPeter Brune @*/ 142989b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 143089b92e6fSPeter Brune PetscFunctionBegin; 143189b92e6fSPeter Brune *sweeps = snes->gssweeps; 143289b92e6fSPeter Brune PetscFunctionReturn(0); 143389b92e6fSPeter Brune } 143489b92e6fSPeter Brune 143589b92e6fSPeter Brune #undef __FUNCT__ 14368b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 14378b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 14388b0a5094SBarry Smith { 14398b0a5094SBarry Smith PetscErrorCode ierr; 1440*6cab3a1bSJed Brown void *functx,*jacctx; 1441*6cab3a1bSJed Brown 14428b0a5094SBarry Smith PetscFunctionBegin; 1443*6cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 1444*6cab3a1bSJed Brown ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr); 14458b0a5094SBarry Smith /* A(x)*x - b(x) */ 1446*6cab3a1bSJed Brown ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr); 1447*6cab3a1bSJed Brown ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr); 14488b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 14498b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 14508b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 14518b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 14528b0a5094SBarry Smith PetscFunctionReturn(0); 14538b0a5094SBarry Smith } 14548b0a5094SBarry Smith 14558b0a5094SBarry Smith #undef __FUNCT__ 14568b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 14578b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 14588b0a5094SBarry Smith { 14598b0a5094SBarry Smith PetscFunctionBegin; 14608b0a5094SBarry Smith *flag = snes->matstruct; 14618b0a5094SBarry Smith PetscFunctionReturn(0); 14628b0a5094SBarry Smith } 14638b0a5094SBarry Smith 14648b0a5094SBarry Smith #undef __FUNCT__ 14658b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 14668b0a5094SBarry Smith /*@C 14670d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 14688b0a5094SBarry Smith 14698b0a5094SBarry Smith Logically Collective on SNES 14708b0a5094SBarry Smith 14718b0a5094SBarry Smith Input Parameters: 14728b0a5094SBarry Smith + snes - the SNES context 14738b0a5094SBarry Smith . r - vector to store function value 14748b0a5094SBarry Smith . func - function evaluation routine 14758b0a5094SBarry 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) 14768b0a5094SBarry Smith . mat - matrix to store A 14778b0a5094SBarry Smith . mfunc - function to compute matrix value 14788b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 14798b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 14808b0a5094SBarry Smith 14818b0a5094SBarry Smith Calling sequence of func: 14828b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 14838b0a5094SBarry Smith 14848b0a5094SBarry Smith + f - function vector 14858b0a5094SBarry Smith - ctx - optional user-defined function context 14868b0a5094SBarry Smith 14878b0a5094SBarry Smith Calling sequence of mfunc: 14888b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 14898b0a5094SBarry Smith 14908b0a5094SBarry Smith + x - input vector 14918b0a5094SBarry 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(), 14928b0a5094SBarry Smith normally just pass mat in this location 14938b0a5094SBarry Smith . mat - form A(x) matrix 14948b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 14958b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 14968b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 14978b0a5094SBarry Smith 14988b0a5094SBarry Smith Notes: 14998b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 15008b0a5094SBarry Smith 15018b0a5094SBarry 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} 15028b0a5094SBarry 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. 15038b0a5094SBarry Smith 15048b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 15058b0a5094SBarry Smith 15060d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 15070d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 15088b0a5094SBarry Smith 15098b0a5094SBarry 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 15108b0a5094SBarry 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 15118b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 15128b0a5094SBarry Smith 15138b0a5094SBarry Smith Level: beginner 15148b0a5094SBarry Smith 15158b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 15168b0a5094SBarry Smith 15170d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 15188b0a5094SBarry Smith @*/ 15198b0a5094SBarry 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) 15208b0a5094SBarry Smith { 15218b0a5094SBarry Smith PetscErrorCode ierr; 15228b0a5094SBarry Smith PetscFunctionBegin; 15238b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15248b0a5094SBarry Smith snes->ops->computepfunction = func; 15258b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 15268b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 15278b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 15288b0a5094SBarry Smith PetscFunctionReturn(0); 15298b0a5094SBarry Smith } 15308b0a5094SBarry Smith 15318b0a5094SBarry Smith #undef __FUNCT__ 1532d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1533d25893d9SBarry Smith /*@C 1534d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1535d25893d9SBarry Smith 1536d25893d9SBarry Smith Logically Collective on SNES 1537d25893d9SBarry Smith 1538d25893d9SBarry Smith Input Parameters: 1539d25893d9SBarry Smith + snes - the SNES context 1540d25893d9SBarry Smith . func - function evaluation routine 1541d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1542d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1543d25893d9SBarry Smith 1544d25893d9SBarry Smith Calling sequence of func: 1545d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1546d25893d9SBarry Smith 1547d25893d9SBarry Smith . f - function vector 1548d25893d9SBarry Smith - ctx - optional user-defined function context 1549d25893d9SBarry Smith 1550d25893d9SBarry Smith Level: intermediate 1551d25893d9SBarry Smith 1552d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1553d25893d9SBarry Smith 1554d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1555d25893d9SBarry Smith @*/ 1556d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1557d25893d9SBarry Smith { 1558d25893d9SBarry Smith PetscFunctionBegin; 1559d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1560d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1561d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1562d25893d9SBarry Smith PetscFunctionReturn(0); 1563d25893d9SBarry Smith } 1564d25893d9SBarry Smith 15653ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 15663ab0aad5SBarry Smith #undef __FUNCT__ 15671096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 15681096aae1SMatthew Knepley /*@C 15691096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 15701096aae1SMatthew Knepley it assumes a zero right hand side. 15711096aae1SMatthew Knepley 15723f9fe445SBarry Smith Logically Collective on SNES 15731096aae1SMatthew Knepley 15741096aae1SMatthew Knepley Input Parameter: 15751096aae1SMatthew Knepley . snes - the SNES context 15761096aae1SMatthew Knepley 15771096aae1SMatthew Knepley Output Parameter: 1578bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 15791096aae1SMatthew Knepley 15801096aae1SMatthew Knepley Level: intermediate 15811096aae1SMatthew Knepley 15821096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 15831096aae1SMatthew Knepley 158485385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 15851096aae1SMatthew Knepley @*/ 15867087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 15871096aae1SMatthew Knepley { 15881096aae1SMatthew Knepley PetscFunctionBegin; 15890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15901096aae1SMatthew Knepley PetscValidPointer(rhs,2); 159185385478SLisandro Dalcin *rhs = snes->vec_rhs; 15921096aae1SMatthew Knepley PetscFunctionReturn(0); 15931096aae1SMatthew Knepley } 15941096aae1SMatthew Knepley 15951096aae1SMatthew Knepley #undef __FUNCT__ 15964a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 15979b94acceSBarry Smith /*@ 159836851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 15999b94acceSBarry Smith SNESSetFunction(). 16009b94acceSBarry Smith 1601c7afd0dbSLois Curfman McInnes Collective on SNES 1602c7afd0dbSLois Curfman McInnes 16039b94acceSBarry Smith Input Parameters: 1604c7afd0dbSLois Curfman McInnes + snes - the SNES context 1605c7afd0dbSLois Curfman McInnes - x - input vector 16069b94acceSBarry Smith 16079b94acceSBarry Smith Output Parameter: 16083638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 16099b94acceSBarry Smith 16101bffabb2SLois Curfman McInnes Notes: 161136851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 161236851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 161336851e7fSLois Curfman McInnes themselves. 161436851e7fSLois Curfman McInnes 161536851e7fSLois Curfman McInnes Level: developer 161636851e7fSLois Curfman McInnes 16179b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 16189b94acceSBarry Smith 1619a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 16209b94acceSBarry Smith @*/ 16217087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 16229b94acceSBarry Smith { 1623dfbe8321SBarry Smith PetscErrorCode ierr; 1624*6cab3a1bSJed Brown DM dm; 1625*6cab3a1bSJed Brown SNESDM sdm; 16269b94acceSBarry Smith 16273a40ed3dSBarry Smith PetscFunctionBegin; 16280700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16290700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 16300700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1631c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1632c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 16334ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1634184914b5SBarry Smith 1635*6cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1636*6cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1637d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 1638*6cab3a1bSJed Brown if (sdm->computefunction) { 1639d64ed03dSBarry Smith PetscStackPush("SNES user function"); 1640*6cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1641d64ed03dSBarry Smith PetscStackPop; 164273250ac0SBarry Smith } else if (snes->dm) { 1643644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1644c90fad12SPeter Brune } else if (snes->vec_rhs) { 1645c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1646644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 164785385478SLisandro Dalcin if (snes->vec_rhs) { 164885385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 16493ab0aad5SBarry Smith } 1650ae3c334cSLois Curfman McInnes snes->nfuncs++; 1651d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 16524ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 16533a40ed3dSBarry Smith PetscFunctionReturn(0); 16549b94acceSBarry Smith } 16559b94acceSBarry Smith 16564a2ae208SSatish Balay #undef __FUNCT__ 1657646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1658c79ef259SPeter Brune /*@ 1659c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1660c79ef259SPeter Brune SNESSetGS(). 1661c79ef259SPeter Brune 1662c79ef259SPeter Brune Collective on SNES 1663c79ef259SPeter Brune 1664c79ef259SPeter Brune Input Parameters: 1665c79ef259SPeter Brune + snes - the SNES context 1666c79ef259SPeter Brune . x - input vector 1667c79ef259SPeter Brune - b - rhs vector 1668c79ef259SPeter Brune 1669c79ef259SPeter Brune Output Parameter: 1670c79ef259SPeter Brune . x - new solution vector 1671c79ef259SPeter Brune 1672c79ef259SPeter Brune Notes: 1673c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1674c79ef259SPeter Brune implementations, so most users would not generally call this routine 1675c79ef259SPeter Brune themselves. 1676c79ef259SPeter Brune 1677c79ef259SPeter Brune Level: developer 1678c79ef259SPeter Brune 1679c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1680c79ef259SPeter Brune 1681c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1682c79ef259SPeter Brune @*/ 1683646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1684646217ecSPeter Brune { 1685646217ecSPeter Brune PetscErrorCode ierr; 168689b92e6fSPeter Brune PetscInt i; 1687*6cab3a1bSJed Brown DM dm; 1688*6cab3a1bSJed Brown SNESDM sdm; 1689646217ecSPeter Brune 1690646217ecSPeter Brune PetscFunctionBegin; 1691646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1692646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1693646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1694646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1695646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 16964ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1697701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 1698*6cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1699*6cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1700*6cab3a1bSJed Brown if (sdm->computegs) { 170189b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1702646217ecSPeter Brune PetscStackPush("SNES user GS"); 1703*6cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1704646217ecSPeter Brune PetscStackPop; 170589b92e6fSPeter Brune } 1706646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1707701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 17084ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1709646217ecSPeter Brune PetscFunctionReturn(0); 1710646217ecSPeter Brune } 1711646217ecSPeter Brune 1712646217ecSPeter Brune 1713646217ecSPeter Brune #undef __FUNCT__ 17144a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 171562fef451SLois Curfman McInnes /*@ 171662fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 171762fef451SLois Curfman McInnes set with SNESSetJacobian(). 171862fef451SLois Curfman McInnes 1719c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1720c7afd0dbSLois Curfman McInnes 172162fef451SLois Curfman McInnes Input Parameters: 1722c7afd0dbSLois Curfman McInnes + snes - the SNES context 1723c7afd0dbSLois Curfman McInnes - x - input vector 172462fef451SLois Curfman McInnes 172562fef451SLois Curfman McInnes Output Parameters: 1726c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 172762fef451SLois Curfman McInnes . B - optional preconditioning matrix 17282b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1729fee21e36SBarry Smith 1730e35cf81dSBarry Smith Options Database Keys: 1731e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1732693365a8SJed Brown . -snes_lag_jacobian <lag> 1733693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1734693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1735693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 17364c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1737c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1738c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1739c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1740c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1741c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 17424c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1743c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1744c01495d3SJed Brown 1745e35cf81dSBarry Smith 174662fef451SLois Curfman McInnes Notes: 174762fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 174862fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 174962fef451SLois Curfman McInnes 175094b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1751dc5a77f8SLois Curfman McInnes flag parameter. 175262fef451SLois Curfman McInnes 175336851e7fSLois Curfman McInnes Level: developer 175436851e7fSLois Curfman McInnes 175562fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 175662fef451SLois Curfman McInnes 1757e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 175862fef451SLois Curfman McInnes @*/ 17597087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 17609b94acceSBarry Smith { 1761dfbe8321SBarry Smith PetscErrorCode ierr; 1762ace3abfcSBarry Smith PetscBool flag; 1763*6cab3a1bSJed Brown DM dm; 1764*6cab3a1bSJed Brown SNESDM sdm; 17653a40ed3dSBarry Smith 17663a40ed3dSBarry Smith PetscFunctionBegin; 17670700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17680700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 17694482741eSBarry Smith PetscValidPointer(flg,5); 1770c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 17714ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 1772*6cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1773*6cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1774*6cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 1775ebd3b9afSBarry Smith 1776ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1777ebd3b9afSBarry Smith 1778fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1779fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1780fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1781fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1782e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1783e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1784ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1785ebd3b9afSBarry Smith if (flag) { 1786ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1787ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1788ebd3b9afSBarry Smith } 1789e35cf81dSBarry Smith PetscFunctionReturn(0); 1790e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1791e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1792e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1793ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1794ebd3b9afSBarry Smith if (flag) { 1795ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1796ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1797ebd3b9afSBarry Smith } 1798e35cf81dSBarry Smith PetscFunctionReturn(0); 1799e35cf81dSBarry Smith } 1800e35cf81dSBarry Smith 1801c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1802e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1803d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 1804*6cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 1805d64ed03dSBarry Smith PetscStackPop; 1806d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1807a8054027SBarry Smith 18083b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 18093b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 18103b4f5425SBarry Smith snes->lagpreconditioner = -1; 18113b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1812a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1813a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1814a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1815a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1816a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1817a8054027SBarry Smith } 1818a8054027SBarry Smith 18196d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 18200700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 18210700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1822693365a8SJed Brown { 1823693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 1824693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 1825693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 1826693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 1827693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 1828693365a8SJed Brown if (flag || flag_draw || flag_contour) { 1829693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 1830693365a8SJed Brown MatStructure mstruct; 1831693365a8SJed Brown PetscViewer vdraw,vstdout; 18326b3a5b13SJed Brown PetscBool flg; 1833693365a8SJed Brown if (flag_operator) { 1834693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 1835693365a8SJed Brown Bexp = Bexp_mine; 1836693365a8SJed Brown } else { 1837693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 1838693365a8SJed Brown ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 1839693365a8SJed Brown if (flg) Bexp = *B; 1840693365a8SJed Brown else { 1841693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 1842693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 1843693365a8SJed Brown Bexp = Bexp_mine; 1844693365a8SJed Brown } 1845693365a8SJed Brown } 1846693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 1847693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 1848693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 1849693365a8SJed Brown if (flag_draw || flag_contour) { 1850693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 1851693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 1852693365a8SJed Brown } else vdraw = PETSC_NULL; 1853693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 1854693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 1855693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 1856693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 1857693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1858693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 1859693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1860693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 1861693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1862693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 1863693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 1864693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 1865693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 1866693365a8SJed Brown } 1867693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 1868693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 1869693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 1870693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 1871693365a8SJed Brown } 1872693365a8SJed Brown } 18734c30e9fbSJed Brown { 18746719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 18756719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 18764c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 18776719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 18784c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 18794c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 18806719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 18816719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 18826719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 18836719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 18844c30e9fbSJed Brown Mat Bfd; 18854c30e9fbSJed Brown MatStructure mstruct; 18864c30e9fbSJed Brown PetscViewer vdraw,vstdout; 18874c30e9fbSJed Brown ISColoring iscoloring; 18884c30e9fbSJed Brown MatFDColoring matfdcoloring; 18894c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 18904c30e9fbSJed Brown void *funcctx; 18916719d8e4SJed Brown PetscReal norm1,norm2,normmax; 18924c30e9fbSJed Brown 18934c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 18944c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 18954c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 18964c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 18974c30e9fbSJed Brown 18984c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 18994c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 19004c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 19014c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 19024c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 19034c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 19044c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 19054c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 19064c30e9fbSJed Brown 19074c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 19084c30e9fbSJed Brown if (flag_draw || flag_contour) { 19094c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 19104c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 19114c30e9fbSJed Brown } else vdraw = PETSC_NULL; 19124c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 19136719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 19144c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 19154c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 19166719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 19174c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 19184c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 19194c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 19206719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 19214c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 19226719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 19236719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 19244c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 19254c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 19264c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 19274c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 19284c30e9fbSJed Brown } 19294c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 19306719d8e4SJed Brown 19316719d8e4SJed Brown if (flag_threshold) { 19326719d8e4SJed Brown PetscInt bs,rstart,rend,i; 19336719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 19346719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 19356719d8e4SJed Brown for (i=rstart; i<rend; i++) { 19366719d8e4SJed Brown const PetscScalar *ba,*ca; 19376719d8e4SJed Brown const PetscInt *bj,*cj; 19386719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 19396719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 19406719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 19416719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 19426719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 19436719d8e4SJed Brown for (j=0; j<bn; j++) { 19446719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 19456719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 19466719d8e4SJed Brown maxentrycol = bj[j]; 19476719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 19486719d8e4SJed Brown } 19496719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 19506719d8e4SJed Brown maxdiffcol = bj[j]; 19516719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 19526719d8e4SJed Brown } 19536719d8e4SJed Brown if (rdiff > maxrdiff) { 19546719d8e4SJed Brown maxrdiffcol = bj[j]; 19556719d8e4SJed Brown maxrdiff = rdiff; 19566719d8e4SJed Brown } 19576719d8e4SJed Brown } 19586719d8e4SJed Brown if (maxrdiff > 1) { 19596719d8e4SJed 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); 19606719d8e4SJed Brown for (j=0; j<bn; j++) { 19616719d8e4SJed Brown PetscReal rdiff; 19626719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 19636719d8e4SJed Brown if (rdiff > 1) { 19646719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 19656719d8e4SJed Brown } 19666719d8e4SJed Brown } 19676719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 19686719d8e4SJed Brown } 19696719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 19706719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 19716719d8e4SJed Brown } 19726719d8e4SJed Brown } 19734c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 19744c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 19754c30e9fbSJed Brown } 19764c30e9fbSJed Brown } 19773a40ed3dSBarry Smith PetscFunctionReturn(0); 19789b94acceSBarry Smith } 19799b94acceSBarry Smith 19804a2ae208SSatish Balay #undef __FUNCT__ 19814a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 19829b94acceSBarry Smith /*@C 19839b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 1984044dda88SLois Curfman McInnes location to store the matrix. 19859b94acceSBarry Smith 19863f9fe445SBarry Smith Logically Collective on SNES and Mat 1987c7afd0dbSLois Curfman McInnes 19889b94acceSBarry Smith Input Parameters: 1989c7afd0dbSLois Curfman McInnes + snes - the SNES context 19909b94acceSBarry Smith . A - Jacobian matrix 19919b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 1992efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 1993c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1994efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 19959b94acceSBarry Smith 19969b94acceSBarry Smith Calling sequence of func: 19978d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 19989b94acceSBarry Smith 1999c7afd0dbSLois Curfman McInnes + x - input vector 20009b94acceSBarry Smith . A - Jacobian matrix 20019b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2002ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 20032b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2004c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 20059b94acceSBarry Smith 20069b94acceSBarry Smith Notes: 200794b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 20082cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2009ac21db08SLois Curfman McInnes 2010ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 20119b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 20129b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 20139b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 20149b94acceSBarry Smith throughout the global iterations. 20159b94acceSBarry Smith 201616913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 201716913363SBarry Smith each matrix. 201816913363SBarry Smith 2019a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2020a8a26c1eSJed Brown must be a MatFDColoring. 2021a8a26c1eSJed Brown 2022c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2023c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2024c3cc8fd1SJed Brown 202536851e7fSLois Curfman McInnes Level: beginner 202636851e7fSLois Curfman McInnes 20279b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 20289b94acceSBarry Smith 20293ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 20309b94acceSBarry Smith @*/ 20317087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 20329b94acceSBarry Smith { 2033dfbe8321SBarry Smith PetscErrorCode ierr; 2034*6cab3a1bSJed Brown DM dm; 20353a7fca6bSBarry Smith 20363a40ed3dSBarry Smith PetscFunctionBegin; 20370700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20380700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 20390700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2040c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 204106975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 2042*6cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2043*6cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 20443a7fca6bSBarry Smith if (A) { 20457dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 20466bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 20479b94acceSBarry Smith snes->jacobian = A; 20483a7fca6bSBarry Smith } 20493a7fca6bSBarry Smith if (B) { 20507dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 20516bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 20529b94acceSBarry Smith snes->jacobian_pre = B; 20533a7fca6bSBarry Smith } 20543a40ed3dSBarry Smith PetscFunctionReturn(0); 20559b94acceSBarry Smith } 205662fef451SLois Curfman McInnes 20574a2ae208SSatish Balay #undef __FUNCT__ 20584a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2059c2aafc4cSSatish Balay /*@C 2060b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2061b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2062b4fd4287SBarry Smith 2063c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2064c7afd0dbSLois Curfman McInnes 2065b4fd4287SBarry Smith Input Parameter: 2066b4fd4287SBarry Smith . snes - the nonlinear solver context 2067b4fd4287SBarry Smith 2068b4fd4287SBarry Smith Output Parameters: 2069c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2070b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 207170e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 207270e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2073fee21e36SBarry Smith 207436851e7fSLois Curfman McInnes Level: advanced 207536851e7fSLois Curfman McInnes 2076b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2077b4fd4287SBarry Smith @*/ 20787087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2079b4fd4287SBarry Smith { 2080*6cab3a1bSJed Brown PetscErrorCode ierr; 2081*6cab3a1bSJed Brown DM dm; 2082*6cab3a1bSJed Brown SNESDM sdm; 2083*6cab3a1bSJed Brown 20843a40ed3dSBarry Smith PetscFunctionBegin; 20850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2086b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2087b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 2088*6cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2089*6cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 2090*6cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 2091*6cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 20923a40ed3dSBarry Smith PetscFunctionReturn(0); 2093b4fd4287SBarry Smith } 2094b4fd4287SBarry Smith 20959b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 20969b94acceSBarry Smith 20974a2ae208SSatish Balay #undef __FUNCT__ 20984a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 20999b94acceSBarry Smith /*@ 21009b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2101272ac6f2SLois Curfman McInnes of a nonlinear solver. 21029b94acceSBarry Smith 2103fee21e36SBarry Smith Collective on SNES 2104fee21e36SBarry Smith 2105c7afd0dbSLois Curfman McInnes Input Parameters: 210670e92668SMatthew Knepley . snes - the SNES context 2107c7afd0dbSLois Curfman McInnes 2108272ac6f2SLois Curfman McInnes Notes: 2109272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2110272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2111272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2112272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2113272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2114272ac6f2SLois Curfman McInnes 211536851e7fSLois Curfman McInnes Level: advanced 211636851e7fSLois Curfman McInnes 21179b94acceSBarry Smith .keywords: SNES, nonlinear, setup 21189b94acceSBarry Smith 21199b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 21209b94acceSBarry Smith @*/ 21217087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 21229b94acceSBarry Smith { 2123dfbe8321SBarry Smith PetscErrorCode ierr; 2124*6cab3a1bSJed Brown DM dm; 2125*6cab3a1bSJed Brown SNESDM sdm; 21263a40ed3dSBarry Smith 21273a40ed3dSBarry Smith PetscFunctionBegin; 21280700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21294dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 21309b94acceSBarry Smith 21317adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 213285385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 213385385478SLisandro Dalcin } 213485385478SLisandro Dalcin 2135a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 213617186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 213758c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 213858c9b817SLisandro Dalcin 213958c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 214058c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 214158c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 214258c9b817SLisandro Dalcin } 214358c9b817SLisandro Dalcin 2144*6cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2145*6cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 2146*6cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 2147*6cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 2148*6cab3a1bSJed Brown if (!snes->vec_func) { 2149*6cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2150214df951SJed Brown } 2151efd51863SBarry Smith 2152b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2153b710008aSBarry Smith 2154d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2155d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2156d25893d9SBarry Smith } 2157d25893d9SBarry Smith 2158410397dcSLisandro Dalcin if (snes->ops->setup) { 2159410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2160410397dcSLisandro Dalcin } 216158c9b817SLisandro Dalcin 21627aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 21633a40ed3dSBarry Smith PetscFunctionReturn(0); 21649b94acceSBarry Smith } 21659b94acceSBarry Smith 21664a2ae208SSatish Balay #undef __FUNCT__ 216737596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 216837596af1SLisandro Dalcin /*@ 216937596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 217037596af1SLisandro Dalcin 217137596af1SLisandro Dalcin Collective on SNES 217237596af1SLisandro Dalcin 217337596af1SLisandro Dalcin Input Parameter: 217437596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 217537596af1SLisandro Dalcin 2176d25893d9SBarry Smith Level: intermediate 2177d25893d9SBarry Smith 2178d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 217937596af1SLisandro Dalcin 218037596af1SLisandro Dalcin .keywords: SNES, destroy 218137596af1SLisandro Dalcin 218237596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 218337596af1SLisandro Dalcin @*/ 218437596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 218537596af1SLisandro Dalcin { 218637596af1SLisandro Dalcin PetscErrorCode ierr; 218737596af1SLisandro Dalcin 218837596af1SLisandro Dalcin PetscFunctionBegin; 218937596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2190d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2191d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2192d25893d9SBarry Smith snes->user = PETSC_NULL; 2193d25893d9SBarry Smith } 21948a23116dSBarry Smith if (snes->pc) { 21958a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 21968a23116dSBarry Smith } 21978a23116dSBarry Smith 219837596af1SLisandro Dalcin if (snes->ops->reset) { 219937596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 220037596af1SLisandro Dalcin } 220137596af1SLisandro Dalcin if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);} 22026bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 22036bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 22046bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 22056bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 22066bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 22076bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2208c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2209c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 221037596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 221137596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 221237596af1SLisandro Dalcin PetscFunctionReturn(0); 221337596af1SLisandro Dalcin } 221437596af1SLisandro Dalcin 221537596af1SLisandro Dalcin #undef __FUNCT__ 22164a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 221752baeb72SSatish Balay /*@ 22189b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 22199b94acceSBarry Smith with SNESCreate(). 22209b94acceSBarry Smith 2221c7afd0dbSLois Curfman McInnes Collective on SNES 2222c7afd0dbSLois Curfman McInnes 22239b94acceSBarry Smith Input Parameter: 22249b94acceSBarry Smith . snes - the SNES context 22259b94acceSBarry Smith 222636851e7fSLois Curfman McInnes Level: beginner 222736851e7fSLois Curfman McInnes 22289b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 22299b94acceSBarry Smith 223063a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 22319b94acceSBarry Smith @*/ 22326bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 22339b94acceSBarry Smith { 22346849ba73SBarry Smith PetscErrorCode ierr; 22353a40ed3dSBarry Smith 22363a40ed3dSBarry Smith PetscFunctionBegin; 22376bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 22386bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 22396bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2240d4bb536fSBarry Smith 22416bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 22428a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 22436b8b9a38SLisandro Dalcin 2244be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 22456bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 22466bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 22476d4c513bSLisandro Dalcin 22486bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 22496bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 22506b8b9a38SLisandro Dalcin 22516bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 22526bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 22536bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 22546b8b9a38SLisandro Dalcin } 22556bf464f9SBarry Smith if ((*snes)->conv_malloc) { 22566bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 22576bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 225858c9b817SLisandro Dalcin } 2259ea630c6eSPeter Brune ierr = PetscViewerDestroy(&(*snes)->ls_monitor);CHKERRQ(ierr); 22606bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2261a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 22623a40ed3dSBarry Smith PetscFunctionReturn(0); 22639b94acceSBarry Smith } 22649b94acceSBarry Smith 22659b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 22669b94acceSBarry Smith 22674a2ae208SSatish Balay #undef __FUNCT__ 2268a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2269a8054027SBarry Smith /*@ 2270a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2271a8054027SBarry Smith 22723f9fe445SBarry Smith Logically Collective on SNES 2273a8054027SBarry Smith 2274a8054027SBarry Smith Input Parameters: 2275a8054027SBarry Smith + snes - the SNES context 2276a8054027SBarry 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 22773b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2278a8054027SBarry Smith 2279a8054027SBarry Smith Options Database Keys: 2280a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2281a8054027SBarry Smith 2282a8054027SBarry Smith Notes: 2283a8054027SBarry Smith The default is 1 2284a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2285a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2286a8054027SBarry Smith 2287a8054027SBarry Smith Level: intermediate 2288a8054027SBarry Smith 2289a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2290a8054027SBarry Smith 2291e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2292a8054027SBarry Smith 2293a8054027SBarry Smith @*/ 22947087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2295a8054027SBarry Smith { 2296a8054027SBarry Smith PetscFunctionBegin; 22970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2298e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2299e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2300c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2301a8054027SBarry Smith snes->lagpreconditioner = lag; 2302a8054027SBarry Smith PetscFunctionReturn(0); 2303a8054027SBarry Smith } 2304a8054027SBarry Smith 2305a8054027SBarry Smith #undef __FUNCT__ 2306efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2307efd51863SBarry Smith /*@ 2308efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2309efd51863SBarry Smith 2310efd51863SBarry Smith Logically Collective on SNES 2311efd51863SBarry Smith 2312efd51863SBarry Smith Input Parameters: 2313efd51863SBarry Smith + snes - the SNES context 2314efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2315efd51863SBarry Smith 2316efd51863SBarry Smith Options Database Keys: 2317efd51863SBarry Smith . -snes_grid_sequence <steps> 2318efd51863SBarry Smith 2319efd51863SBarry Smith Level: intermediate 2320efd51863SBarry Smith 2321c0df2a02SJed Brown Notes: 2322c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2323c0df2a02SJed Brown 2324efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2325efd51863SBarry Smith 2326efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2327efd51863SBarry Smith 2328efd51863SBarry Smith @*/ 2329efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2330efd51863SBarry Smith { 2331efd51863SBarry Smith PetscFunctionBegin; 2332efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2333efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2334efd51863SBarry Smith snes->gridsequence = steps; 2335efd51863SBarry Smith PetscFunctionReturn(0); 2336efd51863SBarry Smith } 2337efd51863SBarry Smith 2338efd51863SBarry Smith #undef __FUNCT__ 2339a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2340a8054027SBarry Smith /*@ 2341a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2342a8054027SBarry Smith 23433f9fe445SBarry Smith Not Collective 2344a8054027SBarry Smith 2345a8054027SBarry Smith Input Parameter: 2346a8054027SBarry Smith . snes - the SNES context 2347a8054027SBarry Smith 2348a8054027SBarry Smith Output Parameter: 2349a8054027SBarry 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 23503b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2351a8054027SBarry Smith 2352a8054027SBarry Smith Options Database Keys: 2353a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2354a8054027SBarry Smith 2355a8054027SBarry Smith Notes: 2356a8054027SBarry Smith The default is 1 2357a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2358a8054027SBarry Smith 2359a8054027SBarry Smith Level: intermediate 2360a8054027SBarry Smith 2361a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2362a8054027SBarry Smith 2363a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2364a8054027SBarry Smith 2365a8054027SBarry Smith @*/ 23667087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2367a8054027SBarry Smith { 2368a8054027SBarry Smith PetscFunctionBegin; 23690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2370a8054027SBarry Smith *lag = snes->lagpreconditioner; 2371a8054027SBarry Smith PetscFunctionReturn(0); 2372a8054027SBarry Smith } 2373a8054027SBarry Smith 2374a8054027SBarry Smith #undef __FUNCT__ 2375e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2376e35cf81dSBarry Smith /*@ 2377e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2378e35cf81dSBarry Smith often the preconditioner is rebuilt. 2379e35cf81dSBarry Smith 23803f9fe445SBarry Smith Logically Collective on SNES 2381e35cf81dSBarry Smith 2382e35cf81dSBarry Smith Input Parameters: 2383e35cf81dSBarry Smith + snes - the SNES context 2384e35cf81dSBarry 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 2385fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2386e35cf81dSBarry Smith 2387e35cf81dSBarry Smith Options Database Keys: 2388e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2389e35cf81dSBarry Smith 2390e35cf81dSBarry Smith Notes: 2391e35cf81dSBarry Smith The default is 1 2392e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2393fe3ffe1eSBarry 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 2394fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2395e35cf81dSBarry Smith 2396e35cf81dSBarry Smith Level: intermediate 2397e35cf81dSBarry Smith 2398e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2399e35cf81dSBarry Smith 2400e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2401e35cf81dSBarry Smith 2402e35cf81dSBarry Smith @*/ 24037087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2404e35cf81dSBarry Smith { 2405e35cf81dSBarry Smith PetscFunctionBegin; 24060700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2407e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2408e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2409c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2410e35cf81dSBarry Smith snes->lagjacobian = lag; 2411e35cf81dSBarry Smith PetscFunctionReturn(0); 2412e35cf81dSBarry Smith } 2413e35cf81dSBarry Smith 2414e35cf81dSBarry Smith #undef __FUNCT__ 2415e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2416e35cf81dSBarry Smith /*@ 2417e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2418e35cf81dSBarry Smith 24193f9fe445SBarry Smith Not Collective 2420e35cf81dSBarry Smith 2421e35cf81dSBarry Smith Input Parameter: 2422e35cf81dSBarry Smith . snes - the SNES context 2423e35cf81dSBarry Smith 2424e35cf81dSBarry Smith Output Parameter: 2425e35cf81dSBarry 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 2426e35cf81dSBarry Smith the Jacobian is built etc. 2427e35cf81dSBarry Smith 2428e35cf81dSBarry Smith Options Database Keys: 2429e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2430e35cf81dSBarry Smith 2431e35cf81dSBarry Smith Notes: 2432e35cf81dSBarry Smith The default is 1 2433e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2434e35cf81dSBarry Smith 2435e35cf81dSBarry Smith Level: intermediate 2436e35cf81dSBarry Smith 2437e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2438e35cf81dSBarry Smith 2439e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2440e35cf81dSBarry Smith 2441e35cf81dSBarry Smith @*/ 24427087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2443e35cf81dSBarry Smith { 2444e35cf81dSBarry Smith PetscFunctionBegin; 24450700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2446e35cf81dSBarry Smith *lag = snes->lagjacobian; 2447e35cf81dSBarry Smith PetscFunctionReturn(0); 2448e35cf81dSBarry Smith } 2449e35cf81dSBarry Smith 2450e35cf81dSBarry Smith #undef __FUNCT__ 24514a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 24529b94acceSBarry Smith /*@ 2453d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 24549b94acceSBarry Smith 24553f9fe445SBarry Smith Logically Collective on SNES 2456c7afd0dbSLois Curfman McInnes 24579b94acceSBarry Smith Input Parameters: 2458c7afd0dbSLois Curfman McInnes + snes - the SNES context 245970441072SBarry Smith . abstol - absolute convergence tolerance 246033174efeSLois Curfman McInnes . rtol - relative convergence tolerance 246133174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 246233174efeSLois Curfman McInnes of the change in the solution between steps 246333174efeSLois Curfman McInnes . maxit - maximum number of iterations 2464c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2465fee21e36SBarry Smith 246633174efeSLois Curfman McInnes Options Database Keys: 246770441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2468c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2469c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2470c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2471c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 24729b94acceSBarry Smith 2473d7a720efSLois Curfman McInnes Notes: 24749b94acceSBarry Smith The default maximum number of iterations is 50. 24759b94acceSBarry Smith The default maximum number of function evaluations is 1000. 24769b94acceSBarry Smith 247736851e7fSLois Curfman McInnes Level: intermediate 247836851e7fSLois Curfman McInnes 247933174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 24809b94acceSBarry Smith 24812492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 24829b94acceSBarry Smith @*/ 24837087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 24849b94acceSBarry Smith { 24853a40ed3dSBarry Smith PetscFunctionBegin; 24860700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2487c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2488c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2489c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2490c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2491c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2492c5eb9154SBarry Smith 2493ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2494ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2495ab54825eSJed Brown snes->abstol = abstol; 2496ab54825eSJed Brown } 2497ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2498ab54825eSJed 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); 2499ab54825eSJed Brown snes->rtol = rtol; 2500ab54825eSJed Brown } 2501ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2502ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2503ab54825eSJed Brown snes->xtol = stol; 2504ab54825eSJed Brown } 2505ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2506ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2507ab54825eSJed Brown snes->max_its = maxit; 2508ab54825eSJed Brown } 2509ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2510ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2511ab54825eSJed Brown snes->max_funcs = maxf; 2512ab54825eSJed Brown } 25133a40ed3dSBarry Smith PetscFunctionReturn(0); 25149b94acceSBarry Smith } 25159b94acceSBarry Smith 25164a2ae208SSatish Balay #undef __FUNCT__ 25174a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 25189b94acceSBarry Smith /*@ 251933174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 252033174efeSLois Curfman McInnes 2521c7afd0dbSLois Curfman McInnes Not Collective 2522c7afd0dbSLois Curfman McInnes 252333174efeSLois Curfman McInnes Input Parameters: 2524c7afd0dbSLois Curfman McInnes + snes - the SNES context 252585385478SLisandro Dalcin . atol - absolute convergence tolerance 252633174efeSLois Curfman McInnes . rtol - relative convergence tolerance 252733174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 252833174efeSLois Curfman McInnes of the change in the solution between steps 252933174efeSLois Curfman McInnes . maxit - maximum number of iterations 2530c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2531fee21e36SBarry Smith 253233174efeSLois Curfman McInnes Notes: 253333174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 253433174efeSLois Curfman McInnes 253536851e7fSLois Curfman McInnes Level: intermediate 253636851e7fSLois Curfman McInnes 253733174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 253833174efeSLois Curfman McInnes 253933174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 254033174efeSLois Curfman McInnes @*/ 25417087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 254233174efeSLois Curfman McInnes { 25433a40ed3dSBarry Smith PetscFunctionBegin; 25440700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 254585385478SLisandro Dalcin if (atol) *atol = snes->abstol; 254633174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 254733174efeSLois Curfman McInnes if (stol) *stol = snes->xtol; 254833174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 254933174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 25503a40ed3dSBarry Smith PetscFunctionReturn(0); 255133174efeSLois Curfman McInnes } 255233174efeSLois Curfman McInnes 25534a2ae208SSatish Balay #undef __FUNCT__ 25544a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 255533174efeSLois Curfman McInnes /*@ 25569b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 25579b94acceSBarry Smith 25583f9fe445SBarry Smith Logically Collective on SNES 2559fee21e36SBarry Smith 2560c7afd0dbSLois Curfman McInnes Input Parameters: 2561c7afd0dbSLois Curfman McInnes + snes - the SNES context 2562c7afd0dbSLois Curfman McInnes - tol - tolerance 2563c7afd0dbSLois Curfman McInnes 25649b94acceSBarry Smith Options Database Key: 2565c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 25669b94acceSBarry Smith 256736851e7fSLois Curfman McInnes Level: intermediate 256836851e7fSLois Curfman McInnes 25699b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 25709b94acceSBarry Smith 25712492ecdbSBarry Smith .seealso: SNESSetTolerances() 25729b94acceSBarry Smith @*/ 25737087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 25749b94acceSBarry Smith { 25753a40ed3dSBarry Smith PetscFunctionBegin; 25760700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2577c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 25789b94acceSBarry Smith snes->deltatol = tol; 25793a40ed3dSBarry Smith PetscFunctionReturn(0); 25809b94acceSBarry Smith } 25819b94acceSBarry Smith 2582df9fa365SBarry Smith /* 2583df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2584df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2585df9fa365SBarry Smith macros instead of functions 2586df9fa365SBarry Smith */ 25874a2ae208SSatish Balay #undef __FUNCT__ 2588a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 25897087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2590ce1608b8SBarry Smith { 2591dfbe8321SBarry Smith PetscErrorCode ierr; 2592ce1608b8SBarry Smith 2593ce1608b8SBarry Smith PetscFunctionBegin; 25940700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2595a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2596ce1608b8SBarry Smith PetscFunctionReturn(0); 2597ce1608b8SBarry Smith } 2598ce1608b8SBarry Smith 25994a2ae208SSatish Balay #undef __FUNCT__ 2600a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 26017087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2602df9fa365SBarry Smith { 2603dfbe8321SBarry Smith PetscErrorCode ierr; 2604df9fa365SBarry Smith 2605df9fa365SBarry Smith PetscFunctionBegin; 2606a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2607df9fa365SBarry Smith PetscFunctionReturn(0); 2608df9fa365SBarry Smith } 2609df9fa365SBarry Smith 26104a2ae208SSatish Balay #undef __FUNCT__ 2611a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 26126bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2613df9fa365SBarry Smith { 2614dfbe8321SBarry Smith PetscErrorCode ierr; 2615df9fa365SBarry Smith 2616df9fa365SBarry Smith PetscFunctionBegin; 2617a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2618df9fa365SBarry Smith PetscFunctionReturn(0); 2619df9fa365SBarry Smith } 2620df9fa365SBarry Smith 26217087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2622b271bb04SBarry Smith #undef __FUNCT__ 2623b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 26247087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2625b271bb04SBarry Smith { 2626b271bb04SBarry Smith PetscDrawLG lg; 2627b271bb04SBarry Smith PetscErrorCode ierr; 2628b271bb04SBarry Smith PetscReal x,y,per; 2629b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2630b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2631b271bb04SBarry Smith PetscDraw draw; 2632b271bb04SBarry Smith PetscFunctionBegin; 2633b271bb04SBarry Smith if (!monctx) { 2634b271bb04SBarry Smith MPI_Comm comm; 2635b271bb04SBarry Smith 2636b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2637b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2638b271bb04SBarry Smith } 2639b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2640b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2641b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2642b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2643b271bb04SBarry Smith x = (PetscReal) n; 2644b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2645b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2646b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2647b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2648b271bb04SBarry Smith } 2649b271bb04SBarry Smith 2650b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2651b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2652b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2653b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2654b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2655b271bb04SBarry Smith x = (PetscReal) n; 2656b271bb04SBarry Smith y = 100.0*per; 2657b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2658b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2659b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2660b271bb04SBarry Smith } 2661b271bb04SBarry Smith 2662b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2663b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2664b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2665b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2666b271bb04SBarry Smith x = (PetscReal) n; 2667b271bb04SBarry Smith y = (prev - rnorm)/prev; 2668b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2669b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2670b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2671b271bb04SBarry Smith } 2672b271bb04SBarry Smith 2673b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2674b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2675b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2676b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2677b271bb04SBarry Smith x = (PetscReal) n; 2678b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2679b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2680b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2681b271bb04SBarry Smith } 2682b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2683b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2684b271bb04SBarry Smith } 2685b271bb04SBarry Smith prev = rnorm; 2686b271bb04SBarry Smith PetscFunctionReturn(0); 2687b271bb04SBarry Smith } 2688b271bb04SBarry Smith 2689b271bb04SBarry Smith #undef __FUNCT__ 2690b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 26917087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2692b271bb04SBarry Smith { 2693b271bb04SBarry Smith PetscErrorCode ierr; 2694b271bb04SBarry Smith 2695b271bb04SBarry Smith PetscFunctionBegin; 2696b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2697b271bb04SBarry Smith PetscFunctionReturn(0); 2698b271bb04SBarry Smith } 2699b271bb04SBarry Smith 2700b271bb04SBarry Smith #undef __FUNCT__ 2701b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 27026bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2703b271bb04SBarry Smith { 2704b271bb04SBarry Smith PetscErrorCode ierr; 2705b271bb04SBarry Smith 2706b271bb04SBarry Smith PetscFunctionBegin; 2707b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2708b271bb04SBarry Smith PetscFunctionReturn(0); 2709b271bb04SBarry Smith } 2710b271bb04SBarry Smith 27117a03ce2fSLisandro Dalcin #undef __FUNCT__ 27127a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2713228d79bcSJed Brown /*@ 2714228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2715228d79bcSJed Brown 2716228d79bcSJed Brown Collective on SNES 2717228d79bcSJed Brown 2718228d79bcSJed Brown Input Parameters: 2719228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2720228d79bcSJed Brown . iter - iteration number 2721228d79bcSJed Brown - rnorm - relative norm of the residual 2722228d79bcSJed Brown 2723228d79bcSJed Brown Notes: 2724228d79bcSJed Brown This routine is called by the SNES implementations. 2725228d79bcSJed Brown It does not typically need to be called by the user. 2726228d79bcSJed Brown 2727228d79bcSJed Brown Level: developer 2728228d79bcSJed Brown 2729228d79bcSJed Brown .seealso: SNESMonitorSet() 2730228d79bcSJed Brown @*/ 27317a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 27327a03ce2fSLisandro Dalcin { 27337a03ce2fSLisandro Dalcin PetscErrorCode ierr; 27347a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 27357a03ce2fSLisandro Dalcin 27367a03ce2fSLisandro Dalcin PetscFunctionBegin; 27377a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 27387a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 27397a03ce2fSLisandro Dalcin } 27407a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 27417a03ce2fSLisandro Dalcin } 27427a03ce2fSLisandro Dalcin 27439b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 27449b94acceSBarry Smith 27454a2ae208SSatish Balay #undef __FUNCT__ 2746a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 27479b94acceSBarry Smith /*@C 2748a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 27499b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 27509b94acceSBarry Smith progress. 27519b94acceSBarry Smith 27523f9fe445SBarry Smith Logically Collective on SNES 2753fee21e36SBarry Smith 2754c7afd0dbSLois Curfman McInnes Input Parameters: 2755c7afd0dbSLois Curfman McInnes + snes - the SNES context 2756c7afd0dbSLois Curfman McInnes . func - monitoring routine 2757b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2758e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2759b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2760b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 27619b94acceSBarry Smith 2762c7afd0dbSLois Curfman McInnes Calling sequence of func: 2763a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2764c7afd0dbSLois Curfman McInnes 2765c7afd0dbSLois Curfman McInnes + snes - the SNES context 2766c7afd0dbSLois Curfman McInnes . its - iteration number 2767c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 276840a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 27699b94acceSBarry Smith 27709665c990SLois Curfman McInnes Options Database Keys: 2771a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2772a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2773a6570f20SBarry Smith uses SNESMonitorLGCreate() 2774cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2775c7afd0dbSLois Curfman McInnes been hardwired into a code by 2776a6570f20SBarry Smith calls to SNESMonitorSet(), but 2777c7afd0dbSLois Curfman McInnes does not cancel those set via 2778c7afd0dbSLois Curfman McInnes the options database. 27799665c990SLois Curfman McInnes 2780639f9d9dSBarry Smith Notes: 27816bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 2782a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 27836bc08f3fSLois Curfman McInnes order in which they were set. 2784639f9d9dSBarry Smith 2785025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 2786025f1a04SBarry Smith 278736851e7fSLois Curfman McInnes Level: intermediate 278836851e7fSLois Curfman McInnes 27899b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 27909b94acceSBarry Smith 2791a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 27929b94acceSBarry Smith @*/ 2793c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 27949b94acceSBarry Smith { 2795b90d0a6eSBarry Smith PetscInt i; 2796649052a6SBarry Smith PetscErrorCode ierr; 2797b90d0a6eSBarry Smith 27983a40ed3dSBarry Smith PetscFunctionBegin; 27990700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 280017186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2801b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 2802649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2803649052a6SBarry Smith if (monitordestroy) { 2804c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2805649052a6SBarry Smith } 2806b90d0a6eSBarry Smith PetscFunctionReturn(0); 2807b90d0a6eSBarry Smith } 2808b90d0a6eSBarry Smith } 2809b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 2810b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2811639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 28123a40ed3dSBarry Smith PetscFunctionReturn(0); 28139b94acceSBarry Smith } 28149b94acceSBarry Smith 28154a2ae208SSatish Balay #undef __FUNCT__ 2816a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 28175cd90555SBarry Smith /*@C 2818a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 28195cd90555SBarry Smith 28203f9fe445SBarry Smith Logically Collective on SNES 2821c7afd0dbSLois Curfman McInnes 28225cd90555SBarry Smith Input Parameters: 28235cd90555SBarry Smith . snes - the SNES context 28245cd90555SBarry Smith 28251a480d89SAdministrator Options Database Key: 2826a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 2827a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 2828c7afd0dbSLois Curfman McInnes set via the options database 28295cd90555SBarry Smith 28305cd90555SBarry Smith Notes: 28315cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 28325cd90555SBarry Smith 283336851e7fSLois Curfman McInnes Level: intermediate 283436851e7fSLois Curfman McInnes 28355cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 28365cd90555SBarry Smith 2837a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 28385cd90555SBarry Smith @*/ 28397087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 28405cd90555SBarry Smith { 2841d952e501SBarry Smith PetscErrorCode ierr; 2842d952e501SBarry Smith PetscInt i; 2843d952e501SBarry Smith 28445cd90555SBarry Smith PetscFunctionBegin; 28450700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2846d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 2847d952e501SBarry Smith if (snes->monitordestroy[i]) { 28483c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 2849d952e501SBarry Smith } 2850d952e501SBarry Smith } 28515cd90555SBarry Smith snes->numbermonitors = 0; 28525cd90555SBarry Smith PetscFunctionReturn(0); 28535cd90555SBarry Smith } 28545cd90555SBarry Smith 28554a2ae208SSatish Balay #undef __FUNCT__ 28564a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 28579b94acceSBarry Smith /*@C 28589b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 28599b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 28609b94acceSBarry Smith 28613f9fe445SBarry Smith Logically Collective on SNES 2862fee21e36SBarry Smith 2863c7afd0dbSLois Curfman McInnes Input Parameters: 2864c7afd0dbSLois Curfman McInnes + snes - the SNES context 2865c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 28667f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 28677f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 28689b94acceSBarry Smith 2869c7afd0dbSLois Curfman McInnes Calling sequence of func: 287006ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2871c7afd0dbSLois Curfman McInnes 2872c7afd0dbSLois Curfman McInnes + snes - the SNES context 287306ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 2874c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 2875184914b5SBarry Smith . reason - reason for convergence/divergence 2876c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 28774b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 28784b27c08aSLois Curfman McInnes - f - 2-norm of function 28799b94acceSBarry Smith 288036851e7fSLois Curfman McInnes Level: advanced 288136851e7fSLois Curfman McInnes 28829b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 28839b94acceSBarry Smith 288485385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 28859b94acceSBarry Smith @*/ 28867087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 28879b94acceSBarry Smith { 28887f7931b9SBarry Smith PetscErrorCode ierr; 28897f7931b9SBarry Smith 28903a40ed3dSBarry Smith PetscFunctionBegin; 28910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 289285385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 28937f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 28947f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 28957f7931b9SBarry Smith } 289685385478SLisandro Dalcin snes->ops->converged = func; 28977f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 289885385478SLisandro Dalcin snes->cnvP = cctx; 28993a40ed3dSBarry Smith PetscFunctionReturn(0); 29009b94acceSBarry Smith } 29019b94acceSBarry Smith 29024a2ae208SSatish Balay #undef __FUNCT__ 29034a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 290452baeb72SSatish Balay /*@ 2905184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2906184914b5SBarry Smith 2907184914b5SBarry Smith Not Collective 2908184914b5SBarry Smith 2909184914b5SBarry Smith Input Parameter: 2910184914b5SBarry Smith . snes - the SNES context 2911184914b5SBarry Smith 2912184914b5SBarry Smith Output Parameter: 29134d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2914184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 2915184914b5SBarry Smith 2916184914b5SBarry Smith Level: intermediate 2917184914b5SBarry Smith 2918184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 2919184914b5SBarry Smith 2920184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 2921184914b5SBarry Smith 292285385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2923184914b5SBarry Smith @*/ 29247087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2925184914b5SBarry Smith { 2926184914b5SBarry Smith PetscFunctionBegin; 29270700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 29284482741eSBarry Smith PetscValidPointer(reason,2); 2929184914b5SBarry Smith *reason = snes->reason; 2930184914b5SBarry Smith PetscFunctionReturn(0); 2931184914b5SBarry Smith } 2932184914b5SBarry Smith 29334a2ae208SSatish Balay #undef __FUNCT__ 29344a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 2935c9005455SLois Curfman McInnes /*@ 2936c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2937c9005455SLois Curfman McInnes 29383f9fe445SBarry Smith Logically Collective on SNES 2939fee21e36SBarry Smith 2940c7afd0dbSLois Curfman McInnes Input Parameters: 2941c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 29428c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 2943cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 2944758f92a0SBarry Smith . na - size of a and its 294564731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2946758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 2947c7afd0dbSLois Curfman McInnes 2948308dcc3eSBarry Smith Notes: 2949308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2950308dcc3eSBarry Smith default array of length 10000 is allocated. 2951308dcc3eSBarry Smith 2952c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 2953c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 2954c9005455SLois Curfman McInnes during the section of code that is being timed. 2955c9005455SLois Curfman McInnes 295636851e7fSLois Curfman McInnes Level: intermediate 295736851e7fSLois Curfman McInnes 2958c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 2959758f92a0SBarry Smith 296008405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 2961758f92a0SBarry Smith 2962c9005455SLois Curfman McInnes @*/ 29637087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 2964c9005455SLois Curfman McInnes { 2965308dcc3eSBarry Smith PetscErrorCode ierr; 2966308dcc3eSBarry Smith 29673a40ed3dSBarry Smith PetscFunctionBegin; 29680700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 29694482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 2970a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 2971308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 2972308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 2973308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 2974308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 2975308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 2976308dcc3eSBarry Smith } 2977c9005455SLois Curfman McInnes snes->conv_hist = a; 2978758f92a0SBarry Smith snes->conv_hist_its = its; 2979758f92a0SBarry Smith snes->conv_hist_max = na; 2980a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 2981758f92a0SBarry Smith snes->conv_hist_reset = reset; 2982758f92a0SBarry Smith PetscFunctionReturn(0); 2983758f92a0SBarry Smith } 2984758f92a0SBarry Smith 2985308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 2986c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 2987c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 2988308dcc3eSBarry Smith EXTERN_C_BEGIN 2989308dcc3eSBarry Smith #undef __FUNCT__ 2990308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 2991308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 2992308dcc3eSBarry Smith { 2993308dcc3eSBarry Smith mxArray *mat; 2994308dcc3eSBarry Smith PetscInt i; 2995308dcc3eSBarry Smith PetscReal *ar; 2996308dcc3eSBarry Smith 2997308dcc3eSBarry Smith PetscFunctionBegin; 2998308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 2999308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3000308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3001308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3002308dcc3eSBarry Smith } 3003308dcc3eSBarry Smith PetscFunctionReturn(mat); 3004308dcc3eSBarry Smith } 3005308dcc3eSBarry Smith EXTERN_C_END 3006308dcc3eSBarry Smith #endif 3007308dcc3eSBarry Smith 3008308dcc3eSBarry Smith 30094a2ae208SSatish Balay #undef __FUNCT__ 30104a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 30110c4c9dddSBarry Smith /*@C 3012758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3013758f92a0SBarry Smith 30143f9fe445SBarry Smith Not Collective 3015758f92a0SBarry Smith 3016758f92a0SBarry Smith Input Parameter: 3017758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3018758f92a0SBarry Smith 3019758f92a0SBarry Smith Output Parameters: 3020758f92a0SBarry Smith . a - array to hold history 3021758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3022758f92a0SBarry Smith negative if not converged) for each solve. 3023758f92a0SBarry Smith - na - size of a and its 3024758f92a0SBarry Smith 3025758f92a0SBarry Smith Notes: 3026758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3027758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3028758f92a0SBarry Smith 3029758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3030758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3031758f92a0SBarry Smith during the section of code that is being timed. 3032758f92a0SBarry Smith 3033758f92a0SBarry Smith Level: intermediate 3034758f92a0SBarry Smith 3035758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3036758f92a0SBarry Smith 3037758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3038758f92a0SBarry Smith 3039758f92a0SBarry Smith @*/ 30407087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3041758f92a0SBarry Smith { 3042758f92a0SBarry Smith PetscFunctionBegin; 30430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3044758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3045758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3046758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 30473a40ed3dSBarry Smith PetscFunctionReturn(0); 3048c9005455SLois Curfman McInnes } 3049c9005455SLois Curfman McInnes 3050e74ef692SMatthew Knepley #undef __FUNCT__ 3051e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3052ac226902SBarry Smith /*@C 305376b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3054eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 30557e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 305676b2cf59SMatthew Knepley 30573f9fe445SBarry Smith Logically Collective on SNES 305876b2cf59SMatthew Knepley 305976b2cf59SMatthew Knepley Input Parameters: 306076b2cf59SMatthew Knepley . snes - The nonlinear solver context 306176b2cf59SMatthew Knepley . func - The function 306276b2cf59SMatthew Knepley 306376b2cf59SMatthew Knepley Calling sequence of func: 3064b5d30489SBarry Smith . func (SNES snes, PetscInt step); 306576b2cf59SMatthew Knepley 306676b2cf59SMatthew Knepley . step - The current step of the iteration 306776b2cf59SMatthew Knepley 3068fe97e370SBarry Smith Level: advanced 3069fe97e370SBarry Smith 3070fe97e370SBarry 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() 3071fe97e370SBarry Smith This is not used by most users. 307276b2cf59SMatthew Knepley 307376b2cf59SMatthew Knepley .keywords: SNES, update 3074b5d30489SBarry Smith 307585385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 307676b2cf59SMatthew Knepley @*/ 30777087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 307876b2cf59SMatthew Knepley { 307976b2cf59SMatthew Knepley PetscFunctionBegin; 30800700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3081e7788613SBarry Smith snes->ops->update = func; 308276b2cf59SMatthew Knepley PetscFunctionReturn(0); 308376b2cf59SMatthew Knepley } 308476b2cf59SMatthew Knepley 3085e74ef692SMatthew Knepley #undef __FUNCT__ 3086e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 308776b2cf59SMatthew Knepley /*@ 308876b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 308976b2cf59SMatthew Knepley 309076b2cf59SMatthew Knepley Not collective 309176b2cf59SMatthew Knepley 309276b2cf59SMatthew Knepley Input Parameters: 309376b2cf59SMatthew Knepley . snes - The nonlinear solver context 309476b2cf59SMatthew Knepley . step - The current step of the iteration 309576b2cf59SMatthew Knepley 3096205452f4SMatthew Knepley Level: intermediate 3097205452f4SMatthew Knepley 309876b2cf59SMatthew Knepley .keywords: SNES, update 3099a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 310076b2cf59SMatthew Knepley @*/ 31017087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 310276b2cf59SMatthew Knepley { 310376b2cf59SMatthew Knepley PetscFunctionBegin; 310476b2cf59SMatthew Knepley PetscFunctionReturn(0); 310576b2cf59SMatthew Knepley } 310676b2cf59SMatthew Knepley 31074a2ae208SSatish Balay #undef __FUNCT__ 31084a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 31099b94acceSBarry Smith /* 31109b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 31119b94acceSBarry Smith positive parameter delta. 31129b94acceSBarry Smith 31139b94acceSBarry Smith Input Parameters: 3114c7afd0dbSLois Curfman McInnes + snes - the SNES context 31159b94acceSBarry Smith . y - approximate solution of linear system 31169b94acceSBarry Smith . fnorm - 2-norm of current function 3117c7afd0dbSLois Curfman McInnes - delta - trust region size 31189b94acceSBarry Smith 31199b94acceSBarry Smith Output Parameters: 3120c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 31219b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 31229b94acceSBarry Smith region, and exceeds zero otherwise. 3123c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 31249b94acceSBarry Smith 31259b94acceSBarry Smith Note: 31264b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 31279b94acceSBarry Smith is set to be the maximum allowable step size. 31289b94acceSBarry Smith 31299b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 31309b94acceSBarry Smith */ 3131dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 31329b94acceSBarry Smith { 3133064f8208SBarry Smith PetscReal nrm; 3134ea709b57SSatish Balay PetscScalar cnorm; 3135dfbe8321SBarry Smith PetscErrorCode ierr; 31363a40ed3dSBarry Smith 31373a40ed3dSBarry Smith PetscFunctionBegin; 31380700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31390700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3140c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3141184914b5SBarry Smith 3142064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3143064f8208SBarry Smith if (nrm > *delta) { 3144064f8208SBarry Smith nrm = *delta/nrm; 3145064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3146064f8208SBarry Smith cnorm = nrm; 31472dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 31489b94acceSBarry Smith *ynorm = *delta; 31499b94acceSBarry Smith } else { 31509b94acceSBarry Smith *gpnorm = 0.0; 3151064f8208SBarry Smith *ynorm = nrm; 31529b94acceSBarry Smith } 31533a40ed3dSBarry Smith PetscFunctionReturn(0); 31549b94acceSBarry Smith } 31559b94acceSBarry Smith 31564a2ae208SSatish Balay #undef __FUNCT__ 31574a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 31586ce558aeSBarry Smith /*@C 3159f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3160f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 31619b94acceSBarry Smith 3162c7afd0dbSLois Curfman McInnes Collective on SNES 3163c7afd0dbSLois Curfman McInnes 3164b2002411SLois Curfman McInnes Input Parameters: 3165c7afd0dbSLois Curfman McInnes + snes - the SNES context 31663cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 316785385478SLisandro Dalcin - x - the solution vector. 31689b94acceSBarry Smith 3169b2002411SLois Curfman McInnes Notes: 31708ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 31718ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 31728ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 31738ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 31748ddd3da0SLois Curfman McInnes 317536851e7fSLois Curfman McInnes Level: beginner 317636851e7fSLois Curfman McInnes 31779b94acceSBarry Smith .keywords: SNES, nonlinear, solve 31789b94acceSBarry Smith 3179c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 31809b94acceSBarry Smith @*/ 31817087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 31829b94acceSBarry Smith { 3183dfbe8321SBarry Smith PetscErrorCode ierr; 3184ace3abfcSBarry Smith PetscBool flg; 3185eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3186eabae89aSBarry Smith PetscViewer viewer; 3187efd51863SBarry Smith PetscInt grid; 3188a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3189052efed2SBarry Smith 31903a40ed3dSBarry Smith PetscFunctionBegin; 31910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3192a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3193a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 31940700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 319585385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 319685385478SLisandro Dalcin 3197a69afd8bSBarry Smith if (!x && snes->dm) { 3198a69afd8bSBarry Smith ierr = DMCreateGlobalVector(snes->dm,&xcreated);CHKERRQ(ierr); 3199a69afd8bSBarry Smith x = xcreated; 3200a69afd8bSBarry Smith } 3201a69afd8bSBarry Smith 3202a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3203efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3204efd51863SBarry Smith 320585385478SLisandro Dalcin /* set solution vector */ 3206efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 32076bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 320885385478SLisandro Dalcin snes->vec_sol = x; 320985385478SLisandro Dalcin /* set afine vector if provided */ 321085385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 32116bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 321285385478SLisandro Dalcin snes->vec_rhs = b; 321385385478SLisandro Dalcin 321470e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 32153f149594SLisandro Dalcin 32167eee914bSBarry Smith if (!grid) { 32177eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3218d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3219dd568438SSatish Balay } else if (snes->dm) { 3220dd568438SSatish Balay PetscBool ig; 3221dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3222dd568438SSatish Balay if (ig) { 32237eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 32247eee914bSBarry Smith } 3225d25893d9SBarry Smith } 3226dd568438SSatish Balay } 3227d25893d9SBarry Smith 3228abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 322950ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3230d5e45103SBarry Smith 32313f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 32324936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 323385385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 32344936397dSBarry Smith if (snes->domainerror){ 32354936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 32364936397dSBarry Smith snes->domainerror = PETSC_FALSE; 32374936397dSBarry Smith } 323817186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 32393f149594SLisandro Dalcin 32407adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3241eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 32427adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 3243eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 32446bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3245eabae89aSBarry Smith } 3246eabae89aSBarry Smith 324790d69ab7SBarry Smith flg = PETSC_FALSE; 3248acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3249da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 32505968eb51SBarry Smith if (snes->printreason) { 3251a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 32525968eb51SBarry Smith if (snes->reason > 0) { 3253a8248277SBarry Smith ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 32545968eb51SBarry Smith } else { 3255a8248277SBarry Smith ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 32565968eb51SBarry Smith } 3257a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 32585968eb51SBarry Smith } 32595968eb51SBarry Smith 32608501fc72SJed Brown flg = PETSC_FALSE; 32618501fc72SJed Brown ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 32628501fc72SJed Brown if (flg) { 32638501fc72SJed Brown PetscViewer viewer; 32648501fc72SJed Brown ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 32658501fc72SJed Brown ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 32668501fc72SJed Brown ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 32678501fc72SJed Brown ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 32688501fc72SJed Brown ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 32698501fc72SJed Brown } 32708501fc72SJed Brown 3271e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3272efd51863SBarry Smith if (grid < snes->gridsequence) { 3273efd51863SBarry Smith DM fine; 3274efd51863SBarry Smith Vec xnew; 3275efd51863SBarry Smith Mat interp; 3276efd51863SBarry Smith 3277efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3278e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3279efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3280efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3281efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3282efd51863SBarry Smith x = xnew; 3283efd51863SBarry Smith 3284efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3285efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3286efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3287a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3288efd51863SBarry Smith } 3289efd51863SBarry Smith } 3290a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 32913a40ed3dSBarry Smith PetscFunctionReturn(0); 32929b94acceSBarry Smith } 32939b94acceSBarry Smith 32949b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 32959b94acceSBarry Smith 32964a2ae208SSatish Balay #undef __FUNCT__ 32974a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 329882bf6240SBarry Smith /*@C 32994b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 33009b94acceSBarry Smith 3301fee21e36SBarry Smith Collective on SNES 3302fee21e36SBarry Smith 3303c7afd0dbSLois Curfman McInnes Input Parameters: 3304c7afd0dbSLois Curfman McInnes + snes - the SNES context 3305454a90a3SBarry Smith - type - a known method 3306c7afd0dbSLois Curfman McInnes 3307c7afd0dbSLois Curfman McInnes Options Database Key: 3308454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3309c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3310ae12b187SLois Curfman McInnes 33119b94acceSBarry Smith Notes: 3312e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 33134b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3314c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 33154b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3316c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 33179b94acceSBarry Smith 3318ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3319ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3320ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3321ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3322ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3323ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3324ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3325ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3326ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3327b0a32e0cSBarry Smith appropriate method. 332836851e7fSLois Curfman McInnes 332936851e7fSLois Curfman McInnes Level: intermediate 3330a703fe33SLois Curfman McInnes 3331454a90a3SBarry Smith .keywords: SNES, set, type 3332435da068SBarry Smith 3333435da068SBarry Smith .seealso: SNESType, SNESCreate() 3334435da068SBarry Smith 33359b94acceSBarry Smith @*/ 33367087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 33379b94acceSBarry Smith { 3338dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3339ace3abfcSBarry Smith PetscBool match; 33403a40ed3dSBarry Smith 33413a40ed3dSBarry Smith PetscFunctionBegin; 33420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33434482741eSBarry Smith PetscValidCharPointer(type,2); 334482bf6240SBarry Smith 33456831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 33460f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 334792ff6ae8SBarry Smith 33484b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3349e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 335075396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3351b5c23020SJed Brown if (snes->ops->destroy) { 3352b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3353b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3354b5c23020SJed Brown } 335575396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 335675396ef9SLisandro Dalcin snes->ops->setup = 0; 335775396ef9SLisandro Dalcin snes->ops->solve = 0; 335875396ef9SLisandro Dalcin snes->ops->view = 0; 335975396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 336075396ef9SLisandro Dalcin snes->ops->destroy = 0; 336175396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 336275396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3363454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 336403bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 33659fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 33669fb22e1aSBarry Smith if (PetscAMSPublishAll) { 33679fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 33689fb22e1aSBarry Smith } 33699fb22e1aSBarry Smith #endif 33703a40ed3dSBarry Smith PetscFunctionReturn(0); 33719b94acceSBarry Smith } 33729b94acceSBarry Smith 3373a847f771SSatish Balay 33749b94acceSBarry Smith /* --------------------------------------------------------------------- */ 33754a2ae208SSatish Balay #undef __FUNCT__ 33764a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 337752baeb72SSatish Balay /*@ 33789b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3379f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 33809b94acceSBarry Smith 3381fee21e36SBarry Smith Not Collective 3382fee21e36SBarry Smith 338336851e7fSLois Curfman McInnes Level: advanced 338436851e7fSLois Curfman McInnes 33859b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 33869b94acceSBarry Smith 33879b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 33889b94acceSBarry Smith @*/ 33897087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 33909b94acceSBarry Smith { 3391dfbe8321SBarry Smith PetscErrorCode ierr; 339282bf6240SBarry Smith 33933a40ed3dSBarry Smith PetscFunctionBegin; 33941441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 33954c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 33963a40ed3dSBarry Smith PetscFunctionReturn(0); 33979b94acceSBarry Smith } 33989b94acceSBarry Smith 33994a2ae208SSatish Balay #undef __FUNCT__ 34004a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 34019b94acceSBarry Smith /*@C 34029a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 34039b94acceSBarry Smith 3404c7afd0dbSLois Curfman McInnes Not Collective 3405c7afd0dbSLois Curfman McInnes 34069b94acceSBarry Smith Input Parameter: 34074b0e389bSBarry Smith . snes - nonlinear solver context 34089b94acceSBarry Smith 34099b94acceSBarry Smith Output Parameter: 34103a7fca6bSBarry Smith . type - SNES method (a character string) 34119b94acceSBarry Smith 341236851e7fSLois Curfman McInnes Level: intermediate 341336851e7fSLois Curfman McInnes 3414454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 34159b94acceSBarry Smith @*/ 34167087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 34179b94acceSBarry Smith { 34183a40ed3dSBarry Smith PetscFunctionBegin; 34190700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34204482741eSBarry Smith PetscValidPointer(type,2); 34217adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 34223a40ed3dSBarry Smith PetscFunctionReturn(0); 34239b94acceSBarry Smith } 34249b94acceSBarry Smith 34254a2ae208SSatish Balay #undef __FUNCT__ 34264a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 342752baeb72SSatish Balay /*@ 34289b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3429c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 34309b94acceSBarry Smith 3431c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3432c7afd0dbSLois Curfman McInnes 34339b94acceSBarry Smith Input Parameter: 34349b94acceSBarry Smith . snes - the SNES context 34359b94acceSBarry Smith 34369b94acceSBarry Smith Output Parameter: 34379b94acceSBarry Smith . x - the solution 34389b94acceSBarry Smith 343970e92668SMatthew Knepley Level: intermediate 344036851e7fSLois Curfman McInnes 34419b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 34429b94acceSBarry Smith 344385385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 34449b94acceSBarry Smith @*/ 34457087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 34469b94acceSBarry Smith { 34473a40ed3dSBarry Smith PetscFunctionBegin; 34480700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34494482741eSBarry Smith PetscValidPointer(x,2); 345085385478SLisandro Dalcin *x = snes->vec_sol; 345170e92668SMatthew Knepley PetscFunctionReturn(0); 345270e92668SMatthew Knepley } 345370e92668SMatthew Knepley 345470e92668SMatthew Knepley #undef __FUNCT__ 34554a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 345652baeb72SSatish Balay /*@ 34579b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 34589b94acceSBarry Smith stored. 34599b94acceSBarry Smith 3460c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3461c7afd0dbSLois Curfman McInnes 34629b94acceSBarry Smith Input Parameter: 34639b94acceSBarry Smith . snes - the SNES context 34649b94acceSBarry Smith 34659b94acceSBarry Smith Output Parameter: 34669b94acceSBarry Smith . x - the solution update 34679b94acceSBarry Smith 346836851e7fSLois Curfman McInnes Level: advanced 346936851e7fSLois Curfman McInnes 34709b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 34719b94acceSBarry Smith 347285385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 34739b94acceSBarry Smith @*/ 34747087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 34759b94acceSBarry Smith { 34763a40ed3dSBarry Smith PetscFunctionBegin; 34770700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34784482741eSBarry Smith PetscValidPointer(x,2); 347985385478SLisandro Dalcin *x = snes->vec_sol_update; 34803a40ed3dSBarry Smith PetscFunctionReturn(0); 34819b94acceSBarry Smith } 34829b94acceSBarry Smith 34834a2ae208SSatish Balay #undef __FUNCT__ 34844a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 34859b94acceSBarry Smith /*@C 34863638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 34879b94acceSBarry Smith 3488a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3489c7afd0dbSLois Curfman McInnes 34909b94acceSBarry Smith Input Parameter: 34919b94acceSBarry Smith . snes - the SNES context 34929b94acceSBarry Smith 34939b94acceSBarry Smith Output Parameter: 34947bf4e008SBarry Smith + r - the function (or PETSC_NULL) 349570e92668SMatthew Knepley . func - the function (or PETSC_NULL) 349670e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 34979b94acceSBarry Smith 349836851e7fSLois Curfman McInnes Level: advanced 349936851e7fSLois Curfman McInnes 3500a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 35019b94acceSBarry Smith 35024b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 35039b94acceSBarry Smith @*/ 35047087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 35059b94acceSBarry Smith { 3506a63bb30eSJed Brown PetscErrorCode ierr; 3507*6cab3a1bSJed Brown DM dm; 3508a63bb30eSJed Brown 35093a40ed3dSBarry Smith PetscFunctionBegin; 35100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3511a63bb30eSJed Brown if (r) { 3512a63bb30eSJed Brown if (!snes->vec_func) { 3513a63bb30eSJed Brown if (snes->vec_rhs) { 3514a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3515a63bb30eSJed Brown } else if (snes->vec_sol) { 3516a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3517a63bb30eSJed Brown } else if (snes->dm) { 3518a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3519a63bb30eSJed Brown } 3520a63bb30eSJed Brown } 3521a63bb30eSJed Brown *r = snes->vec_func; 3522a63bb30eSJed Brown } 3523*6cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3524*6cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 35253a40ed3dSBarry Smith PetscFunctionReturn(0); 35269b94acceSBarry Smith } 35279b94acceSBarry Smith 3528c79ef259SPeter Brune /*@C 3529c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3530c79ef259SPeter Brune 3531c79ef259SPeter Brune Input Parameter: 3532c79ef259SPeter Brune . snes - the SNES context 3533c79ef259SPeter Brune 3534c79ef259SPeter Brune Output Parameter: 3535c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3536c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3537c79ef259SPeter Brune 3538c79ef259SPeter Brune Level: advanced 3539c79ef259SPeter Brune 3540c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3541c79ef259SPeter Brune 3542c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3543c79ef259SPeter Brune @*/ 3544c79ef259SPeter Brune 35454a2ae208SSatish Balay #undef __FUNCT__ 3546646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3547646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3548646217ecSPeter Brune { 3549*6cab3a1bSJed Brown PetscErrorCode ierr; 3550*6cab3a1bSJed Brown DM dm; 3551*6cab3a1bSJed Brown 3552646217ecSPeter Brune PetscFunctionBegin; 3553646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3554*6cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3555*6cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3556646217ecSPeter Brune PetscFunctionReturn(0); 3557646217ecSPeter Brune } 3558646217ecSPeter Brune 35594a2ae208SSatish Balay #undef __FUNCT__ 35604a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 35613c7409f5SSatish Balay /*@C 35623c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3563d850072dSLois Curfman McInnes SNES options in the database. 35643c7409f5SSatish Balay 35653f9fe445SBarry Smith Logically Collective on SNES 3566fee21e36SBarry Smith 3567c7afd0dbSLois Curfman McInnes Input Parameter: 3568c7afd0dbSLois Curfman McInnes + snes - the SNES context 3569c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3570c7afd0dbSLois Curfman McInnes 3571d850072dSLois Curfman McInnes Notes: 3572a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3573c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3574d850072dSLois Curfman McInnes 357536851e7fSLois Curfman McInnes Level: advanced 357636851e7fSLois Curfman McInnes 35773c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3578a86d99e1SLois Curfman McInnes 3579a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 35803c7409f5SSatish Balay @*/ 35817087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 35823c7409f5SSatish Balay { 3583dfbe8321SBarry Smith PetscErrorCode ierr; 35843c7409f5SSatish Balay 35853a40ed3dSBarry Smith PetscFunctionBegin; 35860700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3587639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 35881cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 358994b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 35903a40ed3dSBarry Smith PetscFunctionReturn(0); 35913c7409f5SSatish Balay } 35923c7409f5SSatish Balay 35934a2ae208SSatish Balay #undef __FUNCT__ 35944a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 35953c7409f5SSatish Balay /*@C 3596f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3597d850072dSLois Curfman McInnes SNES options in the database. 35983c7409f5SSatish Balay 35993f9fe445SBarry Smith Logically Collective on SNES 3600fee21e36SBarry Smith 3601c7afd0dbSLois Curfman McInnes Input Parameters: 3602c7afd0dbSLois Curfman McInnes + snes - the SNES context 3603c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3604c7afd0dbSLois Curfman McInnes 3605d850072dSLois Curfman McInnes Notes: 3606a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3607c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3608d850072dSLois Curfman McInnes 360936851e7fSLois Curfman McInnes Level: advanced 361036851e7fSLois Curfman McInnes 36113c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3612a86d99e1SLois Curfman McInnes 3613a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 36143c7409f5SSatish Balay @*/ 36157087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 36163c7409f5SSatish Balay { 3617dfbe8321SBarry Smith PetscErrorCode ierr; 36183c7409f5SSatish Balay 36193a40ed3dSBarry Smith PetscFunctionBegin; 36200700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3621639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 36221cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 362394b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 36243a40ed3dSBarry Smith PetscFunctionReturn(0); 36253c7409f5SSatish Balay } 36263c7409f5SSatish Balay 36274a2ae208SSatish Balay #undef __FUNCT__ 36284a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 36299ab63eb5SSatish Balay /*@C 36303c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 36313c7409f5SSatish Balay SNES options in the database. 36323c7409f5SSatish Balay 3633c7afd0dbSLois Curfman McInnes Not Collective 3634c7afd0dbSLois Curfman McInnes 36353c7409f5SSatish Balay Input Parameter: 36363c7409f5SSatish Balay . snes - the SNES context 36373c7409f5SSatish Balay 36383c7409f5SSatish Balay Output Parameter: 36393c7409f5SSatish Balay . prefix - pointer to the prefix string used 36403c7409f5SSatish Balay 36414ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 36429ab63eb5SSatish Balay sufficient length to hold the prefix. 36439ab63eb5SSatish Balay 364436851e7fSLois Curfman McInnes Level: advanced 364536851e7fSLois Curfman McInnes 36463c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3647a86d99e1SLois Curfman McInnes 3648a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 36493c7409f5SSatish Balay @*/ 36507087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 36513c7409f5SSatish Balay { 3652dfbe8321SBarry Smith PetscErrorCode ierr; 36533c7409f5SSatish Balay 36543a40ed3dSBarry Smith PetscFunctionBegin; 36550700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3656639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 36573a40ed3dSBarry Smith PetscFunctionReturn(0); 36583c7409f5SSatish Balay } 36593c7409f5SSatish Balay 3660b2002411SLois Curfman McInnes 36614a2ae208SSatish Balay #undef __FUNCT__ 36624a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 36633cea93caSBarry Smith /*@C 36643cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 36653cea93caSBarry Smith 36667f6c08e0SMatthew Knepley Level: advanced 36673cea93caSBarry Smith @*/ 36687087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3669b2002411SLois Curfman McInnes { 3670e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3671dfbe8321SBarry Smith PetscErrorCode ierr; 3672b2002411SLois Curfman McInnes 3673b2002411SLois Curfman McInnes PetscFunctionBegin; 3674b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3675c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3676b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3677b2002411SLois Curfman McInnes } 3678da9b6338SBarry Smith 3679da9b6338SBarry Smith #undef __FUNCT__ 3680da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 36817087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3682da9b6338SBarry Smith { 3683dfbe8321SBarry Smith PetscErrorCode ierr; 368477431f27SBarry Smith PetscInt N,i,j; 3685da9b6338SBarry Smith Vec u,uh,fh; 3686da9b6338SBarry Smith PetscScalar value; 3687da9b6338SBarry Smith PetscReal norm; 3688da9b6338SBarry Smith 3689da9b6338SBarry Smith PetscFunctionBegin; 3690da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3691da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3692da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3693da9b6338SBarry Smith 3694da9b6338SBarry Smith /* currently only works for sequential */ 3695da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3696da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3697da9b6338SBarry Smith for (i=0; i<N; i++) { 3698da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 369977431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3700da9b6338SBarry Smith for (j=-10; j<11; j++) { 3701ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3702da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 37033ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3704da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 370577431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3706da9b6338SBarry Smith value = -value; 3707da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3708da9b6338SBarry Smith } 3709da9b6338SBarry Smith } 37106bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 37116bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3712da9b6338SBarry Smith PetscFunctionReturn(0); 3713da9b6338SBarry Smith } 371471f87433Sdalcinl 371571f87433Sdalcinl #undef __FUNCT__ 3716fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 371771f87433Sdalcinl /*@ 3718fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 371971f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 372071f87433Sdalcinl Newton method. 372171f87433Sdalcinl 37223f9fe445SBarry Smith Logically Collective on SNES 372371f87433Sdalcinl 372471f87433Sdalcinl Input Parameters: 372571f87433Sdalcinl + snes - SNES context 372671f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 372771f87433Sdalcinl 372864ba62caSBarry Smith Options Database: 372964ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 373064ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 373164ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 373264ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 373364ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 373464ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 373564ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 373664ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 373764ba62caSBarry Smith 373871f87433Sdalcinl Notes: 373971f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 374071f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 374171f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 374271f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 374371f87433Sdalcinl solver. 374471f87433Sdalcinl 374571f87433Sdalcinl Level: advanced 374671f87433Sdalcinl 374771f87433Sdalcinl Reference: 374871f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 374971f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 375071f87433Sdalcinl 375171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 375271f87433Sdalcinl 3753fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 375471f87433Sdalcinl @*/ 37557087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 375671f87433Sdalcinl { 375771f87433Sdalcinl PetscFunctionBegin; 37580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3759acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 376071f87433Sdalcinl snes->ksp_ewconv = flag; 376171f87433Sdalcinl PetscFunctionReturn(0); 376271f87433Sdalcinl } 376371f87433Sdalcinl 376471f87433Sdalcinl #undef __FUNCT__ 3765fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 376671f87433Sdalcinl /*@ 3767fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 376871f87433Sdalcinl for computing relative tolerance for linear solvers within an 376971f87433Sdalcinl inexact Newton method. 377071f87433Sdalcinl 377171f87433Sdalcinl Not Collective 377271f87433Sdalcinl 377371f87433Sdalcinl Input Parameter: 377471f87433Sdalcinl . snes - SNES context 377571f87433Sdalcinl 377671f87433Sdalcinl Output Parameter: 377771f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 377871f87433Sdalcinl 377971f87433Sdalcinl Notes: 378071f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 378171f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 378271f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 378371f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 378471f87433Sdalcinl solver. 378571f87433Sdalcinl 378671f87433Sdalcinl Level: advanced 378771f87433Sdalcinl 378871f87433Sdalcinl Reference: 378971f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 379071f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 379171f87433Sdalcinl 379271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 379371f87433Sdalcinl 3794fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 379571f87433Sdalcinl @*/ 37967087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 379771f87433Sdalcinl { 379871f87433Sdalcinl PetscFunctionBegin; 37990700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 380071f87433Sdalcinl PetscValidPointer(flag,2); 380171f87433Sdalcinl *flag = snes->ksp_ewconv; 380271f87433Sdalcinl PetscFunctionReturn(0); 380371f87433Sdalcinl } 380471f87433Sdalcinl 380571f87433Sdalcinl #undef __FUNCT__ 3806fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 380771f87433Sdalcinl /*@ 3808fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 380971f87433Sdalcinl convergence criteria for the linear solvers within an inexact 381071f87433Sdalcinl Newton method. 381171f87433Sdalcinl 38123f9fe445SBarry Smith Logically Collective on SNES 381371f87433Sdalcinl 381471f87433Sdalcinl Input Parameters: 381571f87433Sdalcinl + snes - SNES context 381671f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 381771f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 381871f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 381971f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 382071f87433Sdalcinl (0 <= gamma2 <= 1) 382171f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 382271f87433Sdalcinl . alpha2 - power for safeguard 382371f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 382471f87433Sdalcinl 382571f87433Sdalcinl Note: 382671f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 382771f87433Sdalcinl 382871f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 382971f87433Sdalcinl 383071f87433Sdalcinl Level: advanced 383171f87433Sdalcinl 383271f87433Sdalcinl Reference: 383371f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 383471f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 383571f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 383671f87433Sdalcinl 383771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 383871f87433Sdalcinl 3839fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 384071f87433Sdalcinl @*/ 38417087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 384271f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 384371f87433Sdalcinl { 3844fa9f3622SBarry Smith SNESKSPEW *kctx; 384571f87433Sdalcinl PetscFunctionBegin; 38460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3847fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3848e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3849c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 3850c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 3851c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 3852c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 3853c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 3854c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 3855c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 385671f87433Sdalcinl 385771f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 385871f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 385971f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 386071f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 386171f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 386271f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 386371f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 386471f87433Sdalcinl 386571f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 3866e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 386771f87433Sdalcinl } 386871f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 3869e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 387071f87433Sdalcinl } 387171f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 3872e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 387371f87433Sdalcinl } 387471f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 3875e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 387671f87433Sdalcinl } 387771f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 3878e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 387971f87433Sdalcinl } 388071f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 3881e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 388271f87433Sdalcinl } 388371f87433Sdalcinl PetscFunctionReturn(0); 388471f87433Sdalcinl } 388571f87433Sdalcinl 388671f87433Sdalcinl #undef __FUNCT__ 3887fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 388871f87433Sdalcinl /*@ 3889fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 389071f87433Sdalcinl convergence criteria for the linear solvers within an inexact 389171f87433Sdalcinl Newton method. 389271f87433Sdalcinl 389371f87433Sdalcinl Not Collective 389471f87433Sdalcinl 389571f87433Sdalcinl Input Parameters: 389671f87433Sdalcinl snes - SNES context 389771f87433Sdalcinl 389871f87433Sdalcinl Output Parameters: 389971f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 390071f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 390171f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 390271f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 390371f87433Sdalcinl (0 <= gamma2 <= 1) 390471f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 390571f87433Sdalcinl . alpha2 - power for safeguard 390671f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 390771f87433Sdalcinl 390871f87433Sdalcinl Level: advanced 390971f87433Sdalcinl 391071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 391171f87433Sdalcinl 3912fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 391371f87433Sdalcinl @*/ 39147087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 391571f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 391671f87433Sdalcinl { 3917fa9f3622SBarry Smith SNESKSPEW *kctx; 391871f87433Sdalcinl PetscFunctionBegin; 39190700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3920fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3921e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 392271f87433Sdalcinl if(version) *version = kctx->version; 392371f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 392471f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 392571f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 392671f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 392771f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 392871f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 392971f87433Sdalcinl PetscFunctionReturn(0); 393071f87433Sdalcinl } 393171f87433Sdalcinl 393271f87433Sdalcinl #undef __FUNCT__ 3933fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 3934fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 393571f87433Sdalcinl { 393671f87433Sdalcinl PetscErrorCode ierr; 3937fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 393871f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 393971f87433Sdalcinl 394071f87433Sdalcinl PetscFunctionBegin; 3941e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 394271f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 394371f87433Sdalcinl rtol = kctx->rtol_0; 394471f87433Sdalcinl } else { 394571f87433Sdalcinl if (kctx->version == 1) { 394671f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 394771f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 394871f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 394971f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 395071f87433Sdalcinl } else if (kctx->version == 2) { 395171f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 395271f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 395371f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 395471f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 395571f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 395671f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 395771f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 395871f87433Sdalcinl stol = PetscMax(rtol,stol); 395971f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 396071f87433Sdalcinl /* safeguard: avoid oversolving */ 396171f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 396271f87433Sdalcinl stol = PetscMax(rtol,stol); 396371f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 3964e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 396571f87433Sdalcinl } 396671f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 396771f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 396871f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 396971f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 397071f87433Sdalcinl PetscFunctionReturn(0); 397171f87433Sdalcinl } 397271f87433Sdalcinl 397371f87433Sdalcinl #undef __FUNCT__ 3974fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 3975fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 397671f87433Sdalcinl { 397771f87433Sdalcinl PetscErrorCode ierr; 3978fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 397971f87433Sdalcinl PCSide pcside; 398071f87433Sdalcinl Vec lres; 398171f87433Sdalcinl 398271f87433Sdalcinl PetscFunctionBegin; 3983e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 398471f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 398571f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 398671f87433Sdalcinl if (kctx->version == 1) { 3987b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 398871f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 398971f87433Sdalcinl /* KSP residual is true linear residual */ 399071f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 399171f87433Sdalcinl } else { 399271f87433Sdalcinl /* KSP residual is preconditioned residual */ 399371f87433Sdalcinl /* compute true linear residual norm */ 399471f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 399571f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 399671f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 399771f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 39986bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 399971f87433Sdalcinl } 400071f87433Sdalcinl } 400171f87433Sdalcinl PetscFunctionReturn(0); 400271f87433Sdalcinl } 400371f87433Sdalcinl 400471f87433Sdalcinl #undef __FUNCT__ 400571f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 400671f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 400771f87433Sdalcinl { 400871f87433Sdalcinl PetscErrorCode ierr; 400971f87433Sdalcinl 401071f87433Sdalcinl PetscFunctionBegin; 4011fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 401271f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4013fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 401471f87433Sdalcinl PetscFunctionReturn(0); 401571f87433Sdalcinl } 40166c699258SBarry Smith 40176c699258SBarry Smith #undef __FUNCT__ 40186c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 40196c699258SBarry Smith /*@ 40206c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 40216c699258SBarry Smith 40223f9fe445SBarry Smith Logically Collective on SNES 40236c699258SBarry Smith 40246c699258SBarry Smith Input Parameters: 40256c699258SBarry Smith + snes - the preconditioner context 40266c699258SBarry Smith - dm - the dm 40276c699258SBarry Smith 40286c699258SBarry Smith Level: intermediate 40296c699258SBarry Smith 40306c699258SBarry Smith 40316c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 40326c699258SBarry Smith @*/ 40337087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 40346c699258SBarry Smith { 40356c699258SBarry Smith PetscErrorCode ierr; 4036345fed2cSBarry Smith KSP ksp; 4037*6cab3a1bSJed Brown SNESDM sdm; 40386c699258SBarry Smith 40396c699258SBarry Smith PetscFunctionBegin; 40400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4041d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 4042*6cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 4043*6cab3a1bSJed Brown PetscContainer oldcontainer,container; 4044*6cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 4045*6cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 4046*6cab3a1bSJed Brown if (oldcontainer && !container) { 4047*6cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 4048*6cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 4049*6cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 4050*6cab3a1bSJed Brown sdm->originaldm = dm; 4051*6cab3a1bSJed Brown } 4052*6cab3a1bSJed Brown } 40536bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 4054*6cab3a1bSJed Brown } 40556c699258SBarry Smith snes->dm = dm; 4056345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4057345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4058f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 40592c155ee1SBarry Smith if (snes->pc) { 40602c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 40612c155ee1SBarry Smith } 40626c699258SBarry Smith PetscFunctionReturn(0); 40636c699258SBarry Smith } 40646c699258SBarry Smith 40656c699258SBarry Smith #undef __FUNCT__ 40666c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 40676c699258SBarry Smith /*@ 40686c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 40696c699258SBarry Smith 40703f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 40716c699258SBarry Smith 40726c699258SBarry Smith Input Parameter: 40736c699258SBarry Smith . snes - the preconditioner context 40746c699258SBarry Smith 40756c699258SBarry Smith Output Parameter: 40766c699258SBarry Smith . dm - the dm 40776c699258SBarry Smith 40786c699258SBarry Smith Level: intermediate 40796c699258SBarry Smith 40806c699258SBarry Smith 40816c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 40826c699258SBarry Smith @*/ 40837087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 40846c699258SBarry Smith { 4085*6cab3a1bSJed Brown PetscErrorCode ierr; 4086*6cab3a1bSJed Brown 40876c699258SBarry Smith PetscFunctionBegin; 40880700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4089*6cab3a1bSJed Brown if (!snes->dm) { 4090*6cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 4091*6cab3a1bSJed Brown } 40926c699258SBarry Smith *dm = snes->dm; 40936c699258SBarry Smith PetscFunctionReturn(0); 40946c699258SBarry Smith } 40950807856dSBarry Smith 409631823bd8SMatthew G Knepley #undef __FUNCT__ 409731823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 409831823bd8SMatthew G Knepley /*@ 4099fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 410031823bd8SMatthew G Knepley 410131823bd8SMatthew G Knepley Collective on SNES 410231823bd8SMatthew G Knepley 410331823bd8SMatthew G Knepley Input Parameters: 410431823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 410531823bd8SMatthew G Knepley - pc - the preconditioner object 410631823bd8SMatthew G Knepley 410731823bd8SMatthew G Knepley Notes: 410831823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 410931823bd8SMatthew G Knepley to configure it using the API). 411031823bd8SMatthew G Knepley 411131823bd8SMatthew G Knepley Level: developer 411231823bd8SMatthew G Knepley 411331823bd8SMatthew G Knepley .keywords: SNES, set, precondition 411431823bd8SMatthew G Knepley .seealso: SNESGetPC() 411531823bd8SMatthew G Knepley @*/ 411631823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 411731823bd8SMatthew G Knepley { 411831823bd8SMatthew G Knepley PetscErrorCode ierr; 411931823bd8SMatthew G Knepley 412031823bd8SMatthew G Knepley PetscFunctionBegin; 412131823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 412231823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 412331823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 412431823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4125bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 412631823bd8SMatthew G Knepley snes->pc = pc; 412731823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 412831823bd8SMatthew G Knepley PetscFunctionReturn(0); 412931823bd8SMatthew G Knepley } 413031823bd8SMatthew G Knepley 413131823bd8SMatthew G Knepley #undef __FUNCT__ 413231823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 413331823bd8SMatthew G Knepley /*@ 4134fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 413531823bd8SMatthew G Knepley 413631823bd8SMatthew G Knepley Not Collective 413731823bd8SMatthew G Knepley 413831823bd8SMatthew G Knepley Input Parameter: 413931823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 414031823bd8SMatthew G Knepley 414131823bd8SMatthew G Knepley Output Parameter: 414231823bd8SMatthew G Knepley . pc - preconditioner context 414331823bd8SMatthew G Knepley 414431823bd8SMatthew G Knepley Level: developer 414531823bd8SMatthew G Knepley 414631823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 414731823bd8SMatthew G Knepley .seealso: SNESSetPC() 414831823bd8SMatthew G Knepley @*/ 414931823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 415031823bd8SMatthew G Knepley { 415131823bd8SMatthew G Knepley PetscErrorCode ierr; 415231823bd8SMatthew G Knepley 415331823bd8SMatthew G Knepley PetscFunctionBegin; 415431823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 415531823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 415631823bd8SMatthew G Knepley if (!snes->pc) { 415731823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 41584a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 415931823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 416031823bd8SMatthew G Knepley } 416131823bd8SMatthew G Knepley *pc = snes->pc; 416231823bd8SMatthew G Knepley PetscFunctionReturn(0); 416331823bd8SMatthew G Knepley } 416431823bd8SMatthew G Knepley 416569b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4166c6db04a5SJed Brown #include <mex.h> 416769b4f73cSBarry Smith 41688f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 41698f6e6473SBarry Smith 41700807856dSBarry Smith #undef __FUNCT__ 41710807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 41720807856dSBarry Smith /* 41730807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 41740807856dSBarry Smith SNESSetFunctionMatlab(). 41750807856dSBarry Smith 41760807856dSBarry Smith Collective on SNES 41770807856dSBarry Smith 41780807856dSBarry Smith Input Parameters: 41790807856dSBarry Smith + snes - the SNES context 41800807856dSBarry Smith - x - input vector 41810807856dSBarry Smith 41820807856dSBarry Smith Output Parameter: 41830807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 41840807856dSBarry Smith 41850807856dSBarry Smith Notes: 41860807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 41870807856dSBarry Smith implementations, so most users would not generally call this routine 41880807856dSBarry Smith themselves. 41890807856dSBarry Smith 41900807856dSBarry Smith Level: developer 41910807856dSBarry Smith 41920807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 41930807856dSBarry Smith 41940807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 419561b2408cSBarry Smith */ 41967087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 41970807856dSBarry Smith { 4198e650e774SBarry Smith PetscErrorCode ierr; 41998f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 42008f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 42018f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 420291621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4203e650e774SBarry Smith 42040807856dSBarry Smith PetscFunctionBegin; 42050807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 42060807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 42070807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 42080807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 42090807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 42100807856dSBarry Smith 42110807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4212e650e774SBarry Smith 421391621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4214e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4215e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 421691621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 421791621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 421891621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 42198f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 42208f6e6473SBarry Smith prhs[4] = sctx->ctx; 4221b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4222e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4223e650e774SBarry Smith mxDestroyArray(prhs[0]); 4224e650e774SBarry Smith mxDestroyArray(prhs[1]); 4225e650e774SBarry Smith mxDestroyArray(prhs[2]); 42268f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4227e650e774SBarry Smith mxDestroyArray(plhs[0]); 42280807856dSBarry Smith PetscFunctionReturn(0); 42290807856dSBarry Smith } 42300807856dSBarry Smith 42310807856dSBarry Smith 42320807856dSBarry Smith #undef __FUNCT__ 42330807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 423461b2408cSBarry Smith /* 42350807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 42360807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4237e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 42380807856dSBarry Smith 42390807856dSBarry Smith Logically Collective on SNES 42400807856dSBarry Smith 42410807856dSBarry Smith Input Parameters: 42420807856dSBarry Smith + snes - the SNES context 42430807856dSBarry Smith . r - vector to store function value 42440807856dSBarry Smith - func - function evaluation routine 42450807856dSBarry Smith 42460807856dSBarry Smith Calling sequence of func: 424761b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 42480807856dSBarry Smith 42490807856dSBarry Smith 42500807856dSBarry Smith Notes: 42510807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 42520807856dSBarry Smith $ f'(x) x = -f(x), 42530807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 42540807856dSBarry Smith 42550807856dSBarry Smith Level: beginner 42560807856dSBarry Smith 42570807856dSBarry Smith .keywords: SNES, nonlinear, set, function 42580807856dSBarry Smith 42590807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 426061b2408cSBarry Smith */ 42617087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 42620807856dSBarry Smith { 42630807856dSBarry Smith PetscErrorCode ierr; 42648f6e6473SBarry Smith SNESMatlabContext *sctx; 42650807856dSBarry Smith 42660807856dSBarry Smith PetscFunctionBegin; 42678f6e6473SBarry Smith /* currently sctx is memory bleed */ 42688f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 42698f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 42708f6e6473SBarry Smith /* 42718f6e6473SBarry Smith This should work, but it doesn't 42728f6e6473SBarry Smith sctx->ctx = ctx; 42738f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 42748f6e6473SBarry Smith */ 42758f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 42768f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 42770807856dSBarry Smith PetscFunctionReturn(0); 42780807856dSBarry Smith } 427969b4f73cSBarry Smith 428061b2408cSBarry Smith #undef __FUNCT__ 428161b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 428261b2408cSBarry Smith /* 428361b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 428461b2408cSBarry Smith SNESSetJacobianMatlab(). 428561b2408cSBarry Smith 428661b2408cSBarry Smith Collective on SNES 428761b2408cSBarry Smith 428861b2408cSBarry Smith Input Parameters: 428961b2408cSBarry Smith + snes - the SNES context 429061b2408cSBarry Smith . x - input vector 429161b2408cSBarry Smith . A, B - the matrices 429261b2408cSBarry Smith - ctx - user context 429361b2408cSBarry Smith 429461b2408cSBarry Smith Output Parameter: 429561b2408cSBarry Smith . flag - structure of the matrix 429661b2408cSBarry Smith 429761b2408cSBarry Smith Level: developer 429861b2408cSBarry Smith 429961b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 430061b2408cSBarry Smith 430161b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 430261b2408cSBarry Smith @*/ 43037087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 430461b2408cSBarry Smith { 430561b2408cSBarry Smith PetscErrorCode ierr; 430661b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 430761b2408cSBarry Smith int nlhs = 2,nrhs = 6; 430861b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 430961b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 431061b2408cSBarry Smith 431161b2408cSBarry Smith PetscFunctionBegin; 431261b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 431361b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 431461b2408cSBarry Smith 431561b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 431661b2408cSBarry Smith 431761b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 431861b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 431961b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 432061b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 432161b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 432261b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 432361b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 432461b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 432561b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 432661b2408cSBarry Smith prhs[5] = sctx->ctx; 4327b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 432861b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 432961b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 433061b2408cSBarry Smith mxDestroyArray(prhs[0]); 433161b2408cSBarry Smith mxDestroyArray(prhs[1]); 433261b2408cSBarry Smith mxDestroyArray(prhs[2]); 433361b2408cSBarry Smith mxDestroyArray(prhs[3]); 433461b2408cSBarry Smith mxDestroyArray(prhs[4]); 433561b2408cSBarry Smith mxDestroyArray(plhs[0]); 433661b2408cSBarry Smith mxDestroyArray(plhs[1]); 433761b2408cSBarry Smith PetscFunctionReturn(0); 433861b2408cSBarry Smith } 433961b2408cSBarry Smith 434061b2408cSBarry Smith 434161b2408cSBarry Smith #undef __FUNCT__ 434261b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 434361b2408cSBarry Smith /* 434461b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 434561b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4346e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 434761b2408cSBarry Smith 434861b2408cSBarry Smith Logically Collective on SNES 434961b2408cSBarry Smith 435061b2408cSBarry Smith Input Parameters: 435161b2408cSBarry Smith + snes - the SNES context 435261b2408cSBarry Smith . A,B - Jacobian matrices 435361b2408cSBarry Smith . func - function evaluation routine 435461b2408cSBarry Smith - ctx - user context 435561b2408cSBarry Smith 435661b2408cSBarry Smith Calling sequence of func: 435761b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 435861b2408cSBarry Smith 435961b2408cSBarry Smith 436061b2408cSBarry Smith Level: developer 436161b2408cSBarry Smith 436261b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 436361b2408cSBarry Smith 436461b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 436561b2408cSBarry Smith */ 43667087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 436761b2408cSBarry Smith { 436861b2408cSBarry Smith PetscErrorCode ierr; 436961b2408cSBarry Smith SNESMatlabContext *sctx; 437061b2408cSBarry Smith 437161b2408cSBarry Smith PetscFunctionBegin; 437261b2408cSBarry Smith /* currently sctx is memory bleed */ 437361b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 437461b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 437561b2408cSBarry Smith /* 437661b2408cSBarry Smith This should work, but it doesn't 437761b2408cSBarry Smith sctx->ctx = ctx; 437861b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 437961b2408cSBarry Smith */ 438061b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 438161b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 438261b2408cSBarry Smith PetscFunctionReturn(0); 438361b2408cSBarry Smith } 438469b4f73cSBarry Smith 4385f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4386f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4387f9eb7ae2SShri Abhyankar /* 4388f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4389f9eb7ae2SShri Abhyankar 4390f9eb7ae2SShri Abhyankar Collective on SNES 4391f9eb7ae2SShri Abhyankar 4392f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4393f9eb7ae2SShri Abhyankar @*/ 43947087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4395f9eb7ae2SShri Abhyankar { 4396f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 439748f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4398f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4399f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4400f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4401f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4402f9eb7ae2SShri Abhyankar 4403f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4404f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4405f9eb7ae2SShri Abhyankar 4406f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4407f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4408f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4409f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4410f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4411f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4412f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4413f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4414f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4415f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4416f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4417f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4418f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4419f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4420f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4421f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4422f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4423f9eb7ae2SShri Abhyankar } 4424f9eb7ae2SShri Abhyankar 4425f9eb7ae2SShri Abhyankar 4426f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4427f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4428f9eb7ae2SShri Abhyankar /* 4429e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4430f9eb7ae2SShri Abhyankar 4431f9eb7ae2SShri Abhyankar Level: developer 4432f9eb7ae2SShri Abhyankar 4433f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4434f9eb7ae2SShri Abhyankar 4435f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4436f9eb7ae2SShri Abhyankar */ 44377087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4438f9eb7ae2SShri Abhyankar { 4439f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4440f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4441f9eb7ae2SShri Abhyankar 4442f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4443f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4444f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4445f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4446f9eb7ae2SShri Abhyankar /* 4447f9eb7ae2SShri Abhyankar This should work, but it doesn't 4448f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4449f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4450f9eb7ae2SShri Abhyankar */ 4451f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4452f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4453f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4454f9eb7ae2SShri Abhyankar } 4455f9eb7ae2SShri Abhyankar 445669b4f73cSBarry Smith #endif 4457