1af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/ 207475bc1SBarry Smith #include <petscdmshell.h> 3d96771aaSLisandro Dalcin #include <petscdraw.h> 4a01aa210SMatthew G. Knepley #include <petscds.h> 534b4d3a8SMatthew G. Knepley #include <petscdmadaptor.h> 606fc46c8SMatthew G. Knepley #include <petscconvest.h> 79b94acceSBarry Smith 8ace3abfcSBarry Smith PetscBool SNESRegisterAllCalled = PETSC_FALSE; 90298fd71SBarry Smith PetscFunctionList SNESList = NULL; 108ba1e511SMatthew Knepley 118ba1e511SMatthew Knepley /* Logging support */ 1222c6f798SBarry Smith PetscClassId SNES_CLASSID, DMSNES_CLASSID; 13fc8bc0e3SRichard Tran Mills PetscLogEvent SNES_Solve, SNES_SetUp, SNES_FunctionEval, SNES_JacobianEval, SNES_NGSEval, SNES_NGSFuncEval, SNES_NPCSolve, SNES_ObjectiveEval; 14a09944afSBarry Smith 15e113a28aSBarry Smith /*@ 16dc4c0fb0SBarry Smith SNESSetErrorIfNotConverged - Causes `SNESSolve()` to generate an error immediately if the solver has not converged. 17e113a28aSBarry Smith 18c3339decSBarry Smith Logically Collective 19e113a28aSBarry Smith 20e113a28aSBarry Smith Input Parameters: 21f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 22f6dfbefdSBarry Smith - flg - `PETSC_TRUE` indicates you want the error generated 23e113a28aSBarry Smith 2420f4b53cSBarry Smith Options Database Key: 2567b8a455SSatish Balay . -snes_error_if_not_converged <true,false> - cause an immediate error condition and stop the program if the solver does not converge 26e113a28aSBarry Smith 27e113a28aSBarry Smith Level: intermediate 28e113a28aSBarry Smith 29f6dfbefdSBarry Smith Note: 30f6dfbefdSBarry Smith Normally PETSc continues if a solver fails to converge, you can call `SNESGetConvergedReason()` after a `SNESSolve()` 31f6dfbefdSBarry Smith to determine if it has converged. Otherwise the solution may be inaccurate or wrong 32e113a28aSBarry Smith 331cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESGetErrorIfNotConverged()`, `KSPGetErrorIfNotConverged()`, `KSPSetErrorIfNotConverged()` 34e113a28aSBarry Smith @*/ 35d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetErrorIfNotConverged(SNES snes, PetscBool flg) 36d71ae5a4SJacob Faibussowitsch { 37e113a28aSBarry Smith PetscFunctionBegin; 38e113a28aSBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 39acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes, flg, 2); 40e113a28aSBarry Smith snes->errorifnotconverged = flg; 413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 42e113a28aSBarry Smith } 43e113a28aSBarry Smith 44e113a28aSBarry Smith /*@ 45f6dfbefdSBarry Smith SNESGetErrorIfNotConverged - Indicates if `SNESSolve()` will generate an error if the solver does not converge? 46e113a28aSBarry Smith 47e113a28aSBarry Smith Not Collective 48e113a28aSBarry Smith 49e113a28aSBarry Smith Input Parameter: 50f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 51e113a28aSBarry Smith 52e113a28aSBarry Smith Output Parameter: 53f6dfbefdSBarry Smith . flag - `PETSC_TRUE` if it will generate an error, else `PETSC_FALSE` 54e113a28aSBarry Smith 55e113a28aSBarry Smith Level: intermediate 56e113a28aSBarry Smith 571cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetErrorIfNotConverged()`, `KSPGetErrorIfNotConverged()`, `KSPSetErrorIfNotConverged()` 58e113a28aSBarry Smith @*/ 59d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetErrorIfNotConverged(SNES snes, PetscBool *flag) 60d71ae5a4SJacob Faibussowitsch { 61e113a28aSBarry Smith PetscFunctionBegin; 62e113a28aSBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 634f572ea9SToby Isaac PetscAssertPointer(flag, 2); 64e113a28aSBarry Smith *flag = snes->errorifnotconverged; 653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 66e113a28aSBarry Smith } 67e113a28aSBarry Smith 684fc747eaSLawrence Mitchell /*@ 69dc4c0fb0SBarry Smith SNESSetAlwaysComputesFinalResidual - tells the `SNES` to always compute the residual (nonlinear function value) at the final solution 704fc747eaSLawrence Mitchell 71c3339decSBarry Smith Logically Collective 724fc747eaSLawrence Mitchell 734fc747eaSLawrence Mitchell Input Parameters: 74f6dfbefdSBarry Smith + snes - the shell `SNES` 75f6dfbefdSBarry Smith - flg - `PETSC_TRUE` to always compute the residual 764fc747eaSLawrence Mitchell 774fc747eaSLawrence Mitchell Level: advanced 784fc747eaSLawrence Mitchell 79f6dfbefdSBarry Smith Note: 80f6dfbefdSBarry Smith Some solvers (such as smoothers in a `SNESFAS`) do not need the residual computed at the final solution so skip computing it 81f6dfbefdSBarry Smith to save time. 82f6dfbefdSBarry Smith 831cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESGetAlwaysComputesFinalResidual()` 844fc747eaSLawrence Mitchell @*/ 85d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetAlwaysComputesFinalResidual(SNES snes, PetscBool flg) 86d71ae5a4SJacob Faibussowitsch { 874fc747eaSLawrence Mitchell PetscFunctionBegin; 884fc747eaSLawrence Mitchell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 894fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = flg; 903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 914fc747eaSLawrence Mitchell } 924fc747eaSLawrence Mitchell 934fc747eaSLawrence Mitchell /*@ 94f6dfbefdSBarry Smith SNESGetAlwaysComputesFinalResidual - checks if the `SNES` always computes the residual at the final solution 954fc747eaSLawrence Mitchell 96c3339decSBarry Smith Logically Collective 974fc747eaSLawrence Mitchell 984fc747eaSLawrence Mitchell Input Parameter: 99f6dfbefdSBarry Smith . snes - the `SNES` context 1004fc747eaSLawrence Mitchell 1014fc747eaSLawrence Mitchell Output Parameter: 102f6dfbefdSBarry Smith . flg - `PETSC_TRUE` if the residual is computed 1034fc747eaSLawrence Mitchell 1044fc747eaSLawrence Mitchell Level: advanced 1054fc747eaSLawrence Mitchell 1061cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetAlwaysComputesFinalResidual()` 1074fc747eaSLawrence Mitchell @*/ 108d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetAlwaysComputesFinalResidual(SNES snes, PetscBool *flg) 109d71ae5a4SJacob Faibussowitsch { 1104fc747eaSLawrence Mitchell PetscFunctionBegin; 1114fc747eaSLawrence Mitchell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1124fc747eaSLawrence Mitchell *flg = snes->alwayscomputesfinalresidual; 1133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1144fc747eaSLawrence Mitchell } 1154fc747eaSLawrence Mitchell 116e725d27bSBarry Smith /*@ 117f6dfbefdSBarry Smith SNESSetFunctionDomainError - tells `SNES` that the input vector, a proposed new solution, to your function you provided to `SNESSetFunction()` is not 118f0b84518SBarry Smith in the functions domain. For example, a step with negative pressure. 1194936397dSBarry Smith 120c3339decSBarry Smith Logically Collective 1214936397dSBarry Smith 1222fe279fdSBarry Smith Input Parameter: 123f6dfbefdSBarry Smith . snes - the `SNES` context 1244936397dSBarry Smith 12528529972SSatish Balay Level: advanced 1264936397dSBarry Smith 127ced0f3aeSBarry Smith Notes: 128ced0f3aeSBarry Smith If this is called the `SNESSolve()` stops iterating and returns with a `SNESConvergedReason` of `SNES_DIVERGED_FUNCTION_DOMAIN` 129ced0f3aeSBarry Smith 130ced0f3aeSBarry Smith You should always call `SNESGetConvergedReason()` after each `SNESSolve()` and verify if the iteration converged (positive result) or diverged (negative result). 131ced0f3aeSBarry Smith 132f0b84518SBarry Smith You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or 133f0b84518SBarry Smith `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 134f0b84518SBarry Smith 1351cc06b55SBarry Smith .seealso: [](ch_snes), `SNESCreate()`, `SNESSetFunction()`, `SNESFunction`, `SNESSetJacobianDomainError()`, `SNESVISetVariableBounds()`, 136ced0f3aeSBarry Smith `SNESVISetComputeVariableBounds()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESConvergedReason`, `SNESGetConvergedReason()` 1374936397dSBarry Smith @*/ 138d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunctionDomainError(SNES snes) 139d71ae5a4SJacob Faibussowitsch { 1404936397dSBarry Smith PetscFunctionBegin; 1410700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1425f80ce2aSJacob Faibussowitsch PetscCheck(!snes->errorifnotconverged, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "User code indicates input vector is not in the function domain"); 1434936397dSBarry Smith snes->domainerror = PETSC_TRUE; 1443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1454936397dSBarry Smith } 1464936397dSBarry Smith 1476a388c36SPeter Brune /*@ 148f6dfbefdSBarry Smith SNESSetJacobianDomainError - tells `SNES` that the function you provided to `SNESSetJacobian()` at the proposed step. For example there is a negative element transformation. 14907b62357SFande Kong 150c3339decSBarry Smith Logically Collective 15107b62357SFande Kong 1522fe279fdSBarry Smith Input Parameter: 153f6dfbefdSBarry Smith . snes - the `SNES` context 15407b62357SFande Kong 15507b62357SFande Kong Level: advanced 15607b62357SFande Kong 157ced0f3aeSBarry Smith Notes: 158ced0f3aeSBarry Smith If this is called the `SNESSolve()` stops iterating and returns with a `SNESConvergedReason` of `SNES_DIVERGED_FUNCTION_DOMAIN` 159ced0f3aeSBarry Smith 160ced0f3aeSBarry Smith You should always call `SNESGetConvergedReason()` after each `SNESSolve()` and verify if the iteration converged (positive result) or diverged (negative result). 161ced0f3aeSBarry Smith 162f0b84518SBarry Smith You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or 163f0b84518SBarry Smith `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 164f0b84518SBarry Smith 1651cc06b55SBarry Smith .seealso: [](ch_snes), `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESVISetVariableBounds()`, 166ced0f3aeSBarry Smith `SNESVISetComputeVariableBounds()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESConvergedReason`, `SNESGetConvergedReason()` 16707b62357SFande Kong @*/ 168d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetJacobianDomainError(SNES snes) 169d71ae5a4SJacob Faibussowitsch { 17007b62357SFande Kong PetscFunctionBegin; 17107b62357SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1725f80ce2aSJacob Faibussowitsch PetscCheck(!snes->errorifnotconverged, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "User code indicates computeJacobian does not make sense"); 17307b62357SFande Kong snes->jacobiandomainerror = PETSC_TRUE; 1743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17507b62357SFande Kong } 17607b62357SFande Kong 17707b62357SFande Kong /*@ 178f6dfbefdSBarry Smith SNESSetCheckJacobianDomainError - tells `SNESSolve()` whether to check if the user called `SNESSetJacobianDomainError()` Jacobian domain error after 179f6dfbefdSBarry Smith each Jacobian evaluation. By default, we check Jacobian domain error in the debug mode, and do not check it in the optimized mode. 180b351a90bSFande Kong 181c3339decSBarry Smith Logically Collective 182b351a90bSFande Kong 183b351a90bSFande Kong Input Parameters: 18420f4b53cSBarry Smith + snes - the `SNES` context 185f6dfbefdSBarry Smith - flg - indicates if or not to check Jacobian domain error after each Jacobian evaluation 186b351a90bSFande Kong 187b351a90bSFande Kong Level: advanced 188b351a90bSFande Kong 189f6dfbefdSBarry Smith Note: 190f6dfbefdSBarry Smith Checks require one extra parallel synchronization for each Jacobian evaluation 191f6dfbefdSBarry Smith 1921cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESConvergedReason`, `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESGetCheckJacobianDomainError()` 193b351a90bSFande Kong @*/ 194d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetCheckJacobianDomainError(SNES snes, PetscBool flg) 195d71ae5a4SJacob Faibussowitsch { 196b351a90bSFande Kong PetscFunctionBegin; 197b351a90bSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 198b351a90bSFande Kong snes->checkjacdomainerror = flg; 1993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 200b351a90bSFande Kong } 201b351a90bSFande Kong 202b351a90bSFande Kong /*@ 2038383d7d7SFande Kong SNESGetCheckJacobianDomainError - Get an indicator whether or not we are checking Jacobian domain errors after each Jacobian evaluation. 2048383d7d7SFande Kong 205c3339decSBarry Smith Logically Collective 2068383d7d7SFande Kong 2072fe279fdSBarry Smith Input Parameter: 208f6dfbefdSBarry Smith . snes - the `SNES` context 2098383d7d7SFande Kong 2102fe279fdSBarry Smith Output Parameter: 211f6dfbefdSBarry Smith . flg - `PETSC_FALSE` indicates that we don't check Jacobian domain errors after each Jacobian evaluation 2128383d7d7SFande Kong 2138383d7d7SFande Kong Level: advanced 2148383d7d7SFande Kong 2151cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESSetCheckJacobianDomainError()` 2168383d7d7SFande Kong @*/ 217d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetCheckJacobianDomainError(SNES snes, PetscBool *flg) 218d71ae5a4SJacob Faibussowitsch { 2198383d7d7SFande Kong PetscFunctionBegin; 2208383d7d7SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2214f572ea9SToby Isaac PetscAssertPointer(flg, 2); 2228383d7d7SFande Kong *flg = snes->checkjacdomainerror; 2233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2248383d7d7SFande Kong } 2258383d7d7SFande Kong 2268383d7d7SFande Kong /*@ 227f6dfbefdSBarry Smith SNESGetFunctionDomainError - Gets the status of the domain error after a call to `SNESComputeFunction()`; 2286a388c36SPeter Brune 229f6dfbefdSBarry Smith Logically Collective 2306a388c36SPeter Brune 2312fe279fdSBarry Smith Input Parameter: 232f6dfbefdSBarry Smith . snes - the `SNES` context 2336a388c36SPeter Brune 2342fe279fdSBarry Smith Output Parameter: 235f6dfbefdSBarry Smith . domainerror - Set to `PETSC_TRUE` if there's a domain error; `PETSC_FALSE` otherwise. 2366a388c36SPeter Brune 237f6dfbefdSBarry Smith Level: developer 2386a388c36SPeter Brune 2391cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetFunctionDomainError()`, `SNESComputeFunction()` 2406a388c36SPeter Brune @*/ 241d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 242d71ae5a4SJacob Faibussowitsch { 2436a388c36SPeter Brune PetscFunctionBegin; 2446a388c36SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2454f572ea9SToby Isaac PetscAssertPointer(domainerror, 2); 2466a388c36SPeter Brune *domainerror = snes->domainerror; 2473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2486a388c36SPeter Brune } 2496a388c36SPeter Brune 25007b62357SFande Kong /*@ 251f6dfbefdSBarry Smith SNESGetJacobianDomainError - Gets the status of the Jacobian domain error after a call to `SNESComputeJacobian()`; 25207b62357SFande Kong 253c3339decSBarry Smith Logically Collective 25407b62357SFande Kong 2552fe279fdSBarry Smith Input Parameter: 256f6dfbefdSBarry Smith . snes - the `SNES` context 25707b62357SFande Kong 2582fe279fdSBarry Smith Output Parameter: 259f6dfbefdSBarry Smith . domainerror - Set to `PETSC_TRUE` if there's a Jacobian domain error; `PETSC_FALSE` otherwise. 26007b62357SFande Kong 26107b62357SFande Kong Level: advanced 26207b62357SFande Kong 2631cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetFunctionDomainError()`, `SNESComputeFunction()`, `SNESGetFunctionDomainError()` 26407b62357SFande Kong @*/ 265d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetJacobianDomainError(SNES snes, PetscBool *domainerror) 266d71ae5a4SJacob Faibussowitsch { 26707b62357SFande Kong PetscFunctionBegin; 26807b62357SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2694f572ea9SToby Isaac PetscAssertPointer(domainerror, 2); 27007b62357SFande Kong *domainerror = snes->jacobiandomainerror; 2713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27207b62357SFande Kong } 27307b62357SFande Kong 27455849f57SBarry Smith /*@C 275f6dfbefdSBarry Smith SNESLoad - Loads a `SNES` that has been stored in `PETSCVIEWERBINARY` with `SNESView()`. 27655849f57SBarry Smith 277c3339decSBarry Smith Collective 27855849f57SBarry Smith 27955849f57SBarry Smith Input Parameters: 280e4094ef1SJacob Faibussowitsch + snes - the newly loaded `SNES`, this needs to have been created with `SNESCreate()` or 281f6dfbefdSBarry Smith some related function before a call to `SNESLoad()`. 282f6dfbefdSBarry Smith - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` 28355849f57SBarry Smith 28455849f57SBarry Smith Level: intermediate 28555849f57SBarry Smith 286f6dfbefdSBarry Smith Note: 287f6dfbefdSBarry Smith The type is determined by the data in the file, any type set into the `SNES` before this call is ignored. 28855849f57SBarry Smith 2891cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `PetscViewer`, `SNESCreate()`, `SNESType`, `PetscViewerBinaryOpen()`, `SNESView()`, `MatLoad()`, `VecLoad()` 29055849f57SBarry Smith @*/ 291d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLoad(SNES snes, PetscViewer viewer) 292d71ae5a4SJacob Faibussowitsch { 29355849f57SBarry Smith PetscBool isbinary; 294060da220SMatthew G. Knepley PetscInt classid; 29555849f57SBarry Smith char type[256]; 29655849f57SBarry Smith KSP ksp; 2972d53ad75SBarry Smith DM dm; 2982d53ad75SBarry Smith DMSNES dmsnes; 29955849f57SBarry Smith 30055849f57SBarry Smith PetscFunctionBegin; 3012d53ad75SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 30255849f57SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 3039566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 3045f80ce2aSJacob Faibussowitsch PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 30555849f57SBarry Smith 3069566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, &classid, 1, NULL, PETSC_INT)); 3075f80ce2aSJacob Faibussowitsch PetscCheck(classid == SNES_FILE_CLASSID, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONG, "Not SNES next in file"); 3089566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, type, 256, NULL, PETSC_CHAR)); 3099566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, type)); 310dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, load, viewer); 3119566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 3129566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &dmsnes)); 3139566063dSJacob Faibussowitsch PetscCall(DMSNESLoad(dmsnes, viewer)); 3149566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 3159566063dSJacob Faibussowitsch PetscCall(KSPLoad(ksp, viewer)); 3163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 31755849f57SBarry Smith } 3186a388c36SPeter Brune 3199804daf3SBarry Smith #include <petscdraw.h> 320e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 321e04113cfSBarry Smith #include <petscviewersaws.h> 322bfb97211SBarry Smith #endif 3238404b7f3SBarry Smith 324fe2efc57SMark /*@C 325dc4c0fb0SBarry Smith SNESViewFromOptions - View a `SNES` based on values in the options database 326fe2efc57SMark 327c3339decSBarry Smith Collective 328fe2efc57SMark 329fe2efc57SMark Input Parameters: 330f6dfbefdSBarry Smith + A - the `SNES` context 331dc4c0fb0SBarry Smith . obj - Optional object that provides the options prefix for the checks 332736c3998SJose E. Roman - name - command line option 333fe2efc57SMark 334fe2efc57SMark Level: intermediate 335f6dfbefdSBarry Smith 3361cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESView`, `PetscObjectViewFromOptions()`, `SNESCreate()` 337fe2efc57SMark @*/ 338d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESViewFromOptions(SNES A, PetscObject obj, const char name[]) 339d71ae5a4SJacob Faibussowitsch { 340fe2efc57SMark PetscFunctionBegin; 341fe2efc57SMark PetscValidHeaderSpecific(A, SNES_CLASSID, 1); 3429566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 3433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 344fe2efc57SMark } 345fe2efc57SMark 346789d8953SBarry Smith PETSC_EXTERN PetscErrorCode SNESComputeJacobian_DMDA(SNES, Vec, Mat, Mat, void *); 347789d8953SBarry Smith 3487e2c5f70SBarry Smith /*@C 349dc4c0fb0SBarry Smith SNESView - Prints or visualizes the `SNES` data structure. 3509b94acceSBarry Smith 351c3339decSBarry Smith Collective 352fee21e36SBarry Smith 353c7afd0dbSLois Curfman McInnes Input Parameters: 354f6dfbefdSBarry Smith + snes - the `SNES` context 355f6dfbefdSBarry Smith - viewer - the `PetscViewer` 356c7afd0dbSLois Curfman McInnes 3579b94acceSBarry Smith Options Database Key: 358f6dfbefdSBarry Smith . -snes_view - Calls `SNESView()` at end of `SNESSolve()` 3599b94acceSBarry Smith 360dc4c0fb0SBarry Smith Level: beginner 361dc4c0fb0SBarry Smith 3629b94acceSBarry Smith Notes: 3639b94acceSBarry Smith The available visualization contexts include 364f6dfbefdSBarry Smith + `PETSC_VIEWER_STDOUT_SELF` - standard output (default) 365f6dfbefdSBarry Smith - `PETSC_VIEWER_STDOUT_WORLD` - synchronized standard 366c8a8ba5cSLois Curfman McInnes output where only the first processor opens 367c8a8ba5cSLois Curfman McInnes the file. All other processors send their 368c8a8ba5cSLois Curfman McInnes data to the first processor to print. 3699b94acceSBarry Smith 370052bf0daSPierre Jolivet The available formats include 371f6dfbefdSBarry Smith + `PETSC_VIEWER_DEFAULT` - standard output (default) 372f6dfbefdSBarry Smith - `PETSC_VIEWER_ASCII_INFO_DETAIL` - more verbose output for `SNESNASM` 373052bf0daSPierre Jolivet 3743e081fefSLois Curfman McInnes The user can open an alternative visualization context with 375f6dfbefdSBarry Smith `PetscViewerASCIIOpen()` - output to a specified file. 3769b94acceSBarry Smith 377f6dfbefdSBarry Smith In the debugger you can do "call `SNESView`(snes,0)" to display the `SNES` solver. (The same holds for any PETSc object viewer). 378595c91d4SBarry Smith 3791cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLoad()`, `SNESCreate()`, `PetscViewerASCIIOpen()` 3809b94acceSBarry Smith @*/ 381d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESView(SNES snes, PetscViewer viewer) 382d71ae5a4SJacob Faibussowitsch { 383fa9f3622SBarry Smith SNESKSPEW *kctx; 38494b7f48cSBarry Smith KSP ksp; 3857f1410a3SPeter Brune SNESLineSearch linesearch; 38672a02f06SBarry Smith PetscBool iascii, isstring, isbinary, isdraw; 3872d53ad75SBarry Smith DMSNES dmsnes; 388e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 389536b137fSBarry Smith PetscBool issaws; 390bfb97211SBarry Smith #endif 3919b94acceSBarry Smith 3923a40ed3dSBarry Smith PetscFunctionBegin; 3930700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 39448a46eb9SPierre Jolivet if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &viewer)); 3950700a824SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 396c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, viewer, 2); 39774679c65SBarry Smith 3989566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 3999566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring)); 4009566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 4019566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 402e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 4039566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws)); 404bfb97211SBarry Smith #endif 40532077d6dSBarry Smith if (iascii) { 406dc0571f2SMatthew G. Knepley SNESNormSchedule normschedule; 4078404b7f3SBarry Smith DM dm; 4088404b7f3SBarry Smith PetscErrorCode (*cJ)(SNES, Vec, Mat, Mat, void *); 4098404b7f3SBarry Smith void *ctx; 410789d8953SBarry Smith const char *pre = ""; 411dc0571f2SMatthew G. Knepley 4129566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)snes, viewer)); 41348a46eb9SPierre Jolivet if (!snes->setupcalled) PetscCall(PetscViewerASCIIPrintf(viewer, " SNES has not been set up so information may be incomplete\n")); 414e7788613SBarry Smith if (snes->ops->view) { 4159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 416dbbe0bcdSBarry Smith PetscUseTypeMethod(snes, view, viewer); 4179566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 4180ef38995SBarry Smith } 41963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " maximum iterations=%" PetscInt_FMT ", maximum function evaluations=%" PetscInt_FMT "\n", snes->max_its, snes->max_funcs)); 4209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " tolerances: relative=%g, absolute=%g, solution=%g\n", (double)snes->rtol, (double)snes->abstol, (double)snes->stol)); 42148a46eb9SPierre Jolivet if (snes->usesksp) PetscCall(PetscViewerASCIIPrintf(viewer, " total number of linear solver iterations=%" PetscInt_FMT "\n", snes->linear_its)); 42263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " total number of function evaluations=%" PetscInt_FMT "\n", snes->nfuncs)); 4239566063dSJacob Faibussowitsch PetscCall(SNESGetNormSchedule(snes, &normschedule)); 4249566063dSJacob Faibussowitsch if (normschedule > 0) PetscCall(PetscViewerASCIIPrintf(viewer, " norm schedule %s\n", SNESNormSchedules[normschedule])); 42548a46eb9SPierre Jolivet if (snes->gridsequence) PetscCall(PetscViewerASCIIPrintf(viewer, " total number of grid sequence refinements=%" PetscInt_FMT "\n", snes->gridsequence)); 4269b94acceSBarry Smith if (snes->ksp_ewconv) { 427fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 4289b94acceSBarry Smith if (kctx) { 42963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Eisenstat-Walker computation of KSP relative tolerance (version %" PetscInt_FMT ")\n", kctx->version)); 4309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " rtol_0=%g, rtol_max=%g, threshold=%g\n", (double)kctx->rtol_0, (double)kctx->rtol_max, (double)kctx->threshold)); 4319566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " gamma=%g, alpha=%g, alpha2=%g\n", (double)kctx->gamma, (double)kctx->alpha, (double)kctx->alpha2)); 4329b94acceSBarry Smith } 4339b94acceSBarry Smith } 434eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 4359566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Preconditioned is never rebuilt\n")); 436eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 43763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Preconditioned is rebuilt every %" PetscInt_FMT " new Jacobians\n", snes->lagpreconditioner)); 438eb1f6c34SBarry Smith } 439eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 4409566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is never rebuilt\n")); 441eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 44263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is rebuilt every %" PetscInt_FMT " SNES iterations\n", snes->lagjacobian)); 443eb1f6c34SBarry Smith } 4449566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 4459566063dSJacob Faibussowitsch PetscCall(DMSNESGetJacobian(dm, &cJ, &ctx)); 446789d8953SBarry Smith if (snes->mf_operator) { 4479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is applied matrix-free with differencing\n")); 448789d8953SBarry Smith pre = "Preconditioning "; 449789d8953SBarry Smith } 4508404b7f3SBarry Smith if (cJ == SNESComputeJacobianDefault) { 4519566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using finite differences one column at a time\n", pre)); 4528404b7f3SBarry Smith } else if (cJ == SNESComputeJacobianDefaultColor) { 4539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using finite differences with coloring\n", pre)); 454789d8953SBarry Smith /* it slightly breaks data encapsulation for access the DMDA information directly */ 455789d8953SBarry Smith } else if (cJ == SNESComputeJacobian_DMDA) { 456789d8953SBarry Smith MatFDColoring fdcoloring; 4579566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)dm, "DMDASNES_FDCOLORING", (PetscObject *)&fdcoloring)); 458789d8953SBarry Smith if (fdcoloring) { 4599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using colored finite differences on a DMDA\n", pre)); 460789d8953SBarry Smith } else { 4619566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using a DMDA local Jacobian\n", pre)); 462789d8953SBarry Smith } 463996e1cbcSBarry Smith } else if (snes->mf && !snes->mf_operator) { 4649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is applied matrix-free with differencing, no explicit Jacobian\n")); 4658404b7f3SBarry Smith } 4660f5bd95cSBarry Smith } else if (isstring) { 467317d6ea6SBarry Smith const char *type; 4689566063dSJacob Faibussowitsch PetscCall(SNESGetType(snes, &type)); 4699566063dSJacob Faibussowitsch PetscCall(PetscViewerStringSPrintf(viewer, " SNESType: %-7.7s", type)); 470dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, view, viewer); 47155849f57SBarry Smith } else if (isbinary) { 47255849f57SBarry Smith PetscInt classid = SNES_FILE_CLASSID; 47355849f57SBarry Smith MPI_Comm comm; 47455849f57SBarry Smith PetscMPIInt rank; 47555849f57SBarry Smith char type[256]; 47655849f57SBarry Smith 4779566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)snes, &comm)); 4789566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 479dd400576SPatrick Sanan if (rank == 0) { 4809566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(viewer, &classid, 1, PETSC_INT)); 4819566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(type, ((PetscObject)snes)->type_name, sizeof(type))); 4829566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(viewer, type, sizeof(type), PETSC_CHAR)); 48355849f57SBarry Smith } 484dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, view, viewer); 48572a02f06SBarry Smith } else if (isdraw) { 48672a02f06SBarry Smith PetscDraw draw; 48772a02f06SBarry Smith char str[36]; 48889fd9fafSBarry Smith PetscReal x, y, bottom, h; 48972a02f06SBarry Smith 4909566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 4919566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCurrentPoint(draw, &x, &y)); 4929566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(str, "SNES: ", sizeof(str))); 4939566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(str, ((PetscObject)snes)->type_name, sizeof(str))); 4949566063dSJacob Faibussowitsch PetscCall(PetscDrawStringBoxed(draw, x, y, PETSC_DRAW_BLUE, PETSC_DRAW_BLACK, str, NULL, &h)); 49589fd9fafSBarry Smith bottom = y - h; 4969566063dSJacob Faibussowitsch PetscCall(PetscDrawPushCurrentPoint(draw, x, bottom)); 497dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, view, viewer); 498e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 499536b137fSBarry Smith } else if (issaws) { 500d45a07a7SBarry Smith PetscMPIInt rank; 5012657e9d9SBarry Smith const char *name; 502d45a07a7SBarry Smith 5039566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)snes, &name)); 5049566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 505dd400576SPatrick Sanan if (!((PetscObject)snes)->amsmem && rank == 0) { 506d45a07a7SBarry Smith char dir[1024]; 507d45a07a7SBarry Smith 5089566063dSJacob Faibussowitsch PetscCall(PetscObjectViewSAWs((PetscObject)snes, viewer)); 5099566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/its", name)); 510792fecdfSBarry Smith PetscCallSAWs(SAWs_Register, (dir, &snes->iter, 1, SAWs_READ, SAWs_INT)); 51148a46eb9SPierre Jolivet if (!snes->conv_hist) PetscCall(SNESSetConvergenceHistory(snes, NULL, NULL, PETSC_DECIDE, PETSC_TRUE)); 5129566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/conv_hist", name)); 513792fecdfSBarry Smith PetscCallSAWs(SAWs_Register, (dir, snes->conv_hist, 10, SAWs_READ, SAWs_DOUBLE)); 514f05ece33SBarry Smith } 515bfb97211SBarry Smith #endif 51672a02f06SBarry Smith } 51772a02f06SBarry Smith if (snes->linesearch) { 5189566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 5199566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5209566063dSJacob Faibussowitsch PetscCall(SNESLineSearchView(linesearch, viewer)); 5219566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 52219bcc07fSBarry Smith } 523efd4aadfSBarry Smith if (snes->npc && snes->usesnpc) { 5249566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5259566063dSJacob Faibussowitsch PetscCall(SNESView(snes->npc, viewer)); 5269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5274a0c5b0cSMatthew G Knepley } 5289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5299566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &dmsnes)); 5309566063dSJacob Faibussowitsch PetscCall(DMSNESView(dmsnes, viewer)); 5319566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5322c155ee1SBarry Smith if (snes->usesksp) { 5339566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 5349566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5359566063dSJacob Faibussowitsch PetscCall(KSPView(ksp, viewer)); 5369566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5372c155ee1SBarry Smith } 53872a02f06SBarry Smith if (isdraw) { 53972a02f06SBarry Smith PetscDraw draw; 5409566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 5419566063dSJacob Faibussowitsch PetscCall(PetscDrawPopCurrentPoint(draw)); 5427f1410a3SPeter Brune } 5433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5449b94acceSBarry Smith } 5459b94acceSBarry Smith 54676b2cf59SMatthew Knepley /* 54776b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 54876b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 54976b2cf59SMatthew Knepley */ 55076b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 551a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 5526849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 55376b2cf59SMatthew Knepley 554ac226902SBarry Smith /*@C 555f6dfbefdSBarry Smith SNESAddOptionsChecker - Adds an additional function to check for `SNES` options. 55676b2cf59SMatthew Knepley 55776b2cf59SMatthew Knepley Not Collective 55876b2cf59SMatthew Knepley 55976b2cf59SMatthew Knepley Input Parameter: 56076b2cf59SMatthew Knepley . snescheck - function that checks for options 56176b2cf59SMatthew Knepley 56276b2cf59SMatthew Knepley Level: developer 56376b2cf59SMatthew Knepley 5641cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetFromOptions()` 56576b2cf59SMatthew Knepley @*/ 566d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 567d71ae5a4SJacob Faibussowitsch { 56876b2cf59SMatthew Knepley PetscFunctionBegin; 56963a3b9bcSJacob Faibussowitsch PetscCheck(numberofsetfromoptions < MAXSETFROMOPTIONS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %d allowed", MAXSETFROMOPTIONS); 57076b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 5713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 57276b2cf59SMatthew Knepley } 57376b2cf59SMatthew Knepley 574d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 575d71ae5a4SJacob Faibussowitsch { 576aa3661deSLisandro Dalcin Mat J; 577895c21f2SBarry Smith MatNullSpace nullsp; 578aa3661deSLisandro Dalcin 579aa3661deSLisandro Dalcin PetscFunctionBegin; 5800700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 581aa3661deSLisandro Dalcin 58298613b67SLisandro Dalcin if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 58398613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 5849566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A ? A : B, NULL, &snes->vec_func)); 58598613b67SLisandro Dalcin } 58698613b67SLisandro Dalcin 5870fdf79fbSJacob Faibussowitsch PetscCheck(version == 1 || version == 2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator routines, only version 1 and 2"); 588aa3661deSLisandro Dalcin if (version == 1) { 5899566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes, &J)); 5909566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix)); 5919566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 5921e2ae407SBarry Smith /* TODO: the version 2 code should be merged into the MatCreateSNESMF() and MatCreateMFFD() infrastructure and then removed */ 5930fdf79fbSJacob Faibussowitsch } else /* if (version == 2) */ { 5945f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_func, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "SNESSetFunction() must be called first"); 595570b7f6dSBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16) 596f6dfbefdSBarry Smith PetscCall(MatCreateSNESMFMore(snes, snes->vec_func, &J)); 597aa3661deSLisandro Dalcin #else 5982479783cSJose E. Roman SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "matrix-free operator routines (version 2)"); 599aa3661deSLisandro Dalcin #endif 6000fdf79fbSJacob Faibussowitsch } 601aa3661deSLisandro Dalcin 60201c1178eSBarry Smith /* attach any user provided null space that was on Amat to the newly created matrix-free matrix */ 603895c21f2SBarry Smith if (snes->jacobian) { 6049566063dSJacob Faibussowitsch PetscCall(MatGetNullSpace(snes->jacobian, &nullsp)); 6051baa6e33SBarry Smith if (nullsp) PetscCall(MatSetNullSpace(J, nullsp)); 606895c21f2SBarry Smith } 607895c21f2SBarry Smith 60863a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default matrix-free operator routines (version %" PetscInt_FMT ")\n", version)); 609d3462f78SMatthew Knepley if (hasOperator) { 610aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 611aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 6129566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, NULL, NULL, NULL)); 613aa3661deSLisandro Dalcin } else { 614aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 61501c1178eSBarry Smith provided preconditioner Jacobian with the default matrix-free version. */ 616b552625fSStefano Zampini if (snes->npcside == PC_LEFT && snes->npc) { 6179566063dSJacob Faibussowitsch if (!snes->jacobian) PetscCall(SNESSetJacobian(snes, J, NULL, NULL, NULL)); 618172a4300SPeter Brune } else { 619789d8953SBarry Smith KSP ksp; 620789d8953SBarry Smith PC pc; 621789d8953SBarry Smith PetscBool match; 622789d8953SBarry Smith 6239566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, J, MatMFFDComputeJacobian, NULL)); 624aa3661deSLisandro Dalcin /* Force no preconditioner */ 6259566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 6269566063dSJacob Faibussowitsch PetscCall(KSPGetPC(ksp, &pc)); 6272698c518SLisandro Dalcin PetscCall(PetscObjectTypeCompareAny((PetscObject)pc, &match, PCSHELL, PCH2OPUS, "")); 628aa3661deSLisandro Dalcin if (!match) { 6299566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n")); 6309566063dSJacob Faibussowitsch PetscCall(PCSetType(pc, PCNONE)); 631aa3661deSLisandro Dalcin } 632aa3661deSLisandro Dalcin } 633789d8953SBarry Smith } 6349566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 6353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 636aa3661deSLisandro Dalcin } 637aa3661deSLisandro Dalcin 638d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine, Mat Restrict, Vec Rscale, Mat Inject, DM dmcoarse, void *ctx) 639d71ae5a4SJacob Faibussowitsch { 640dfe15315SJed Brown SNES snes = (SNES)ctx; 6410298fd71SBarry Smith Vec Xfine, Xfine_named = NULL, Xcoarse; 642dfe15315SJed Brown 643dfe15315SJed Brown PetscFunctionBegin; 64416ebb321SJed Brown if (PetscLogPrintInfo) { 64516ebb321SJed Brown PetscInt finelevel, coarselevel, fineclevel, coarseclevel; 6469566063dSJacob Faibussowitsch PetscCall(DMGetRefineLevel(dmfine, &finelevel)); 6479566063dSJacob Faibussowitsch PetscCall(DMGetCoarsenLevel(dmfine, &fineclevel)); 6489566063dSJacob Faibussowitsch PetscCall(DMGetRefineLevel(dmcoarse, &coarselevel)); 6499566063dSJacob Faibussowitsch PetscCall(DMGetCoarsenLevel(dmcoarse, &coarseclevel)); 65063a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(dmfine, "Restricting SNES solution vector from level %" PetscInt_FMT "-%" PetscInt_FMT " to level %" PetscInt_FMT "-%" PetscInt_FMT "\n", finelevel, fineclevel, coarselevel, coarseclevel)); 65116ebb321SJed Brown } 652dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 653dfe15315SJed Brown else { 6549566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dmfine, "SNESVecSol", &Xfine_named)); 655dfe15315SJed Brown Xfine = Xfine_named; 656dfe15315SJed Brown } 6579566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dmcoarse, "SNESVecSol", &Xcoarse)); 658907f5c5aSLawrence Mitchell if (Inject) { 6599566063dSJacob Faibussowitsch PetscCall(MatRestrict(Inject, Xfine, Xcoarse)); 660907f5c5aSLawrence Mitchell } else { 6619566063dSJacob Faibussowitsch PetscCall(MatRestrict(Restrict, Xfine, Xcoarse)); 6629566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(Xcoarse, Xcoarse, Rscale)); 663907f5c5aSLawrence Mitchell } 6649566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedGlobalVector(dmcoarse, "SNESVecSol", &Xcoarse)); 6659566063dSJacob Faibussowitsch if (Xfine_named) PetscCall(DMRestoreNamedGlobalVector(dmfine, "SNESVecSol", &Xfine_named)); 6663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 667dfe15315SJed Brown } 668dfe15315SJed Brown 669d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm, DM dmc, void *ctx) 670d71ae5a4SJacob Faibussowitsch { 67116ebb321SJed Brown PetscFunctionBegin; 6729566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(dmc, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, ctx)); 6733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 67416ebb321SJed Brown } 67516ebb321SJed Brown 676a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 677a6950cb2SJed Brown * safely call SNESGetDM() in their residual evaluation routine. */ 678d71ae5a4SJacob Faibussowitsch static PetscErrorCode KSPComputeOperators_SNES(KSP ksp, Mat A, Mat B, void *ctx) 679d71ae5a4SJacob Faibussowitsch { 680caa4e7f2SJed Brown SNES snes = (SNES)ctx; 6810298fd71SBarry Smith Vec X, Xnamed = NULL; 682dfe15315SJed Brown DM dmsave; 6834e269d77SPeter Brune void *ctxsave; 68425ce1634SJed Brown PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *) = NULL; 685caa4e7f2SJed Brown 686caa4e7f2SJed Brown PetscFunctionBegin; 687dfe15315SJed Brown dmsave = snes->dm; 6889566063dSJacob Faibussowitsch PetscCall(KSPGetDM(ksp, &snes->dm)); 689dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 6909371c9d4SSatish Balay else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ PetscCall(DMGetNamedGlobalVector(snes->dm, "SNESVecSol", &Xnamed)); 691dfe15315SJed Brown X = Xnamed; 6929566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, NULL, NULL, &jac, &ctxsave)); 6934e269d77SPeter Brune /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */ 69448a46eb9SPierre Jolivet if (jac == SNESComputeJacobianDefaultColor) PetscCall(SNESSetJacobian(snes, NULL, NULL, SNESComputeJacobianDefaultColor, NULL)); 6954e269d77SPeter Brune } 6964dde8bb0SMatthew G. Knepley /* Make sure KSP DM has the Jacobian computation routine */ 6974dde8bb0SMatthew G. Knepley { 6984dde8bb0SMatthew G. Knepley DMSNES sdm; 6994e269d77SPeter Brune 7009566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &sdm)); 70148a46eb9SPierre Jolivet if (!sdm->ops->computejacobian) PetscCall(DMCopyDMSNES(dmsave, snes->dm)); 7024dde8bb0SMatthew G. Knepley } 7032b93b426SMatthew G. Knepley /* Compute the operators */ 7049566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobian(snes, X, A, B)); 7052b93b426SMatthew G. Knepley /* Put the previous context back */ 70648a46eb9SPierre Jolivet if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) PetscCall(SNESSetJacobian(snes, NULL, NULL, jac, ctxsave)); 7074e269d77SPeter Brune 7089566063dSJacob Faibussowitsch if (Xnamed) PetscCall(DMRestoreNamedGlobalVector(snes->dm, "SNESVecSol", &Xnamed)); 709dfe15315SJed Brown snes->dm = dmsave; 7103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 711caa4e7f2SJed Brown } 712caa4e7f2SJed Brown 7136cab3a1bSJed Brown /*@ 714dc4c0fb0SBarry Smith SNESSetUpMatrices - ensures that matrices are available for `SNES` Newton-like methods, this is called by `SNESSetUp_XXX()` 7156cab3a1bSJed Brown 7166cab3a1bSJed Brown Collective 7176cab3a1bSJed Brown 7184165533cSJose E. Roman Input Parameter: 71920f4b53cSBarry Smith . snes - `SNES` object to configure 7206cab3a1bSJed Brown 7216cab3a1bSJed Brown Level: developer 7226cab3a1bSJed Brown 723dc4c0fb0SBarry Smith Note: 724dc4c0fb0SBarry Smith If the matrices do not yet exist it attempts to create them based on options previously set for the `SNES` such as `-snes_mf` 725dc4c0fb0SBarry Smith 7261cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetUp()` 7276cab3a1bSJed Brown @*/ 728d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUpMatrices(SNES snes) 729d71ae5a4SJacob Faibussowitsch { 7306cab3a1bSJed Brown DM dm; 731942e3340SBarry Smith DMSNES sdm; 7326cab3a1bSJed Brown 7336cab3a1bSJed Brown PetscFunctionBegin; 7349566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 7359566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 73658b371f3SBarry Smith if (!snes->jacobian && snes->mf) { 7376cab3a1bSJed Brown Mat J; 7386cab3a1bSJed Brown void *functx; 7399566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes, &J)); 7409566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix)); 7419566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 7429566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 7439566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, J, NULL, NULL)); 7449566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 745caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 7466cab3a1bSJed Brown Mat J, B; 7479566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes, &J)); 7489566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix)); 7499566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 7509566063dSJacob Faibussowitsch PetscCall(DMCreateMatrix(snes->dm, &B)); 75106f20277SJed Brown /* sdm->computejacobian was already set to reach here */ 7529566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, B, NULL, NULL)); 7539566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 7549566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 755caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 7561ba9b98eSMatthew G. Knepley PetscDS prob; 7576cab3a1bSJed Brown Mat J, B; 7581ba9b98eSMatthew G. Knepley PetscBool hasPrec = PETSC_FALSE; 7591ba9b98eSMatthew G. Knepley 7606cab3a1bSJed Brown J = snes->jacobian; 7619566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 7629566063dSJacob Faibussowitsch if (prob) PetscCall(PetscDSHasJacobianPreconditioner(prob, &hasPrec)); 7639566063dSJacob Faibussowitsch if (J) PetscCall(PetscObjectReference((PetscObject)J)); 7649566063dSJacob Faibussowitsch else if (hasPrec) PetscCall(DMCreateMatrix(snes->dm, &J)); 7659566063dSJacob Faibussowitsch PetscCall(DMCreateMatrix(snes->dm, &B)); 7669566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J ? J : B, B, NULL, NULL)); 7679566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 7689566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 7696cab3a1bSJed Brown } 770caa4e7f2SJed Brown { 771caa4e7f2SJed Brown KSP ksp; 7729566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 7739566063dSJacob Faibussowitsch PetscCall(KSPSetComputeOperators(ksp, KSPComputeOperators_SNES, snes)); 7749566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(snes->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, snes)); 775caa4e7f2SJed Brown } 7763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7776cab3a1bSJed Brown } 7786cab3a1bSJed Brown 779d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESMonitorPauseFinal_Internal(SNES snes) 780d71ae5a4SJacob Faibussowitsch { 7815e7c47f3SMatthew G. Knepley PetscInt i; 7825e7c47f3SMatthew G. Knepley 7835e7c47f3SMatthew G. Knepley PetscFunctionBegin; 7843ba16761SJacob Faibussowitsch if (!snes->pauseFinal) PetscFunctionReturn(PETSC_SUCCESS); 7855e7c47f3SMatthew G. Knepley for (i = 0; i < snes->numbermonitors; ++i) { 7865e7c47f3SMatthew G. Knepley PetscViewerAndFormat *vf = (PetscViewerAndFormat *)snes->monitorcontext[i]; 7875e7c47f3SMatthew G. Knepley PetscDraw draw; 7885e7c47f3SMatthew G. Knepley PetscReal lpause; 7895e7c47f3SMatthew G. Knepley 7905e7c47f3SMatthew G. Knepley if (!vf) continue; 7915e7c47f3SMatthew G. Knepley if (vf->lg) { 7925e7c47f3SMatthew G. Knepley if (!PetscCheckPointer(vf->lg, PETSC_OBJECT)) continue; 7935e7c47f3SMatthew G. Knepley if (((PetscObject)vf->lg)->classid != PETSC_DRAWLG_CLASSID) continue; 7949566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(vf->lg, &draw)); 7959566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPause(draw, &lpause)); 7969566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, -1.0)); 7979566063dSJacob Faibussowitsch PetscCall(PetscDrawPause(draw)); 7989566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, lpause)); 7995e7c47f3SMatthew G. Knepley } else { 8005e7c47f3SMatthew G. Knepley PetscBool isdraw; 8015e7c47f3SMatthew G. Knepley 8025e7c47f3SMatthew G. Knepley if (!PetscCheckPointer(vf->viewer, PETSC_OBJECT)) continue; 8035e7c47f3SMatthew G. Knepley if (((PetscObject)vf->viewer)->classid != PETSC_VIEWER_CLASSID) continue; 8049566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer, PETSCVIEWERDRAW, &isdraw)); 8055e7c47f3SMatthew G. Knepley if (!isdraw) continue; 8069566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(vf->viewer, 0, &draw)); 8079566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPause(draw, &lpause)); 8089566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, -1.0)); 8099566063dSJacob Faibussowitsch PetscCall(PetscDrawPause(draw)); 8109566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, lpause)); 8115e7c47f3SMatthew G. Knepley } 8125e7c47f3SMatthew G. Knepley } 8133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8145e7c47f3SMatthew G. Knepley } 8155e7c47f3SMatthew G. Knepley 816fde5950dSBarry Smith /*@C 817fde5950dSBarry Smith SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 818fde5950dSBarry Smith 819c3339decSBarry Smith Collective 820fde5950dSBarry Smith 821fde5950dSBarry Smith Input Parameters: 822dc4c0fb0SBarry Smith + snes - `SNES` object you wish to monitor 823fde5950dSBarry Smith . name - the monitor type one is seeking 824fde5950dSBarry Smith . help - message indicating what monitoring is done 825fde5950dSBarry Smith . manual - manual page for the monitor 826fde5950dSBarry Smith . monitor - the monitor function 827f6dfbefdSBarry Smith - monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the `SNES` or `PetscViewer` objects 828fde5950dSBarry Smith 829f6dfbefdSBarry Smith Options Database Key: 830f6dfbefdSBarry Smith . -name - trigger the use of this monitor in `SNESSetFromOptions()` 831f6dfbefdSBarry Smith 832f6dfbefdSBarry Smith Level: advanced 833fde5950dSBarry Smith 8341cc06b55SBarry Smith .seealso: [](ch_snes), `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 835db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 836e4094ef1SJacob Faibussowitsch `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, 837db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 838c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 839db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 840db781477SPatrick Sanan `PetscOptionsFList()`, `PetscOptionsEList()` 841fde5950dSBarry Smith @*/ 842d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSetFromOptions(SNES snes, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(SNES, PetscInt, PetscReal, PetscViewerAndFormat *), PetscErrorCode (*monitorsetup)(SNES, PetscViewerAndFormat *)) 843d71ae5a4SJacob Faibussowitsch { 844fde5950dSBarry Smith PetscViewer viewer; 845fde5950dSBarry Smith PetscViewerFormat format; 846fde5950dSBarry Smith PetscBool flg; 847fde5950dSBarry Smith 848fde5950dSBarry Smith PetscFunctionBegin; 8499566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, name, &viewer, &format, &flg)); 850fde5950dSBarry Smith if (flg) { 851d43b4f6eSBarry Smith PetscViewerAndFormat *vf; 8529566063dSJacob Faibussowitsch PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf)); 8539566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)viewer)); 8541baa6e33SBarry Smith if (monitorsetup) PetscCall((*monitorsetup)(snes, vf)); 8559566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, (PetscErrorCode(*)(SNES, PetscInt, PetscReal, void *))monitor, vf, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy)); 856fde5950dSBarry Smith } 8573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 858fde5950dSBarry Smith } 859fde5950dSBarry Smith 860a4598233SStefano Zampini PetscErrorCode SNESEWSetFromOptions_Private(SNESKSPEW *kctx, PetscBool print_api, MPI_Comm comm, const char *prefix) 861d71ae5a4SJacob Faibussowitsch { 862a4598233SStefano Zampini const char *api = print_api ? "SNESKSPSetParametersEW" : NULL; 863a4598233SStefano Zampini 8640f0abf79SStefano Zampini PetscFunctionBegin; 8650f0abf79SStefano Zampini PetscOptionsBegin(comm, prefix, "Eisenstat and Walker type forcing options", "KSP"); 866a4598233SStefano Zampini PetscCall(PetscOptionsInt("-ksp_ew_version", "Version 1, 2 or 3", api, kctx->version, &kctx->version, NULL)); 867a4598233SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_rtol0", "0 <= rtol0 < 1", api, kctx->rtol_0, &kctx->rtol_0, NULL)); 868a4598233SStefano Zampini kctx->rtol_max = PetscMax(kctx->rtol_0, kctx->rtol_max); 869a4598233SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_rtolmax", "0 <= rtolmax < 1", api, kctx->rtol_max, &kctx->rtol_max, NULL)); 870a4598233SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_gamma", "0 <= gamma <= 1", api, kctx->gamma, &kctx->gamma, NULL)); 871a4598233SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_alpha", "1 < alpha <= 2", api, kctx->alpha, &kctx->alpha, NULL)); 8720f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_alpha2", "alpha2", NULL, kctx->alpha2, &kctx->alpha2, NULL)); 873a4598233SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_threshold", "0 < threshold < 1", api, kctx->threshold, &kctx->threshold, NULL)); 8740f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p1", "p1", NULL, kctx->v4_p1, &kctx->v4_p1, NULL)); 8750f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p2", "p2", NULL, kctx->v4_p2, &kctx->v4_p2, NULL)); 8760f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p3", "p3", NULL, kctx->v4_p3, &kctx->v4_p3, NULL)); 8770f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m1", "Scaling when rk-1 in [p2,p3)", NULL, kctx->v4_m1, &kctx->v4_m1, NULL)); 8780f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m2", "Scaling when rk-1 in [p3,+infty)", NULL, kctx->v4_m2, &kctx->v4_m2, NULL)); 8790f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m3", "Threshold for successive rtol (0.1 in Eq.7)", NULL, kctx->v4_m3, &kctx->v4_m3, NULL)); 8800f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m4", "Adaptation scaling (0.5 in Eq.7)", NULL, kctx->v4_m4, &kctx->v4_m4, NULL)); 8810f0abf79SStefano Zampini PetscOptionsEnd(); 8823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8830f0abf79SStefano Zampini } 8840f0abf79SStefano Zampini 8859b94acceSBarry Smith /*@ 886f6dfbefdSBarry Smith SNESSetFromOptions - Sets various `SNES` and `KSP` parameters from user options. 8879b94acceSBarry Smith 888c3339decSBarry Smith Collective 889c7afd0dbSLois Curfman McInnes 8909b94acceSBarry Smith Input Parameter: 891f6dfbefdSBarry Smith . snes - the `SNES` context 8929b94acceSBarry Smith 89336851e7fSLois Curfman McInnes Options Database Keys: 894f6dfbefdSBarry Smith + -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, `SNESType` for complete list 89582738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 89682738288SBarry Smith of the change in the solution between steps 89770441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 898b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 899e4d06f11SPatrick Farrell . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 900be5caee7SBarry Smith . -snes_force_iteration <force> - force SNESSolve() to take at least one iteration 901b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 902b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 9034839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 904ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 905a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 9063d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - retains the -snes_lag_preconditioner information across multiple SNESSolve() 907e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 9083d5a8a6aSBarry Smith . -snes_lag_jacobian_persists <true,false> - retains the -snes_lag_jacobian information across multiple SNESSolve() 9094a221d59SStefano Zampini . -snes_tr_tol <trtol> - trust region tolerance 910f362779dSJed Brown . -snes_convergence_test - <default,skip,correct_pressure> convergence test in nonlinear solver. 911f6dfbefdSBarry Smith default `SNESConvergedDefault()`. skip `SNESConvergedSkip()` means continue iterating until max_it or some other criterion is reached, saving expense 912f6dfbefdSBarry Smith of convergence test. correct_pressure S`NESConvergedCorrectPressure()` has special handling of a pressure null space. 913fde5950dSBarry Smith . -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout 914fde5950dSBarry Smith . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 915fde5950dSBarry Smith . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 916fde5950dSBarry Smith . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 9174619e776SBarry Smith . -snes_monitor_lg_residualnorm - plots residual norm at each iteration 918459f5d12SBarry Smith . -snes_monitor_lg_range - plots residual norm at each iteration 9195e7c47f3SMatthew G. Knepley . -snes_monitor_pause_final - Pauses all monitor drawing after the solver ends 920e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 921e2e60de9SPeter Brune . -snes_fd_color - use finite differences with coloring to compute Jacobian 9225968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 923b5badacbSBarry Smith . -snes_converged_reason - print the reason for convergence/divergence after each solve 924e62ac41dSBarry Smith . -npc_snes_type <type> - the SNES type to use as a nonlinear preconditioner 925e62ac41dSBarry Smith . -snes_test_jacobian <optional threshold> - compare the user provided Jacobian with one computed via finite differences to check for errors. If a threshold is given, display only those entries whose difference is greater than the threshold. 926e62ac41dSBarry Smith - -snes_test_jacobian_view - display the user provided Jacobian, the finite difference Jacobian and the difference between them to help users detect the location of errors in the user provided Jacobian. 92782738288SBarry Smith 928f6dfbefdSBarry Smith Options Database Keys for Eisenstat-Walker method: 929fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 9304b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 93136851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 93236851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 93336851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 93436851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 93536851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 93636851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 93782738288SBarry Smith 938dc4c0fb0SBarry Smith Level: beginner 939dc4c0fb0SBarry Smith 94011ca99fdSLois Curfman McInnes Notes: 941ec5066bdSBarry Smith To see all options, run your program with the -help option or consult the users manual 942ec5066bdSBarry Smith 94301c1178eSBarry Smith `SNES` supports three approaches for computing (approximate) Jacobians: user provided via `SNESSetJacobian()`, matrix-free, and computing explicitly with 944f6dfbefdSBarry Smith finite differences and coloring using `MatFDColoring`. It is also possible to use automatic differentiation and the `MatFDColoring` object. 94583e2fdc7SBarry Smith 9461cc06b55SBarry Smith .seealso: [](ch_snes), `SNESType`, `SNESSetOptionsPrefix()`, `SNESResetFromOptions()`, `SNES`, `SNESCreate()` 9479b94acceSBarry Smith @*/ 948d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFromOptions(SNES snes) 949d71ae5a4SJacob Faibussowitsch { 9508afaa268SBarry Smith PetscBool flg, pcset, persist, set; 951d8f46077SPeter Brune PetscInt i, indx, lag, grids; 95204d7464bSBarry Smith const char *deft = SNESNEWTONLS; 953649ef022SMatthew Knepley const char *convtests[] = {"default", "skip", "correct_pressure"}; 95485385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 9550f0abf79SStefano Zampini char type[256], monfilename[PETSC_MAX_PATH_LEN], ewprefix[256]; 956c40d0f55SPeter Brune PCSide pcside; 957a64e098fSPeter Brune const char *optionsprefix; 9589b94acceSBarry Smith 9593a40ed3dSBarry Smith PetscFunctionBegin; 9600700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 9619566063dSJacob Faibussowitsch PetscCall(SNESRegisterAll()); 962d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)snes); 963639ff905SBarry Smith if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name; 9649566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-snes_type", "Nonlinear solver method", "SNESSetType", SNESList, deft, type, 256, &flg)); 965d64ed03dSBarry Smith if (flg) { 9669566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, type)); 9677adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 9689566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, deft)); 969d64ed03dSBarry Smith } 9709566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_stol", "Stop if step length less than", "SNESSetTolerances", snes->stol, &snes->stol, NULL)); 9719566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_atol", "Stop if function norm less than", "SNESSetTolerances", snes->abstol, &snes->abstol, NULL)); 972186905e3SBarry Smith 9739566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_rtol", "Stop if decrease in function norm less than", "SNESSetTolerances", snes->rtol, &snes->rtol, NULL)); 9749566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_divergence_tolerance", "Stop if residual norm increases by this factor", "SNESSetDivergenceTolerance", snes->divtol, &snes->divtol, NULL)); 9759566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_it", "Maximum iterations", "SNESSetTolerances", snes->max_its, &snes->max_its, NULL)); 9769566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_funcs", "Maximum function evaluations", "SNESSetTolerances", snes->max_funcs, &snes->max_funcs, NULL)); 9779566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_fail", "Maximum nonlinear step failures", "SNESSetMaxNonlinearStepFailures", snes->maxFailures, &snes->maxFailures, NULL)); 9789566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_linear_solve_fail", "Maximum failures in linear solves allowed", "SNESSetMaxLinearSolveFailures", snes->maxLinearSolveFailures, &snes->maxLinearSolveFailures, NULL)); 9799566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_error_if_not_converged", "Generate error if solver does not converge", "SNESSetErrorIfNotConverged", snes->errorifnotconverged, &snes->errorifnotconverged, NULL)); 9809566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_force_iteration", "Force SNESSolve() to take at least one iteration", "SNESSetForceIteration", snes->forceiteration, &snes->forceiteration, NULL)); 9819566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_check_jacobian_domain_error", "Check Jacobian domain error after Jacobian evaluation", "SNESCheckJacobianDomainError", snes->checkjacdomainerror, &snes->checkjacdomainerror, NULL)); 98285385478SLisandro Dalcin 9839566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_lag_preconditioner", "How often to rebuild preconditioner", "SNESSetLagPreconditioner", snes->lagpreconditioner, &lag, &flg)); 984a8054027SBarry Smith if (flg) { 9855f80ce2aSJacob Faibussowitsch PetscCheck(lag != -1, PetscObjectComm((PetscObject)snes), PETSC_ERR_USER, "Cannot set the lag to -1 from the command line since the preconditioner must be built as least once, perhaps you mean -2"); 9869566063dSJacob Faibussowitsch PetscCall(SNESSetLagPreconditioner(snes, lag)); 987a8054027SBarry Smith } 9889566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_lag_preconditioner_persists", "Preconditioner lagging through multiple SNES solves", "SNESSetLagPreconditionerPersists", snes->lagjac_persist, &persist, &flg)); 9891baa6e33SBarry Smith if (flg) PetscCall(SNESSetLagPreconditionerPersists(snes, persist)); 9909566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_lag_jacobian", "How often to rebuild Jacobian", "SNESSetLagJacobian", snes->lagjacobian, &lag, &flg)); 991e35cf81dSBarry Smith if (flg) { 9925f80ce2aSJacob Faibussowitsch PetscCheck(lag != -1, PetscObjectComm((PetscObject)snes), PETSC_ERR_USER, "Cannot set the lag to -1 from the command line since the Jacobian must be built as least once, perhaps you mean -2"); 9939566063dSJacob Faibussowitsch PetscCall(SNESSetLagJacobian(snes, lag)); 994e35cf81dSBarry Smith } 9959566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_lag_jacobian_persists", "Jacobian lagging through multiple SNES solves", "SNESSetLagJacobianPersists", snes->lagjac_persist, &persist, &flg)); 9961baa6e33SBarry Smith if (flg) PetscCall(SNESSetLagJacobianPersists(snes, persist)); 99737ec4e1aSPeter Brune 9989566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_grid_sequence", "Use grid sequencing to generate initial guess", "SNESSetGridSequence", snes->gridsequence, &grids, &flg)); 9991baa6e33SBarry Smith if (flg) PetscCall(SNESSetGridSequence(snes, grids)); 1000a8054027SBarry Smith 1001*400f6f02SBarry Smith PetscCall(PetscOptionsEList("-snes_convergence_test", "Convergence test", "SNESSetConvergenceTest", convtests, PETSC_STATIC_ARRAY_LENGTH(convtests), "default", &indx, &flg)); 100285385478SLisandro Dalcin if (flg) { 100385385478SLisandro Dalcin switch (indx) { 1004d71ae5a4SJacob Faibussowitsch case 0: 1005d71ae5a4SJacob Faibussowitsch PetscCall(SNESSetConvergenceTest(snes, SNESConvergedDefault, NULL, NULL)); 1006d71ae5a4SJacob Faibussowitsch break; 1007d71ae5a4SJacob Faibussowitsch case 1: 1008d71ae5a4SJacob Faibussowitsch PetscCall(SNESSetConvergenceTest(snes, SNESConvergedSkip, NULL, NULL)); 1009d71ae5a4SJacob Faibussowitsch break; 1010d71ae5a4SJacob Faibussowitsch case 2: 1011d71ae5a4SJacob Faibussowitsch PetscCall(SNESSetConvergenceTest(snes, SNESConvergedCorrectPressure, NULL, NULL)); 1012d71ae5a4SJacob Faibussowitsch break; 101385385478SLisandro Dalcin } 101485385478SLisandro Dalcin } 101585385478SLisandro Dalcin 10169566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_norm_schedule", "SNES Norm schedule", "SNESSetNormSchedule", SNESNormSchedules, 5, "function", &indx, &flg)); 10179566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetNormSchedule(snes, (SNESNormSchedule)indx)); 1018fdacfa88SPeter Brune 10199566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_function_type", "SNES Norm schedule", "SNESSetFunctionType", SNESFunctionTypes, 2, "unpreconditioned", &indx, &flg)); 10209566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetFunctionType(snes, (SNESFunctionType)indx)); 1021186905e3SBarry Smith 102285385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 102385385478SLisandro Dalcin 10249566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_ksp_ew", "Use Eisentat-Walker linear system convergence test", "SNESKSPSetUseEW", snes->ksp_ewconv, &snes->ksp_ewconv, NULL)); 1025186905e3SBarry Smith 10260f0abf79SStefano Zampini PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 10270f0abf79SStefano Zampini PetscCall(PetscSNPrintf(ewprefix, sizeof(ewprefix), "%s%s", optionsprefix ? optionsprefix : "", "snes_")); 1028a4598233SStefano Zampini PetscCall(SNESEWSetFromOptions_Private(kctx, PETSC_TRUE, PetscObjectComm((PetscObject)snes), ewprefix)); 1029186905e3SBarry Smith 103090d69ab7SBarry Smith flg = PETSC_FALSE; 10319566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_cancel", "Remove all monitors", "SNESMonitorCancel", flg, &flg, &set)); 10329566063dSJacob Faibussowitsch if (set && flg) PetscCall(SNESMonitorCancel(snes)); 1033eabae89aSBarry Smith 10349566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor", "Monitor norm of function", "SNESMonitorDefault", SNESMonitorDefault, SNESMonitorDefaultSetUp)); 10359566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_short", "Monitor norm of function with fewer digits", "SNESMonitorDefaultShort", SNESMonitorDefaultShort, NULL)); 10369566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_range", "Monitor range of elements of function", "SNESMonitorRange", SNESMonitorRange, NULL)); 1037eabae89aSBarry Smith 10389566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_ratio", "Monitor ratios of the norm of function for consecutive steps", "SNESMonitorRatio", SNESMonitorRatio, SNESMonitorRatioSetUp)); 10399566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_field", "Monitor norm of function (split into fields)", "SNESMonitorDefaultField", SNESMonitorDefaultField, NULL)); 10409566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_solution", "View solution at each iteration", "SNESMonitorSolution", SNESMonitorSolution, NULL)); 10419566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_solution_update", "View correction at each iteration", "SNESMonitorSolutionUpdate", SNESMonitorSolutionUpdate, NULL)); 10429566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_residual", "View residual at each iteration", "SNESMonitorResidual", SNESMonitorResidual, NULL)); 10439566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_jacupdate_spectrum", "Print the change in the spectrum of the Jacobian", "SNESMonitorJacUpdateSpectrum", SNESMonitorJacUpdateSpectrum, NULL)); 10449566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_fields", "Monitor norm of function per field", "SNESMonitorSet", SNESMonitorFields, NULL)); 10459566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_pause_final", "Pauses all draw monitors at the final iterate", "SNESMonitorPauseFinal_Internal", PETSC_FALSE, &snes->pauseFinal, NULL)); 10462db13446SMatthew G. Knepley 10479566063dSJacob Faibussowitsch PetscCall(PetscOptionsString("-snes_monitor_python", "Use Python function", "SNESMonitorSet", NULL, monfilename, sizeof(monfilename), &flg)); 10489566063dSJacob Faibussowitsch if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)snes, monfilename)); 10495180491cSLisandro Dalcin 105090d69ab7SBarry Smith flg = PETSC_FALSE; 10519566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_lg_range", "Plot function range at each iteration", "SNESMonitorLGRange", flg, &flg, NULL)); 1052459f5d12SBarry Smith if (flg) { 1053459f5d12SBarry Smith PetscViewer ctx; 1054e24b481bSBarry Smith 10559566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &ctx)); 10569566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, SNESMonitorLGRange, ctx, (PetscErrorCode(*)(void **))PetscViewerDestroy)); 1057459f5d12SBarry Smith } 10582e7541e6SPeter Brune 105990d69ab7SBarry Smith flg = PETSC_FALSE; 10609566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_converged_reason_view_cancel", "Remove all converged reason viewers", "SNESConvergedReasonViewCancel", flg, &flg, &set)); 10619566063dSJacob Faibussowitsch if (set && flg) PetscCall(SNESConvergedReasonViewCancel(snes)); 1062c4421ceaSFande Kong 1063c4421ceaSFande Kong flg = PETSC_FALSE; 10649566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd", "Use finite differences (slow) to compute Jacobian", "SNESComputeJacobianDefault", flg, &flg, NULL)); 10654b27c08aSLois Curfman McInnes if (flg) { 10666cab3a1bSJed Brown void *functx; 1067b1f624c7SBarry Smith DM dm; 10689566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 1069800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetJacobianContext_Internal(dm)); 10709566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 10719566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, snes->jacobian, snes->jacobian_pre, SNESComputeJacobianDefault, functx)); 10729566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default finite difference Jacobian matrix\n")); 10739b94acceSBarry Smith } 1074639f9d9dSBarry Smith 107544848bc4SPeter Brune flg = PETSC_FALSE; 10769566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd_function", "Use finite differences (slow) to compute function from user objective", "SNESObjectiveComputeFunctionDefaultFD", flg, &flg, NULL)); 10771baa6e33SBarry Smith if (flg) PetscCall(SNESSetFunction(snes, NULL, SNESObjectiveComputeFunctionDefaultFD, NULL)); 107897584545SPeter Brune 107997584545SPeter Brune flg = PETSC_FALSE; 10809566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd_color", "Use finite differences with coloring to compute Jacobian", "SNESComputeJacobianDefaultColor", flg, &flg, NULL)); 108144848bc4SPeter Brune if (flg) { 1082c52e227fSPeter Brune DM dm; 10839566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 1084800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetJacobianContext_Internal(dm)); 10859566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, snes->jacobian, snes->jacobian_pre, SNESComputeJacobianDefaultColor, NULL)); 10869566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default finite difference coloring Jacobian matrix\n")); 108744848bc4SPeter Brune } 108844848bc4SPeter Brune 1089aa3661deSLisandro Dalcin flg = PETSC_FALSE; 10909566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_mf_operator", "Use a Matrix-Free Jacobian with user-provided preconditioner matrix", "SNESSetUseMatrixFree", PETSC_FALSE, &snes->mf_operator, &flg)); 1091d8f46077SPeter Brune if (flg && snes->mf_operator) { 1092a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 1093d8f46077SPeter Brune snes->mf = PETSC_TRUE; 1094a8248277SBarry Smith } 1095aa3661deSLisandro Dalcin flg = PETSC_FALSE; 10969566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_mf", "Use a Matrix-Free Jacobian with no preconditioner matrix", "SNESSetUseMatrixFree", PETSC_FALSE, &snes->mf, &flg)); 1097d8f46077SPeter Brune if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 10989566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_mf_version", "Matrix-Free routines version 1 or 2", "None", snes->mf_version, &snes->mf_version, NULL)); 1099d28543b3SPeter Brune 1100c40d0f55SPeter Brune flg = PETSC_FALSE; 11019566063dSJacob Faibussowitsch PetscCall(SNESGetNPCSide(snes, &pcside)); 11029566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-snes_npc_side", "SNES nonlinear preconditioner side", "SNESSetNPCSide", PCSides, (PetscEnum)pcside, (PetscEnum *)&pcside, &flg)); 11039566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetNPCSide(snes, pcside)); 1104c40d0f55SPeter Brune 1105e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 11068a70d858SHong Zhang /* 11078a70d858SHong Zhang Publish convergence information using SAWs 11088a70d858SHong Zhang */ 11098a70d858SHong Zhang flg = PETSC_FALSE; 11109566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_saws", "Publish SNES progress using SAWs", "SNESMonitorSet", flg, &flg, NULL)); 11118a70d858SHong Zhang if (flg) { 11128a70d858SHong Zhang void *ctx; 11139566063dSJacob Faibussowitsch PetscCall(SNESMonitorSAWsCreate(snes, &ctx)); 11149566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, SNESMonitorSAWs, ctx, SNESMonitorSAWsDestroy)); 11158a70d858SHong Zhang } 11168a70d858SHong Zhang #endif 11178a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS) 1118b90c6cbeSBarry Smith { 1119b90c6cbeSBarry Smith PetscBool set; 1120b90c6cbeSBarry Smith flg = PETSC_FALSE; 11219566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_saws_block", "Block for SAWs at end of SNESSolve", "PetscObjectSAWsBlock", ((PetscObject)snes)->amspublishblock, &flg, &set)); 11221baa6e33SBarry Smith if (set) PetscCall(PetscObjectSAWsSetBlock((PetscObject)snes, flg)); 1123b90c6cbeSBarry Smith } 1124b90c6cbeSBarry Smith #endif 1125b90c6cbeSBarry Smith 112648a46eb9SPierre Jolivet for (i = 0; i < numberofsetfromoptions; i++) PetscCall((*othersetfromoptions[i])(snes)); 112776b2cf59SMatthew Knepley 1128dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, setfromoptions, PetscOptionsObject); 11295d973c19SBarry Smith 11305d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 1131dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)snes, PetscOptionsObject)); 1132d0609cedSBarry Smith PetscOptionsEnd(); 11334bbc92c1SBarry Smith 1134d8d34be6SBarry Smith if (snes->linesearch) { 11359566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 11369566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFromOptions(snes->linesearch)); 1137d8d34be6SBarry Smith } 11389e764e56SPeter Brune 11396aa5e7e9SBarry Smith if (snes->usesksp) { 11409566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 11419566063dSJacob Faibussowitsch PetscCall(KSPSetOperators(snes->ksp, snes->jacobian, snes->jacobian_pre)); 11429566063dSJacob Faibussowitsch PetscCall(KSPSetFromOptions(snes->ksp)); 11436aa5e7e9SBarry Smith } 11446991f827SBarry Smith 1145b5badacbSBarry Smith /* if user has set the SNES NPC type via options database, create it. */ 11469566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 11479566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasName(((PetscObject)snes)->options, optionsprefix, "-npc_snes_type", &pcset)); 114848a46eb9SPierre Jolivet if (pcset && (!snes->npc)) PetscCall(SNESGetNPC(snes, &snes->npc)); 11491baa6e33SBarry Smith if (snes->npc) PetscCall(SNESSetFromOptions(snes->npc)); 1150b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled++; 11513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1152b3cd9a81SMatthew G. Knepley } 1153b3cd9a81SMatthew G. Knepley 1154b3cd9a81SMatthew G. Knepley /*@ 1155f6dfbefdSBarry Smith SNESResetFromOptions - Sets various `SNES` and `KSP` parameters from user options ONLY if the `SNESSetFromOptions()` was previously set from options 1156b3cd9a81SMatthew G. Knepley 1157c3339decSBarry Smith Collective 1158b3cd9a81SMatthew G. Knepley 1159b3cd9a81SMatthew G. Knepley Input Parameter: 1160f6dfbefdSBarry Smith . snes - the `SNES` context 1161b3cd9a81SMatthew G. Knepley 1162b3cd9a81SMatthew G. Knepley Level: beginner 1163b3cd9a81SMatthew G. Knepley 11641cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetFromOptions()`, `SNESSetOptionsPrefix()` 1165b3cd9a81SMatthew G. Knepley @*/ 1166d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESResetFromOptions(SNES snes) 1167d71ae5a4SJacob Faibussowitsch { 1168b3cd9a81SMatthew G. Knepley PetscFunctionBegin; 11699566063dSJacob Faibussowitsch if (snes->setfromoptionscalled) PetscCall(SNESSetFromOptions(snes)); 11703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11719b94acceSBarry Smith } 11729b94acceSBarry Smith 1173bb9467b5SJed Brown /*@C 1174d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 1175d25893d9SBarry Smith the nonlinear solvers. 1176d25893d9SBarry Smith 1177dc4c0fb0SBarry Smith Logically Collective; No Fortran Support 1178d25893d9SBarry Smith 1179d25893d9SBarry Smith Input Parameters: 1180f6dfbefdSBarry Smith + snes - the `SNES` context 1181d25893d9SBarry Smith . compute - function to compute the context 1182d25893d9SBarry Smith - destroy - function to destroy the context 1183d25893d9SBarry Smith 1184d25893d9SBarry Smith Level: intermediate 1185d25893d9SBarry Smith 1186f6dfbefdSBarry Smith Note: 1187f6dfbefdSBarry Smith This routine is useful if you are performing grid sequencing or using `SNESFAS` and need the appropriate context generated for each level. 1188f6dfbefdSBarry Smith 1189f6dfbefdSBarry Smith Use `SNESSetApplicationContext()` to see the context immediately 1190f6dfbefdSBarry Smith 119142747ad1SJacob Faibussowitsch .seealso: [](ch_snes), `SNESGetApplicationContext()`, `SNESSetApplicationContext()` 1192d25893d9SBarry Smith @*/ 1193d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetComputeApplicationContext(SNES snes, PetscErrorCode (*compute)(SNES, void **), PetscErrorCode (*destroy)(void **)) 1194d71ae5a4SJacob Faibussowitsch { 1195d25893d9SBarry Smith PetscFunctionBegin; 1196d25893d9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1197d25893d9SBarry Smith snes->ops->usercompute = compute; 1198d25893d9SBarry Smith snes->ops->userdestroy = destroy; 11993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1200d25893d9SBarry Smith } 1201a847f771SSatish Balay 1202b07ff414SBarry Smith /*@ 1203f6dfbefdSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for the nonlinear solvers. 12049b94acceSBarry Smith 1205c3339decSBarry Smith Logically Collective 1206fee21e36SBarry Smith 1207c7afd0dbSLois Curfman McInnes Input Parameters: 1208f6dfbefdSBarry Smith + snes - the `SNES` context 1209c7afd0dbSLois Curfman McInnes - usrP - optional user context 1210c7afd0dbSLois Curfman McInnes 121136851e7fSLois Curfman McInnes Level: intermediate 121236851e7fSLois Curfman McInnes 1213f6dfbefdSBarry Smith Notes: 1214f6dfbefdSBarry Smith Users can provide a context when constructing the `SNES` options and then access it inside their function, Jacobian, or other evaluation function 1215f6dfbefdSBarry Smith with `SNESGetApplicationContext()` 1216f6dfbefdSBarry Smith 1217f6dfbefdSBarry Smith To provide a function that computes the context for you use `SNESSetComputeApplicationContext()` 1218f6dfbefdSBarry Smith 1219e4094ef1SJacob Faibussowitsch Fortran Notes: 1220dc4c0fb0SBarry Smith You must write a Fortran interface definition for this 1221daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1222daf670e6SBarry Smith 12231cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetComputeApplicationContext()`, `SNESGetApplicationContext()` 12249b94acceSBarry Smith @*/ 1225d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetApplicationContext(SNES snes, void *usrP) 1226d71ae5a4SJacob Faibussowitsch { 1227b07ff414SBarry Smith KSP ksp; 12281b2093e4SBarry Smith 12293a40ed3dSBarry Smith PetscFunctionBegin; 12300700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 12319566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 12329566063dSJacob Faibussowitsch PetscCall(KSPSetApplicationContext(ksp, usrP)); 12339b94acceSBarry Smith snes->user = usrP; 12343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12359b94acceSBarry Smith } 123674679c65SBarry Smith 1237b07ff414SBarry Smith /*@ 12389b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 1239f6dfbefdSBarry Smith nonlinear solvers set with `SNESGetApplicationContext()` or with `SNESSetComputeApplicationContext()` 12409b94acceSBarry Smith 1241c7afd0dbSLois Curfman McInnes Not Collective 1242c7afd0dbSLois Curfman McInnes 12439b94acceSBarry Smith Input Parameter: 1244f6dfbefdSBarry Smith . snes - `SNES` context 12459b94acceSBarry Smith 12469b94acceSBarry Smith Output Parameter: 12479b94acceSBarry Smith . usrP - user context 12489b94acceSBarry Smith 124936851e7fSLois Curfman McInnes Level: intermediate 125036851e7fSLois Curfman McInnes 1251e4094ef1SJacob Faibussowitsch Fortran Notes: 1252dc4c0fb0SBarry Smith You must write a Fortran interface definition for this 1253dc4c0fb0SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1254dc4c0fb0SBarry Smith 12551cc06b55SBarry Smith .seealso: [](ch_snes), `SNESSetApplicationContext()` 12569b94acceSBarry Smith @*/ 1257d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetApplicationContext(SNES snes, void *usrP) 1258d71ae5a4SJacob Faibussowitsch { 12593a40ed3dSBarry Smith PetscFunctionBegin; 12600700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1261e71120c6SJed Brown *(void **)usrP = snes->user; 12623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12639b94acceSBarry Smith } 126474679c65SBarry Smith 12659b94acceSBarry Smith /*@ 126601c1178eSBarry Smith SNESSetUseMatrixFree - indicates that `SNES` should use matrix-free finite difference matrix vector products to apply the Jacobian. 12673565c898SBarry Smith 1268dc4c0fb0SBarry Smith Logically Collective 12693565c898SBarry Smith 12703565c898SBarry Smith Input Parameters: 1271f6dfbefdSBarry Smith + snes - `SNES` context 1272f6dfbefdSBarry Smith . mf_operator - use matrix-free only for the Amat used by `SNESSetJacobian()`, this means the user provided Pmat will continue to be used 1273f6dfbefdSBarry Smith - mf - use matrix-free for both the Amat and Pmat used by `SNESSetJacobian()`, both the Amat and Pmat set in `SNESSetJacobian()` will be ignored. With 1274f6dfbefdSBarry Smith this option no matrix element based preconditioners can be used in the linear solve since the matrix won't be explicitly available 12753565c898SBarry Smith 1276f6dfbefdSBarry Smith Options Database Keys: 127701c1178eSBarry Smith + -snes_mf_operator - use matrix-free only for the mat operator 1278f6dfbefdSBarry Smith . -snes_mf - use matrix-free for both the mat and pmat operator 1279ec5066bdSBarry Smith . -snes_fd_color - compute the Jacobian via coloring and finite differences. 1280ec5066bdSBarry Smith - -snes_fd - compute the Jacobian via finite differences (slow) 12813565c898SBarry Smith 12823565c898SBarry Smith Level: intermediate 12833565c898SBarry Smith 1284f6dfbefdSBarry Smith Note: 1285dc4c0fb0SBarry Smith `SNES` supports three approaches for computing (approximate) Jacobians: user provided via `SNESSetJacobian()`, matrix-free, and computing explicitly with 1286f6dfbefdSBarry Smith finite differences and coloring using `MatFDColoring`. It is also possible to use automatic differentiation and the `MatFDColoring` object. 1287ec5066bdSBarry Smith 12881cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESGetUseMatrixFree()`, `MatCreateSNESMF()`, `SNESComputeJacobianDefaultColor()` 12893565c898SBarry Smith @*/ 1290d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUseMatrixFree(SNES snes, PetscBool mf_operator, PetscBool mf) 1291d71ae5a4SJacob Faibussowitsch { 12923565c898SBarry Smith PetscFunctionBegin; 12933565c898SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 129488b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes, mf_operator, 2); 129588b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes, mf, 3); 12964ddffce6SLisandro Dalcin snes->mf = mf_operator ? PETSC_TRUE : mf; 12973565c898SBarry Smith snes->mf_operator = mf_operator; 12983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12993565c898SBarry Smith } 13003565c898SBarry Smith 13013565c898SBarry Smith /*@ 1302dc4c0fb0SBarry Smith SNESGetUseMatrixFree - indicates if the `SNES` uses matrix-free finite difference matrix vector products to apply the Jacobian. 13033565c898SBarry Smith 1304f6dfbefdSBarry Smith Not Collective, but the resulting flags will be the same on all MPI ranks 13053565c898SBarry Smith 13063565c898SBarry Smith Input Parameter: 1307f6dfbefdSBarry Smith . snes - `SNES` context 13083565c898SBarry Smith 13093565c898SBarry Smith Output Parameters: 1310f6dfbefdSBarry Smith + mf_operator - use matrix-free only for the Amat used by `SNESSetJacobian()`, this means the user provided Pmat will continue to be used 1311f6dfbefdSBarry Smith - mf - use matrix-free for both the Amat and Pmat used by `SNESSetJacobian()`, both the Amat and Pmat set in `SNESSetJacobian()` will be ignored 13123565c898SBarry Smith 13133565c898SBarry Smith Level: intermediate 13143565c898SBarry Smith 13151cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetUseMatrixFree()`, `MatCreateSNESMF()` 13163565c898SBarry Smith @*/ 1317d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetUseMatrixFree(SNES snes, PetscBool *mf_operator, PetscBool *mf) 1318d71ae5a4SJacob Faibussowitsch { 13193565c898SBarry Smith PetscFunctionBegin; 13203565c898SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13213565c898SBarry Smith if (mf) *mf = snes->mf; 13223565c898SBarry Smith if (mf_operator) *mf_operator = snes->mf_operator; 13233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13243565c898SBarry Smith } 13253565c898SBarry Smith 13263565c898SBarry Smith /*@ 1327c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 1328c8228a4eSBarry Smith at this time. 13299b94acceSBarry Smith 1330c7afd0dbSLois Curfman McInnes Not Collective 1331c7afd0dbSLois Curfman McInnes 13329b94acceSBarry Smith Input Parameter: 1333f6dfbefdSBarry Smith . snes - `SNES` context 13349b94acceSBarry Smith 13359b94acceSBarry Smith Output Parameter: 13369b94acceSBarry Smith . iter - iteration number 13379b94acceSBarry Smith 1338dc4c0fb0SBarry Smith Level: intermediate 1339dc4c0fb0SBarry Smith 1340c8228a4eSBarry Smith Notes: 1341c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 1342c8228a4eSBarry Smith 1343c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 1344f6dfbefdSBarry Smith Jacobian at each `SNES` iteration). For example, the code 134508405cd6SLois Curfman McInnes .vb 134608405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 134708405cd6SLois Curfman McInnes if (!(it % 2)) { 134808405cd6SLois Curfman McInnes [compute Jacobian here] 134908405cd6SLois Curfman McInnes } 135008405cd6SLois Curfman McInnes .ve 1351f6dfbefdSBarry Smith can be used in your function that computes the Jacobian to cause the Jacobian to be 1352f6dfbefdSBarry Smith recomputed every second `SNES` iteration. See also `SNESSetLagJacobian()` 1353c8228a4eSBarry Smith 1354f6dfbefdSBarry Smith After the `SNES` solve is complete this will return the number of nonlinear iterations used. 1355c04deec6SBarry Smith 13561cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetLagJacobian()`, `SNESGetLinearSolveIterations()` 13579b94acceSBarry Smith @*/ 1358d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetIterationNumber(SNES snes, PetscInt *iter) 1359d71ae5a4SJacob Faibussowitsch { 13603a40ed3dSBarry Smith PetscFunctionBegin; 13610700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13624f572ea9SToby Isaac PetscAssertPointer(iter, 2); 13639b94acceSBarry Smith *iter = snes->iter; 13643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13659b94acceSBarry Smith } 136674679c65SBarry Smith 1367360c497dSPeter Brune /*@ 1368360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 1369360c497dSPeter Brune 1370360c497dSPeter Brune Not Collective 1371360c497dSPeter Brune 1372d8d19677SJose E. Roman Input Parameters: 1373f6dfbefdSBarry Smith + snes - `SNES` context 1374a2b725a8SWilliam Gropp - iter - iteration number 1375360c497dSPeter Brune 1376360c497dSPeter Brune Level: developer 1377360c497dSPeter Brune 13781cc06b55SBarry Smith .seealso: [](ch_snes), `SNESGetLinearSolveIterations()` 1379360c497dSPeter Brune @*/ 1380d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetIterationNumber(SNES snes, PetscInt iter) 1381d71ae5a4SJacob Faibussowitsch { 1382360c497dSPeter Brune PetscFunctionBegin; 1383360c497dSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13849566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsTakeAccess((PetscObject)snes)); 1385360c497dSPeter Brune snes->iter = iter; 13869566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsGrantAccess((PetscObject)snes)); 13873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1388360c497dSPeter Brune } 1389360c497dSPeter Brune 13909b94acceSBarry Smith /*@ 1391b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 13929b94acceSBarry Smith attempted by the nonlinear solver. 13939b94acceSBarry Smith 1394c7afd0dbSLois Curfman McInnes Not Collective 1395c7afd0dbSLois Curfman McInnes 13969b94acceSBarry Smith Input Parameter: 1397f6dfbefdSBarry Smith . snes - `SNES` context 13989b94acceSBarry Smith 13999b94acceSBarry Smith Output Parameter: 14009b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 14019b94acceSBarry Smith 1402dc4c0fb0SBarry Smith Level: intermediate 1403dc4c0fb0SBarry Smith 1404f6dfbefdSBarry Smith Note: 1405f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()`. 1406c96a6f78SLois Curfman McInnes 14071cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1408db781477SPatrick Sanan `SNESSetMaxNonlinearStepFailures()`, `SNESGetMaxNonlinearStepFailures()` 14099b94acceSBarry Smith @*/ 1410d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNonlinearStepFailures(SNES snes, PetscInt *nfails) 1411d71ae5a4SJacob Faibussowitsch { 14123a40ed3dSBarry Smith PetscFunctionBegin; 14130700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14144f572ea9SToby Isaac PetscAssertPointer(nfails, 2); 141550ffb88aSMatthew Knepley *nfails = snes->numFailures; 14163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 141750ffb88aSMatthew Knepley } 141850ffb88aSMatthew Knepley 141950ffb88aSMatthew Knepley /*@ 1420b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 1421f6dfbefdSBarry Smith attempted by the nonlinear solver before it gives up and generates an error 142250ffb88aSMatthew Knepley 142350ffb88aSMatthew Knepley Not Collective 142450ffb88aSMatthew Knepley 142550ffb88aSMatthew Knepley Input Parameters: 1426f6dfbefdSBarry Smith + snes - `SNES` context 142750ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 142850ffb88aSMatthew Knepley 142950ffb88aSMatthew Knepley Level: intermediate 143050ffb88aSMatthew Knepley 14311cc06b55SBarry Smith .seealso: [](ch_snes), `SNESSetErrorIfNotConverged()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1432db781477SPatrick Sanan `SNESGetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 143350ffb88aSMatthew Knepley @*/ 1434d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 1435d71ae5a4SJacob Faibussowitsch { 143650ffb88aSMatthew Knepley PetscFunctionBegin; 14370700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 143850ffb88aSMatthew Knepley snes->maxFailures = maxFails; 14393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 144050ffb88aSMatthew Knepley } 144150ffb88aSMatthew Knepley 144250ffb88aSMatthew Knepley /*@ 1443b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 1444f6dfbefdSBarry Smith attempted by the nonlinear solver before it gives up and generates an error 144550ffb88aSMatthew Knepley 144650ffb88aSMatthew Knepley Not Collective 144750ffb88aSMatthew Knepley 144850ffb88aSMatthew Knepley Input Parameter: 144920f4b53cSBarry Smith . snes - `SNES` context 145050ffb88aSMatthew Knepley 145150ffb88aSMatthew Knepley Output Parameter: 145250ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 145350ffb88aSMatthew Knepley 145450ffb88aSMatthew Knepley Level: intermediate 145550ffb88aSMatthew Knepley 14561cc06b55SBarry Smith .seealso: [](ch_snes), `SNESSetErrorIfNotConverged()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1457db781477SPatrick Sanan `SNESSetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 145850ffb88aSMatthew Knepley @*/ 1459d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 1460d71ae5a4SJacob Faibussowitsch { 146150ffb88aSMatthew Knepley PetscFunctionBegin; 14620700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14634f572ea9SToby Isaac PetscAssertPointer(maxFails, 2); 146450ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 14653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14669b94acceSBarry Smith } 1467a847f771SSatish Balay 14682541af92SBarry Smith /*@ 14692541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 1470f6dfbefdSBarry Smith done by the `SNES` object 14712541af92SBarry Smith 14722541af92SBarry Smith Not Collective 14732541af92SBarry Smith 14742541af92SBarry Smith Input Parameter: 1475f6dfbefdSBarry Smith . snes - `SNES` context 14762541af92SBarry Smith 14772541af92SBarry Smith Output Parameter: 14782541af92SBarry Smith . nfuncs - number of evaluations 14792541af92SBarry Smith 14802541af92SBarry Smith Level: intermediate 14812541af92SBarry Smith 1482f6dfbefdSBarry Smith Note: 1483f6dfbefdSBarry Smith Reset every time `SNESSolve()` is called unless `SNESSetCountersReset()` is used. 1484971e163fSPeter Brune 14851cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, `SNESSetCountersReset()` 14862541af92SBarry Smith @*/ 1487d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 1488d71ae5a4SJacob Faibussowitsch { 14892541af92SBarry Smith PetscFunctionBegin; 14900700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14914f572ea9SToby Isaac PetscAssertPointer(nfuncs, 2); 14922541af92SBarry Smith *nfuncs = snes->nfuncs; 14933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14942541af92SBarry Smith } 14952541af92SBarry Smith 14963d4c4710SBarry Smith /*@ 14973d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 14983d4c4710SBarry Smith linear solvers. 14993d4c4710SBarry Smith 15003d4c4710SBarry Smith Not Collective 15013d4c4710SBarry Smith 15023d4c4710SBarry Smith Input Parameter: 1503f6dfbefdSBarry Smith . snes - `SNES` context 15043d4c4710SBarry Smith 15053d4c4710SBarry Smith Output Parameter: 15063d4c4710SBarry Smith . nfails - number of failed solves 15073d4c4710SBarry Smith 1508f6dfbefdSBarry Smith Options Database Key: 15099d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 15109d85da0cSMatthew G. Knepley 1511f6dfbefdSBarry Smith Level: intermediate 1512f6dfbefdSBarry Smith 1513f6dfbefdSBarry Smith Note: 1514f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()`. 15153d4c4710SBarry Smith 15161cc06b55SBarry Smith .seealso: [](ch_snes), `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()` 15173d4c4710SBarry Smith @*/ 1518d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLinearSolveFailures(SNES snes, PetscInt *nfails) 1519d71ae5a4SJacob Faibussowitsch { 15203d4c4710SBarry Smith PetscFunctionBegin; 15210700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 15224f572ea9SToby Isaac PetscAssertPointer(nfails, 2); 15233d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 15243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15253d4c4710SBarry Smith } 15263d4c4710SBarry Smith 15273d4c4710SBarry Smith /*@ 15283d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 1529f6dfbefdSBarry Smith allowed before `SNES` returns with a diverged reason of `SNES_DIVERGED_LINEAR_SOLVE` 15303d4c4710SBarry Smith 1531c3339decSBarry Smith Logically Collective 15323d4c4710SBarry Smith 15333d4c4710SBarry Smith Input Parameters: 1534f6dfbefdSBarry Smith + snes - `SNES` context 15353d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 15363d4c4710SBarry Smith 1537f6dfbefdSBarry Smith Options Database Key: 15389d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 15399d85da0cSMatthew G. Knepley 1540dc4c0fb0SBarry Smith Level: intermediate 1541dc4c0fb0SBarry Smith 1542f6dfbefdSBarry Smith Note: 1543f6dfbefdSBarry Smith By default this is 0; that is `SNES` returns on the first failed linear solve 15443d4c4710SBarry Smith 15451cc06b55SBarry Smith .seealso: [](ch_snes), `SNESSetErrorIfNotConverged()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()` 15463d4c4710SBarry Smith @*/ 1547d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 1548d71ae5a4SJacob Faibussowitsch { 15493d4c4710SBarry Smith PetscFunctionBegin; 15500700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1551c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxFails, 2); 15523d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 15533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15543d4c4710SBarry Smith } 15553d4c4710SBarry Smith 15563d4c4710SBarry Smith /*@ 15573d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 1558f6dfbefdSBarry Smith are allowed before `SNES` returns as unsuccessful 15593d4c4710SBarry Smith 15603d4c4710SBarry Smith Not Collective 15613d4c4710SBarry Smith 15623d4c4710SBarry Smith Input Parameter: 1563f6dfbefdSBarry Smith . snes - `SNES` context 15643d4c4710SBarry Smith 15653d4c4710SBarry Smith Output Parameter: 15663d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 15673d4c4710SBarry Smith 15683d4c4710SBarry Smith Level: intermediate 15693d4c4710SBarry Smith 1570f6dfbefdSBarry Smith Note: 1571f6dfbefdSBarry Smith By default this is 1; that is `SNES` returns on the first failed linear solve 15723d4c4710SBarry Smith 15731cc06b55SBarry Smith .seealso: [](ch_snes), `SNESSetErrorIfNotConverged()`, `SNESGetLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, 15743d4c4710SBarry Smith @*/ 1575d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 1576d71ae5a4SJacob Faibussowitsch { 15773d4c4710SBarry Smith PetscFunctionBegin; 15780700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 15794f572ea9SToby Isaac PetscAssertPointer(maxFails, 2); 15803d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 15813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15823d4c4710SBarry Smith } 15833d4c4710SBarry Smith 1584c96a6f78SLois Curfman McInnes /*@ 1585b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1586c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1587c96a6f78SLois Curfman McInnes 1588c7afd0dbSLois Curfman McInnes Not Collective 1589c7afd0dbSLois Curfman McInnes 1590c96a6f78SLois Curfman McInnes Input Parameter: 1591f6dfbefdSBarry Smith . snes - `SNES` context 1592c96a6f78SLois Curfman McInnes 1593c96a6f78SLois Curfman McInnes Output Parameter: 1594c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1595c96a6f78SLois Curfman McInnes 1596dc4c0fb0SBarry Smith Level: intermediate 1597dc4c0fb0SBarry Smith 1598c96a6f78SLois Curfman McInnes Notes: 1599f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()` unless `SNESSetCountersReset()` is used. 1600c96a6f78SLois Curfman McInnes 1601f6dfbefdSBarry Smith If the linear solver fails inside the `SNESSolve()` the iterations for that call to the linear solver are not included. If you wish to count them 1602f6dfbefdSBarry Smith then call `KSPGetIterationNumber()` after the failed solve. 1603010be392SBarry Smith 16041cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESGetIterationNumber()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESSetCountersReset()` 1605c96a6f78SLois Curfman McInnes @*/ 1606d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLinearSolveIterations(SNES snes, PetscInt *lits) 1607d71ae5a4SJacob Faibussowitsch { 16083a40ed3dSBarry Smith PetscFunctionBegin; 16090700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 16104f572ea9SToby Isaac PetscAssertPointer(lits, 2); 1611c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 16123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1613c96a6f78SLois Curfman McInnes } 1614c96a6f78SLois Curfman McInnes 1615971e163fSPeter Brune /*@ 1616971e163fSPeter Brune SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations 1617f6dfbefdSBarry Smith are reset every time `SNESSolve()` is called. 1618971e163fSPeter Brune 1619c3339decSBarry Smith Logically Collective 1620971e163fSPeter Brune 1621d8d19677SJose E. Roman Input Parameters: 1622f6dfbefdSBarry Smith + snes - `SNES` context 1623f6dfbefdSBarry Smith - reset - whether to reset the counters or not, defaults to `PETSC_TRUE` 1624971e163fSPeter Brune 1625971e163fSPeter Brune Level: developer 1626971e163fSPeter Brune 16271cc06b55SBarry Smith .seealso: [](ch_snes), `SNESGetNumberFunctionEvals()`, `SNESGetLinearSolveIterations()`, `SNESGetNPC()` 1628971e163fSPeter Brune @*/ 1629d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetCountersReset(SNES snes, PetscBool reset) 1630d71ae5a4SJacob Faibussowitsch { 1631971e163fSPeter Brune PetscFunctionBegin; 1632971e163fSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1633971e163fSPeter Brune PetscValidLogicalCollectiveBool(snes, reset, 2); 1634971e163fSPeter Brune snes->counters_reset = reset; 16353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1636971e163fSPeter Brune } 1637971e163fSPeter Brune 16382999313aSBarry Smith /*@ 1639f6dfbefdSBarry Smith SNESSetKSP - Sets a `KSP` context for the `SNES` object to use 16402999313aSBarry Smith 1641f6dfbefdSBarry Smith Not Collective, but the `SNES` and `KSP` objects must live on the same MPI_Comm 16422999313aSBarry Smith 16432999313aSBarry Smith Input Parameters: 1644f6dfbefdSBarry Smith + snes - the `SNES` context 1645f6dfbefdSBarry Smith - ksp - the `KSP` context 16462999313aSBarry Smith 1647dc4c0fb0SBarry Smith Level: developer 1648dc4c0fb0SBarry Smith 16492999313aSBarry Smith Notes: 1650f6dfbefdSBarry Smith The `SNES` object already has its `KSP` object, you can obtain with `SNESGetKSP()` 16512999313aSBarry Smith so this routine is rarely needed. 16522999313aSBarry Smith 1653f6dfbefdSBarry Smith The `KSP` object that is already in the `SNES` object has its reference count 16542999313aSBarry Smith decreased by one. 16552999313aSBarry Smith 165642747ad1SJacob Faibussowitsch .seealso: [](ch_snes), `SNES`, `KSP`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()` 16572999313aSBarry Smith @*/ 1658d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetKSP(SNES snes, KSP ksp) 1659d71ae5a4SJacob Faibussowitsch { 16602999313aSBarry Smith PetscFunctionBegin; 16610700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 16620700a824SBarry Smith PetscValidHeaderSpecific(ksp, KSP_CLASSID, 2); 16632999313aSBarry Smith PetscCheckSameComm(snes, 1, ksp, 2); 16649566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ksp)); 16659566063dSJacob Faibussowitsch if (snes->ksp) PetscCall(PetscObjectDereference((PetscObject)snes->ksp)); 16662999313aSBarry Smith snes->ksp = ksp; 16673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16682999313aSBarry Smith } 16692999313aSBarry Smith 167052baeb72SSatish Balay /*@ 1671dc4c0fb0SBarry Smith SNESCreate - Creates a nonlinear solver context used to manage a set of nonlinear solves 16729b94acceSBarry Smith 1673d083f849SBarry Smith Collective 1674c7afd0dbSLois Curfman McInnes 1675f6dfbefdSBarry Smith Input Parameter: 1676906ed7ccSBarry Smith . comm - MPI communicator 16779b94acceSBarry Smith 16789b94acceSBarry Smith Output Parameter: 167920f4b53cSBarry Smith . outsnes - the new `SNES` context 16809b94acceSBarry Smith 1681c7afd0dbSLois Curfman McInnes Options Database Keys: 1682dc4c0fb0SBarry Smith + -snes_mf - Activates default matrix-free Jacobian-vector products, and no preconditioning matrix 1683dc4c0fb0SBarry Smith . -snes_mf_operator - Activates default matrix-free Jacobian-vector products, and a user-provided preconditioning matrix 1684dc4c0fb0SBarry Smith as set by `SNESSetJacobian()` 1685dc4c0fb0SBarry Smith . -snes_fd_coloring - uses a relative fast computation of the Jacobian using finite differences and a graph coloring 1686c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1687c1f60f51SBarry Smith 168836851e7fSLois Curfman McInnes Level: beginner 168936851e7fSLois Curfman McInnes 169095452b02SPatrick Sanan Developer Notes: 1691f6dfbefdSBarry Smith `SNES` always creates a `KSP` object even though many `SNES` methods do not use it. This is 1692efd4aadfSBarry Smith unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the 1693f6dfbefdSBarry Smith particular method does use `KSP` and regulates if the information about the `KSP` is printed 1694f6dfbefdSBarry Smith in `SNESView()`. 1695efd4aadfSBarry Smith 1696f6dfbefdSBarry Smith `TSSetFromOptions()` does call `SNESSetFromOptions()` which can lead to users being confused 1697f6dfbefdSBarry Smith by help messages about meaningless `SNES` options. 1698f6dfbefdSBarry Smith 1699dc4c0fb0SBarry Smith `SNES` always creates the snes->kspconvctx even though it is used by only one type. This should be fixed. 1700efd4aadfSBarry Smith 1701e4094ef1SJacob Faibussowitsch .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESDestroy()`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 17029b94acceSBarry Smith @*/ 1703d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESCreate(MPI_Comm comm, SNES *outsnes) 1704d71ae5a4SJacob Faibussowitsch { 17059b94acceSBarry Smith SNES snes; 1706fa9f3622SBarry Smith SNESKSPEW *kctx; 170737fcc0dbSBarry Smith 17083a40ed3dSBarry Smith PetscFunctionBegin; 17094f572ea9SToby Isaac PetscAssertPointer(outsnes, 2); 17100298fd71SBarry Smith *outsnes = NULL; 17119566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 17128ba1e511SMatthew Knepley 17139566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(snes, SNES_CLASSID, "SNES", "Nonlinear solver", "SNES", comm, SNESDestroy, SNESView)); 17147adad957SLisandro Dalcin 17158d359177SBarry Smith snes->ops->converged = SNESConvergedDefault; 17162c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 171788976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 17189b94acceSBarry Smith snes->max_its = 50; 17199750a799SBarry Smith snes->max_funcs = 10000; 17209b94acceSBarry Smith snes->norm = 0.0; 1721c1e67a49SFande Kong snes->xnorm = 0.0; 1722c1e67a49SFande Kong snes->ynorm = 0.0; 1723365a6726SPeter Brune snes->normschedule = SNES_NORM_ALWAYS; 17246c67d002SPeter Brune snes->functype = SNES_FUNCTION_DEFAULT; 17258ca48ce9SPierre Jolivet snes->rtol = PetscDefined(USE_REAL_SINGLE) ? 1.e-5 : 1.e-8; 1726b4874afaSBarry Smith snes->ttol = 0.0; 17278ca48ce9SPierre Jolivet snes->abstol = PetscDefined(USE_REAL_SINGLE) ? 1.e-25 : 1.e-50; 17288ca48ce9SPierre Jolivet snes->stol = PetscDefined(USE_REAL_SINGLE) ? 1.e-5 : 1.e-8; 17298ca48ce9SPierre Jolivet snes->deltatol = PetscDefined(USE_REAL_SINGLE) ? 1.e-6 : 1.e-12; 1730e37c518bSBarry Smith snes->divtol = 1.e4; 1731e37c518bSBarry Smith snes->rnorm0 = 0; 17329b94acceSBarry Smith snes->nfuncs = 0; 173350ffb88aSMatthew Knepley snes->numFailures = 0; 173450ffb88aSMatthew Knepley snes->maxFailures = 1; 17357a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1736e35cf81dSBarry Smith snes->lagjacobian = 1; 173737ec4e1aSPeter Brune snes->jac_iter = 0; 173837ec4e1aSPeter Brune snes->lagjac_persist = PETSC_FALSE; 1739a8054027SBarry Smith snes->lagpreconditioner = 1; 174037ec4e1aSPeter Brune snes->pre_iter = 0; 174137ec4e1aSPeter Brune snes->lagpre_persist = PETSC_FALSE; 1742639f9d9dSBarry Smith snes->numbermonitors = 0; 1743c4421ceaSFande Kong snes->numberreasonviews = 0; 17449e5d0892SLisandro Dalcin snes->data = NULL; 17454dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1746186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 17476f24a144SLois Curfman McInnes snes->nwork = 0; 17489e5d0892SLisandro Dalcin snes->work = NULL; 174958c9b817SLisandro Dalcin snes->nvwork = 0; 17509e5d0892SLisandro Dalcin snes->vwork = NULL; 1751758f92a0SBarry Smith snes->conv_hist_len = 0; 1752758f92a0SBarry Smith snes->conv_hist_max = 0; 17530298fd71SBarry Smith snes->conv_hist = NULL; 17540298fd71SBarry Smith snes->conv_hist_its = NULL; 1755758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1756971e163fSPeter Brune snes->counters_reset = PETSC_TRUE; 1757e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1758184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 1759efd4aadfSBarry Smith snes->npcside = PC_RIGHT; 1760b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled = 0; 1761c40d0f55SPeter Brune 1762d8f46077SPeter Brune snes->mf = PETSC_FALSE; 1763d8f46077SPeter Brune snes->mf_operator = PETSC_FALSE; 1764d8f46077SPeter Brune snes->mf_version = 1; 1765d8f46077SPeter Brune 17663d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 17673d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 17683d4c4710SBarry Smith 1769349187a7SBarry Smith snes->vizerotolerance = 1.e-8; 177076bd3646SJed Brown snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE; 1771349187a7SBarry Smith 17724fc747eaSLawrence Mitchell /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */ 17734fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 17744fc747eaSLawrence Mitchell 17759b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 17764dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&kctx)); 1777f5af7f23SKarl Rupp 17789b94acceSBarry Smith snes->kspconvctx = (void *)kctx; 17799b94acceSBarry Smith kctx->version = 2; 17800f0abf79SStefano Zampini kctx->rtol_0 = 0.3; /* Eisenstat and Walker suggest rtol_0=.5, but 17819b94acceSBarry Smith this was too large for some test cases */ 178275567043SBarry Smith kctx->rtol_last = 0.0; 17830f0abf79SStefano Zampini kctx->rtol_max = 0.9; 17849b94acceSBarry Smith kctx->gamma = 1.0; 17850f0abf79SStefano Zampini kctx->alpha = 0.5 * (1.0 + PetscSqrtReal(5.0)); 178671f87433Sdalcinl kctx->alpha2 = kctx->alpha; 17870f0abf79SStefano Zampini kctx->threshold = 0.1; 178875567043SBarry Smith kctx->lresid_last = 0.0; 178975567043SBarry Smith kctx->norm_last = 0.0; 17909b94acceSBarry Smith 17910f0abf79SStefano Zampini kctx->rk_last = 0.0; 17920f0abf79SStefano Zampini kctx->rk_last_2 = 0.0; 17930f0abf79SStefano Zampini kctx->rtol_last_2 = 0.0; 17940f0abf79SStefano Zampini kctx->v4_p1 = 0.1; 17950f0abf79SStefano Zampini kctx->v4_p2 = 0.4; 17960f0abf79SStefano Zampini kctx->v4_p3 = 0.7; 17970f0abf79SStefano Zampini kctx->v4_m1 = 0.8; 17980f0abf79SStefano Zampini kctx->v4_m2 = 0.5; 17990f0abf79SStefano Zampini kctx->v4_m3 = 0.1; 18000f0abf79SStefano Zampini kctx->v4_m4 = 0.5; 18010f0abf79SStefano Zampini 18029b94acceSBarry Smith *outsnes = snes; 18033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18049b94acceSBarry Smith } 18059b94acceSBarry Smith 180688f0584fSBarry Smith /*MC 1807f6dfbefdSBarry Smith SNESFunction - Functional form used to convey the nonlinear function to `SNES` in `SNESSetFunction()` 180888f0584fSBarry Smith 180988f0584fSBarry Smith Synopsis: 1810411c0326SBarry Smith #include "petscsnes.h" 1811411c0326SBarry Smith PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx); 181288f0584fSBarry Smith 1813c3339decSBarry Smith Collective 18141843f636SBarry Smith 181588f0584fSBarry Smith Input Parameters: 1816f6dfbefdSBarry Smith + snes - the `SNES` context 181788f0584fSBarry Smith . x - state at which to evaluate residual 1818f6dfbefdSBarry Smith - ctx - optional user-defined function context, passed in with `SNESSetFunction()` 181988f0584fSBarry Smith 182088f0584fSBarry Smith Output Parameter: 182188f0584fSBarry Smith . f - vector to put residual (function value) 182288f0584fSBarry Smith 1823878cb397SSatish Balay Level: intermediate 1824878cb397SSatish Balay 18251cc06b55SBarry Smith .seealso: [](ch_snes), `SNESSetFunction()`, `SNESGetFunction()` 182688f0584fSBarry Smith M*/ 182788f0584fSBarry Smith 18289b94acceSBarry Smith /*@C 18299b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 1830f6dfbefdSBarry Smith vector for use by the `SNES` routines in solving systems of nonlinear 18319b94acceSBarry Smith equations. 18329b94acceSBarry Smith 1833c3339decSBarry Smith Logically Collective 1834fee21e36SBarry Smith 1835c7afd0dbSLois Curfman McInnes Input Parameters: 1836f6dfbefdSBarry Smith + snes - the `SNES` context 1837dc4c0fb0SBarry Smith . r - vector to store function values, may be `NULL` 183820f4b53cSBarry Smith . f - function evaluation routine; for calling sequence see `SNESFunction` 1839c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1840dc4c0fb0SBarry Smith function evaluation routine (may be `NULL`) 18419b94acceSBarry Smith 184236851e7fSLois Curfman McInnes Level: beginner 184336851e7fSLois Curfman McInnes 18441cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetPicard()`, `SNESFunction` 18459b94acceSBarry Smith @*/ 1846d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunction(SNES snes, Vec r, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) 1847d71ae5a4SJacob Faibussowitsch { 18486cab3a1bSJed Brown DM dm; 18496cab3a1bSJed Brown 18503a40ed3dSBarry Smith PetscFunctionBegin; 18510700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1852d2a683ecSLisandro Dalcin if (r) { 1853d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r, VEC_CLASSID, 2); 1854d2a683ecSLisandro Dalcin PetscCheckSameComm(snes, 1, r, 2); 18559566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)r)); 18569566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_func)); 185785385478SLisandro Dalcin snes->vec_func = r; 1858d2a683ecSLisandro Dalcin } 18599566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 18609566063dSJacob Faibussowitsch PetscCall(DMSNESSetFunction(dm, f, ctx)); 186148a46eb9SPierre Jolivet if (f == SNESPicardComputeFunction) PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx)); 18623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18639b94acceSBarry Smith } 18649b94acceSBarry Smith 1865e4ed7901SPeter Brune /*@C 18660b4db180SJacob Faibussowitsch SNESSetInitialFunction - Set an already computed function evaluation at the initial guess to be reused by `SNESSolve()`. 1867e4ed7901SPeter Brune 1868c3339decSBarry Smith Logically Collective 1869e4ed7901SPeter Brune 1870e4ed7901SPeter Brune Input Parameters: 1871f6dfbefdSBarry Smith + snes - the `SNES` context 1872e4ed7901SPeter Brune - f - vector to store function value 1873e4ed7901SPeter Brune 1874dc4c0fb0SBarry Smith Level: developer 1875dc4c0fb0SBarry Smith 1876e4ed7901SPeter Brune Notes: 1877e4ed7901SPeter Brune This should not be modified during the solution procedure. 1878e4ed7901SPeter Brune 1879f6dfbefdSBarry Smith This is used extensively in the `SNESFAS` hierarchy and in nonlinear preconditioning. 1880e4ed7901SPeter Brune 18811cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESFAS`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetInitialFunctionNorm()` 1882e4ed7901SPeter Brune @*/ 1883d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1884d71ae5a4SJacob Faibussowitsch { 1885e4ed7901SPeter Brune Vec vec_func; 1886e4ed7901SPeter Brune 1887e4ed7901SPeter Brune PetscFunctionBegin; 1888e4ed7901SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1889e4ed7901SPeter Brune PetscValidHeaderSpecific(f, VEC_CLASSID, 2); 1890e4ed7901SPeter Brune PetscCheckSameComm(snes, 1, f, 2); 1891efd4aadfSBarry Smith if (snes->npcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) { 1892902f982fSPeter Brune snes->vec_func_init_set = PETSC_FALSE; 18933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1894902f982fSPeter Brune } 18959566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &vec_func, NULL, NULL)); 18969566063dSJacob Faibussowitsch PetscCall(VecCopy(f, vec_func)); 1897f5af7f23SKarl Rupp 1898217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 18993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1900e4ed7901SPeter Brune } 1901e4ed7901SPeter Brune 1902534ebe21SPeter Brune /*@ 1903f6dfbefdSBarry Smith SNESSetNormSchedule - Sets the `SNESNormSchedule` used in convergence and monitoring 1904f6dfbefdSBarry Smith of the `SNES` method, when norms are computed in the solving process 1905534ebe21SPeter Brune 1906c3339decSBarry Smith Logically Collective 1907534ebe21SPeter Brune 1908534ebe21SPeter Brune Input Parameters: 1909f6dfbefdSBarry Smith + snes - the `SNES` context 1910365a6726SPeter Brune - normschedule - the frequency of norm computation 1911534ebe21SPeter Brune 1912517f1916SMatthew G. Knepley Options Database Key: 191367b8a455SSatish Balay . -snes_norm_schedule <none, always, initialonly, finalonly, initialfinalonly> - set the schedule 1914517f1916SMatthew G. Knepley 1915dc4c0fb0SBarry Smith Level: advanced 1916dc4c0fb0SBarry Smith 1917534ebe21SPeter Brune Notes: 1918f6dfbefdSBarry Smith Only certain `SNES` methods support certain `SNESNormSchedules`. Most require evaluation 1919534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1920534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1921f6dfbefdSBarry Smith `SNESNGS` and the like do not require the norm of the function to be computed, and therefore 1922534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1923534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1924534ebe21SPeter Brune their solution. 1925534ebe21SPeter Brune 1926e4094ef1SJacob Faibussowitsch .seealso: [](ch_snes), `SNESNormSchedule`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()` 1927534ebe21SPeter Brune @*/ 1928d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule) 1929d71ae5a4SJacob Faibussowitsch { 1930534ebe21SPeter Brune PetscFunctionBegin; 1931534ebe21SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1932365a6726SPeter Brune snes->normschedule = normschedule; 19333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1934534ebe21SPeter Brune } 1935534ebe21SPeter Brune 1936534ebe21SPeter Brune /*@ 1937f6dfbefdSBarry Smith SNESGetNormSchedule - Gets the `SNESNormSchedule` used in convergence and monitoring 1938f6dfbefdSBarry Smith of the `SNES` method. 1939534ebe21SPeter Brune 1940c3339decSBarry Smith Logically Collective 1941534ebe21SPeter Brune 1942534ebe21SPeter Brune Input Parameters: 1943f6dfbefdSBarry Smith + snes - the `SNES` context 1944365a6726SPeter Brune - normschedule - the type of the norm used 1945534ebe21SPeter Brune 1946534ebe21SPeter Brune Level: advanced 1947534ebe21SPeter Brune 19481cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1949534ebe21SPeter Brune @*/ 1950d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule) 1951d71ae5a4SJacob Faibussowitsch { 1952534ebe21SPeter Brune PetscFunctionBegin; 1953534ebe21SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1954365a6726SPeter Brune *normschedule = snes->normschedule; 19553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1956534ebe21SPeter Brune } 1957534ebe21SPeter Brune 1958c5ce4427SMatthew G. Knepley /*@ 1959c5ce4427SMatthew G. Knepley SNESSetFunctionNorm - Sets the last computed residual norm. 1960c5ce4427SMatthew G. Knepley 1961c3339decSBarry Smith Logically Collective 1962c5ce4427SMatthew G. Knepley 1963c5ce4427SMatthew G. Knepley Input Parameters: 1964f6dfbefdSBarry Smith + snes - the `SNES` context 1965f6dfbefdSBarry Smith - norm - the value of the norm 1966c5ce4427SMatthew G. Knepley 1967c5ce4427SMatthew G. Knepley Level: developer 1968c5ce4427SMatthew G. Knepley 19691cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1970c5ce4427SMatthew G. Knepley @*/ 1971d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm) 1972d71ae5a4SJacob Faibussowitsch { 1973c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1974c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1975c5ce4427SMatthew G. Knepley snes->norm = norm; 19763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1977c5ce4427SMatthew G. Knepley } 1978c5ce4427SMatthew G. Knepley 1979c5ce4427SMatthew G. Knepley /*@ 1980c5ce4427SMatthew G. Knepley SNESGetFunctionNorm - Gets the last computed norm of the residual 1981c5ce4427SMatthew G. Knepley 1982c5ce4427SMatthew G. Knepley Not Collective 1983c5ce4427SMatthew G. Knepley 1984c5ce4427SMatthew G. Knepley Input Parameter: 1985f6dfbefdSBarry Smith . snes - the `SNES` context 1986c5ce4427SMatthew G. Knepley 1987c5ce4427SMatthew G. Knepley Output Parameter: 1988c5ce4427SMatthew G. Knepley . norm - the last computed residual norm 1989c5ce4427SMatthew G. Knepley 1990c5ce4427SMatthew G. Knepley Level: developer 1991c5ce4427SMatthew G. Knepley 19921cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1993c5ce4427SMatthew G. Knepley @*/ 1994d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm) 1995d71ae5a4SJacob Faibussowitsch { 1996c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1997c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 19984f572ea9SToby Isaac PetscAssertPointer(norm, 2); 1999c5ce4427SMatthew G. Knepley *norm = snes->norm; 20003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2001c5ce4427SMatthew G. Knepley } 2002c5ce4427SMatthew G. Knepley 2003c1e67a49SFande Kong /*@ 2004f6dfbefdSBarry Smith SNESGetUpdateNorm - Gets the last computed norm of the solution update 2005c1e67a49SFande Kong 2006c1e67a49SFande Kong Not Collective 2007c1e67a49SFande Kong 2008c1e67a49SFande Kong Input Parameter: 2009f6dfbefdSBarry Smith . snes - the `SNES` context 2010c1e67a49SFande Kong 2011c1e67a49SFande Kong Output Parameter: 2012c1e67a49SFande Kong . ynorm - the last computed update norm 2013c1e67a49SFande Kong 2014c1e67a49SFande Kong Level: developer 2015c1e67a49SFande Kong 2016f6dfbefdSBarry Smith Note: 2017f6dfbefdSBarry Smith The new solution is the current solution plus the update, so this norm is an indication of the size of the update 2018f6dfbefdSBarry Smith 20191cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()` 2020c1e67a49SFande Kong @*/ 2021d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetUpdateNorm(SNES snes, PetscReal *ynorm) 2022d71ae5a4SJacob Faibussowitsch { 2023c1e67a49SFande Kong PetscFunctionBegin; 2024c1e67a49SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 20254f572ea9SToby Isaac PetscAssertPointer(ynorm, 2); 2026c1e67a49SFande Kong *ynorm = snes->ynorm; 20273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2028c1e67a49SFande Kong } 2029c1e67a49SFande Kong 2030c1e67a49SFande Kong /*@ 20314591eaf2SFande Kong SNESGetSolutionNorm - Gets the last computed norm of the solution 2032c1e67a49SFande Kong 2033c1e67a49SFande Kong Not Collective 2034c1e67a49SFande Kong 2035c1e67a49SFande Kong Input Parameter: 2036f6dfbefdSBarry Smith . snes - the `SNES` context 2037c1e67a49SFande Kong 2038c1e67a49SFande Kong Output Parameter: 2039c1e67a49SFande Kong . xnorm - the last computed solution norm 2040c1e67a49SFande Kong 2041c1e67a49SFande Kong Level: developer 2042c1e67a49SFande Kong 20431cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()`, `SNESGetUpdateNorm()` 2044c1e67a49SFande Kong @*/ 2045d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolutionNorm(SNES snes, PetscReal *xnorm) 2046d71ae5a4SJacob Faibussowitsch { 2047c1e67a49SFande Kong PetscFunctionBegin; 2048c1e67a49SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 20494f572ea9SToby Isaac PetscAssertPointer(xnorm, 2); 2050c1e67a49SFande Kong *xnorm = snes->xnorm; 20513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2052c1e67a49SFande Kong } 2053c1e67a49SFande Kong 205447073ea2SPeter Brune /*@C 2055f6dfbefdSBarry Smith SNESSetFunctionType - Sets the `SNESFunctionType` 2056f6dfbefdSBarry Smith of the `SNES` method. 205747073ea2SPeter Brune 2058c3339decSBarry Smith Logically Collective 205947073ea2SPeter Brune 206047073ea2SPeter Brune Input Parameters: 2061f6dfbefdSBarry Smith + snes - the `SNES` context 2062f6dfbefdSBarry Smith - type - the function type 206347073ea2SPeter Brune 206447073ea2SPeter Brune Level: developer 206547073ea2SPeter Brune 2066f6dfbefdSBarry Smith Notes: 2067f6dfbefdSBarry Smith Possible values of the function type 2068f6dfbefdSBarry Smith + `SNES_FUNCTION_DEFAULT` - the default for the given `SNESType` 2069f6dfbefdSBarry Smith . `SNES_FUNCTION_UNPRECONDITIONED` - an unpreconditioned function evaluation (this is the function provided with `SNESSetFunction()` 2070f6dfbefdSBarry Smith - `SNES_FUNCTION_PRECONDITIONED` - a transformation of the function provided with `SNESSetFunction()` 2071f6dfbefdSBarry Smith 2072f6dfbefdSBarry Smith Different `SNESType`s use this value in different ways 2073f6dfbefdSBarry Smith 20741cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESFunctionType`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 207547073ea2SPeter Brune @*/ 2076d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type) 2077d71ae5a4SJacob Faibussowitsch { 207847073ea2SPeter Brune PetscFunctionBegin; 207947073ea2SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 208047073ea2SPeter Brune snes->functype = type; 20813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 208247073ea2SPeter Brune } 208347073ea2SPeter Brune 208447073ea2SPeter Brune /*@C 2085f6dfbefdSBarry Smith SNESGetFunctionType - Gets the `SNESFunctionType` used in convergence and monitoring set with `SNESSetFunctionType()` 208647073ea2SPeter Brune of the SNES method. 208747073ea2SPeter Brune 2088c3339decSBarry Smith Logically Collective 208947073ea2SPeter Brune 209047073ea2SPeter Brune Input Parameters: 2091f6dfbefdSBarry Smith + snes - the `SNES` context 2092f6dfbefdSBarry Smith - type - the type of the function evaluation, see `SNESSetFunctionType()` 209347073ea2SPeter Brune 209447073ea2SPeter Brune Level: advanced 209547073ea2SPeter Brune 20961cc06b55SBarry Smith .seealso: [](ch_snes), `SNESSetFunctionType()`, `SNESFunctionType`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 209747073ea2SPeter Brune @*/ 2098d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type) 2099d71ae5a4SJacob Faibussowitsch { 210047073ea2SPeter Brune PetscFunctionBegin; 210147073ea2SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 210247073ea2SPeter Brune *type = snes->functype; 21033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2104534ebe21SPeter Brune } 2105534ebe21SPeter Brune 2106c79ef259SPeter Brune /*@C 2107be95d8f1SBarry Smith SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for 2108c79ef259SPeter Brune use with composed nonlinear solvers. 2109c79ef259SPeter Brune 2110c79ef259SPeter Brune Input Parameters: 2111dc4c0fb0SBarry Smith + snes - the `SNES` context 211237fdd005SBarry Smith . f - function evaluation routine to apply Gauss-Seidel 2113c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 2114dc4c0fb0SBarry Smith smoother evaluation routine (may be `NULL`) 2115c79ef259SPeter Brune 211620f4b53cSBarry Smith Calling sequence of `f`: 21170b4db180SJacob Faibussowitsch $ PetscErrorCode f(SNES snes, Vec X, Vec B, void *ctx); 2118f6dfbefdSBarry Smith + snes - the `SNES` context 2119f6dfbefdSBarry Smith . X - the current solution 2120dc4c0fb0SBarry Smith . B - the right hand side vector (which may be `NULL`) 2121f6dfbefdSBarry Smith - ctx - a user provided context 2122f6dfbefdSBarry Smith 2123dc4c0fb0SBarry Smith Level: intermediate 2124dc4c0fb0SBarry Smith 2125f6dfbefdSBarry Smith Note: 2126f6dfbefdSBarry Smith The `SNESNGS` routines are used by the composed nonlinear solver to generate 2127f6dfbefdSBarry Smith a problem appropriate update to the solution, particularly `SNESFAS`. 2128c79ef259SPeter Brune 21291cc06b55SBarry Smith .seealso: [](ch_snes), `SNESGetNGS()`, `SNESNCG`, `SNESGetFunction()`, `SNESComputeNGS()` 2130c79ef259SPeter Brune @*/ 21310b4db180SJacob Faibussowitsch PetscErrorCode SNESSetNGS(SNES snes, PetscErrorCode (*f)(SNES snes, Vec X, Vec B, void *ctx), void *ctx) 2132d71ae5a4SJacob Faibussowitsch { 21336cab3a1bSJed Brown DM dm; 21346cab3a1bSJed Brown 2135646217ecSPeter Brune PetscFunctionBegin; 21366cab3a1bSJed Brown PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 21379566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21389566063dSJacob Faibussowitsch PetscCall(DMSNESSetNGS(dm, f, ctx)); 21393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2140646217ecSPeter Brune } 2141646217ecSPeter Brune 2142bbc1464cSBarry Smith /* 2143bbc1464cSBarry Smith This is used for -snes_mf_operator; it uses a duplicate of snes->jacobian_pre because snes->jacobian_pre cannot be 2144bbc1464cSBarry Smith changed during the KSPSolve() 2145bbc1464cSBarry Smith */ 2146d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeMFFunction(SNES snes, Vec x, Vec f, void *ctx) 2147d71ae5a4SJacob Faibussowitsch { 2148bbc1464cSBarry Smith DM dm; 2149bbc1464cSBarry Smith DMSNES sdm; 2150bbc1464cSBarry Smith 2151bbc1464cSBarry Smith PetscFunctionBegin; 21529566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21539566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 2154bbc1464cSBarry Smith /* A(x)*x - b(x) */ 2155bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 2156792fecdfSBarry Smith PetscCallBack("SNES Picard callback function", (*sdm->ops->computepfunction)(snes, x, f, sdm->pctx)); 21579566063dSJacob Faibussowitsch PetscCall(VecScale(f, -1.0)); 21580df40c35SBarry Smith /* Cannot share nonzero pattern because of the possible use of SNESComputeJacobianDefault() */ 2159ef1023bdSBarry Smith if (!snes->picard) PetscCall(MatDuplicate(snes->jacobian_pre, MAT_DO_NOT_COPY_VALUES, &snes->picard)); 2160792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx)); 21619566063dSJacob Faibussowitsch PetscCall(MatMultAdd(snes->picard, x, f, f)); 2162bbc1464cSBarry Smith } else { 2163792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx)); 21649566063dSJacob Faibussowitsch PetscCall(MatMult(snes->picard, x, f)); 2165bbc1464cSBarry Smith } 21663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2167bbc1464cSBarry Smith } 2168bbc1464cSBarry Smith 2169d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeFunction(SNES snes, Vec x, Vec f, void *ctx) 2170d71ae5a4SJacob Faibussowitsch { 2171e03ab78fSPeter Brune DM dm; 2172942e3340SBarry Smith DMSNES sdm; 21736cab3a1bSJed Brown 21748b0a5094SBarry Smith PetscFunctionBegin; 21759566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21769566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 21778b0a5094SBarry Smith /* A(x)*x - b(x) */ 2178bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 2179792fecdfSBarry Smith PetscCallBack("SNES Picard callback function", (*sdm->ops->computepfunction)(snes, x, f, sdm->pctx)); 21809566063dSJacob Faibussowitsch PetscCall(VecScale(f, -1.0)); 2181792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx)); 21829566063dSJacob Faibussowitsch PetscCall(MatMultAdd(snes->jacobian_pre, x, f, f)); 2183bbc1464cSBarry Smith } else { 2184792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx)); 21859566063dSJacob Faibussowitsch PetscCall(MatMult(snes->jacobian_pre, x, f)); 2186bbc1464cSBarry Smith } 21873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21888b0a5094SBarry Smith } 21898b0a5094SBarry Smith 2190d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeJacobian(SNES snes, Vec x1, Mat J, Mat B, void *ctx) 2191d71ae5a4SJacob Faibussowitsch { 21928b0a5094SBarry Smith PetscFunctionBegin; 2193e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 2194bbc1464cSBarry Smith /* must assembly if matrix-free to get the last SNES solution */ 21959566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY)); 21969566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY)); 21973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21988b0a5094SBarry Smith } 21998b0a5094SBarry Smith 22008b0a5094SBarry Smith /*@C 2201f6dfbefdSBarry Smith SNESSetPicard - Use `SNES` to solve the system A(x) x = bp(x) + b via a Picard type iteration (Picard linearization) 22028b0a5094SBarry Smith 2203c3339decSBarry Smith Logically Collective 22048b0a5094SBarry Smith 22058b0a5094SBarry Smith Input Parameters: 2206f6dfbefdSBarry Smith + snes - the `SNES` context 2207dc4c0fb0SBarry Smith . r - vector to store function values, may be `NULL` 2208dc4c0fb0SBarry Smith . bp - function evaluation routine, may be `NULL` 22096b7fb656SBarry Smith . Amat - matrix with which A(x) x - bp(x) - b is to be computed 2210dc4c0fb0SBarry Smith . Pmat - matrix from which preconditioner is computed (usually the same as `Amat`) 221120f4b53cSBarry Smith . J - function to compute matrix values, for the calling sequence see `SNESJacobianFunction()` 2212dc4c0fb0SBarry Smith - ctx - [optional] user-defined context for private data for the function evaluation routine (may be `NULL`) 2213dc4c0fb0SBarry Smith 2214dc4c0fb0SBarry Smith Level: intermediate 22158b0a5094SBarry Smith 22168b0a5094SBarry Smith Notes: 22176b7fb656SBarry Smith It is often better to provide the nonlinear function F() and some approximation to its Jacobian directly and use 2218f450aa47SBarry Smith an approximate Newton solver. This interface is provided to allow porting/testing a previous Picard based code in PETSc before converting it to approximate Newton. 2219f450aa47SBarry Smith 2220f6dfbefdSBarry Smith One can call `SNESSetPicard()` or `SNESSetFunction()` (and possibly `SNESSetJacobian()`) but cannot call both 22218b0a5094SBarry Smith 2222dc4c0fb0SBarry Smith Solves the equation A(x) x = bp(x) - b via the defect correction algorithm A(x^{n}) (x^{n+1} - x^{n}) = bp(x^{n}) + b - A(x^{n})x^{n}. 2223dc4c0fb0SBarry Smith When an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = bp(x^{n}) + b iteration. 22248b0a5094SBarry Smith 2225dc4c0fb0SBarry Smith Run with `-snes_mf_operator` to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 22268b0a5094SBarry Smith 22270d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 22286b7fb656SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = bp(x^n) + b 22298b0a5094SBarry Smith 22308b0a5094SBarry 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 22318b0a5094SBarry 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 22328b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 22338b0a5094SBarry Smith 2234dc4c0fb0SBarry Smith When used with `-snes_mf_operator` this will run matrix-free Newton's method where the matrix-vector product is of the true Jacobian of A(x)x - bp(x) -b and 2235f6dfbefdSBarry Smith A(x^{n}) is used to build the preconditioner 22366b7fb656SBarry Smith 2237dc4c0fb0SBarry Smith When used with `-snes_fd` this will compute the true Jacobian (very slowly one column at at time) and thus represent Newton's method. 22386b7fb656SBarry Smith 2239dc4c0fb0SBarry Smith When used with `-snes_fd_coloring` this will compute the Jacobian via coloring and thus represent a faster implementation of Newton's method. But the 22406b7fb656SBarry Smith the nonzero structure of the Jacobian is, in general larger than that of the Picard matrix A so you must provide in A the needed nonzero structure for the correct 2241f6dfbefdSBarry Smith coloring. When using `DMDA` this may mean creating the matrix A with `DMCreateMatrix()` using a wider stencil than strictly needed for A or with a `DMDA_STENCIL_BOX`. 2242aaa8cc7dSPierre Jolivet See the comment in src/snes/tutorials/ex15.c. 2243bbc1464cSBarry Smith 22441cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESGetFunction()`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESGetPicard()`, `SNESLineSearchPreCheckPicard()`, `SNESJacobianFunction` 22458b0a5094SBarry Smith @*/ 2246d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetPicard(SNES snes, Vec r, PetscErrorCode (*bp)(SNES, Vec, Vec, void *), Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx) 2247d71ae5a4SJacob Faibussowitsch { 2248e03ab78fSPeter Brune DM dm; 2249e03ab78fSPeter Brune 22508b0a5094SBarry Smith PetscFunctionBegin; 22518b0a5094SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 22529566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 22539566063dSJacob Faibussowitsch PetscCall(DMSNESSetPicard(dm, bp, J, ctx)); 22549566063dSJacob Faibussowitsch PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx)); 22559566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes, r, SNESPicardComputeFunction, ctx)); 22569566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, Amat, Pmat, SNESPicardComputeJacobian, ctx)); 22573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22588b0a5094SBarry Smith } 22598b0a5094SBarry Smith 22607971a8bfSPeter Brune /*@C 22617971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 22627971a8bfSPeter Brune 2263f6dfbefdSBarry Smith Not Collective, but `Vec` is parallel if `SNES` is parallel. Collective if `Vec` is requested, but has not been created yet. 22647971a8bfSPeter Brune 22657971a8bfSPeter Brune Input Parameter: 2266f6dfbefdSBarry Smith . snes - the `SNES` context 22677971a8bfSPeter Brune 2268d8d19677SJose E. Roman Output Parameters: 2269dc4c0fb0SBarry Smith + r - the function (or `NULL`) 227020f4b53cSBarry Smith . f - the function (or `NULL`); for calling sequence see `SNESFunction` 2271dc4c0fb0SBarry Smith . Amat - the matrix used to defined the operation A(x) x - b(x) (or `NULL`) 2272dc4c0fb0SBarry Smith . Pmat - the matrix from which the preconditioner will be constructed (or `NULL`) 227320f4b53cSBarry Smith . J - the function for matrix evaluation (or `NULL`); for calling sequence see `SNESJacobianFunction` 2274dc4c0fb0SBarry Smith - ctx - the function context (or `NULL`) 22757971a8bfSPeter Brune 22767971a8bfSPeter Brune Level: advanced 22777971a8bfSPeter Brune 22781cc06b55SBarry Smith .seealso: [](ch_snes), `SNESSetFunction()`, `SNESSetPicard()`, `SNESGetFunction()`, `SNESGetJacobian()`, `SNESGetDM()`, `SNESFunction`, `SNESJacobianFunction` 22797971a8bfSPeter Brune @*/ 2280d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetPicard(SNES snes, Vec *r, PetscErrorCode (**f)(SNES, Vec, Vec, void *), Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES, Vec, Mat, Mat, void *), void **ctx) 2281d71ae5a4SJacob Faibussowitsch { 22827971a8bfSPeter Brune DM dm; 22837971a8bfSPeter Brune 22847971a8bfSPeter Brune PetscFunctionBegin; 22857971a8bfSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 22869566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, r, NULL, NULL)); 22879566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, Amat, Pmat, NULL, NULL)); 22889566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 22899566063dSJacob Faibussowitsch PetscCall(DMSNESGetPicard(dm, f, J, ctx)); 22903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22917971a8bfSPeter Brune } 22927971a8bfSPeter Brune 2293d25893d9SBarry Smith /*@C 2294dc4c0fb0SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the nonlinear problem 2295d25893d9SBarry Smith 2296c3339decSBarry Smith Logically Collective 2297d25893d9SBarry Smith 2298d25893d9SBarry Smith Input Parameters: 2299f6dfbefdSBarry Smith + snes - the `SNES` context 2300d25893d9SBarry Smith . func - function evaluation routine 2301d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 2302dc4c0fb0SBarry Smith function evaluation routine (may be `NULL`) 2303d25893d9SBarry Smith 230420f4b53cSBarry Smith Calling sequence of `func`: 230520f4b53cSBarry Smith $ PetscErrorCode func(SNES snes, Vec x, void *ctx); 230620f4b53cSBarry Smith + snes - the `SNES` solver 230720f4b53cSBarry Smith . x - vector to put initial guess 2308d25893d9SBarry Smith - ctx - optional user-defined function context 2309d25893d9SBarry Smith 2310d25893d9SBarry Smith Level: intermediate 2311d25893d9SBarry Smith 23121cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()` 2313d25893d9SBarry Smith @*/ 23140b4db180SJacob Faibussowitsch PetscErrorCode SNESSetComputeInitialGuess(SNES snes, PetscErrorCode (*func)(SNES snes, Vec x, void *ctx), void *ctx) 2315d71ae5a4SJacob Faibussowitsch { 2316d25893d9SBarry Smith PetscFunctionBegin; 2317d25893d9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2318d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 2319d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 23203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2321d25893d9SBarry Smith } 2322d25893d9SBarry Smith 23231096aae1SMatthew Knepley /*@C 2324dc4c0fb0SBarry Smith SNESGetRhs - Gets the vector for solving F(x) = `rhs`. If `rhs` is not set 23251096aae1SMatthew Knepley it assumes a zero right hand side. 23261096aae1SMatthew Knepley 2327c3339decSBarry Smith Logically Collective 23281096aae1SMatthew Knepley 23291096aae1SMatthew Knepley Input Parameter: 2330f6dfbefdSBarry Smith . snes - the `SNES` context 23311096aae1SMatthew Knepley 23321096aae1SMatthew Knepley Output Parameter: 2333dc4c0fb0SBarry Smith . rhs - the right hand side vector or `NULL` if the right hand side vector is null 23341096aae1SMatthew Knepley 23351096aae1SMatthew Knepley Level: intermediate 23361096aae1SMatthew Knepley 23371cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESGetSolution()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetFunction()` 23381096aae1SMatthew Knepley @*/ 2339d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetRhs(SNES snes, Vec *rhs) 2340d71ae5a4SJacob Faibussowitsch { 23411096aae1SMatthew Knepley PetscFunctionBegin; 23420700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 23434f572ea9SToby Isaac PetscAssertPointer(rhs, 2); 234485385478SLisandro Dalcin *rhs = snes->vec_rhs; 23453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23461096aae1SMatthew Knepley } 23471096aae1SMatthew Knepley 23489b94acceSBarry Smith /*@ 2349f6dfbefdSBarry Smith SNESComputeFunction - Calls the function that has been set with `SNESSetFunction()`. 23509b94acceSBarry Smith 2351c3339decSBarry Smith Collective 2352c7afd0dbSLois Curfman McInnes 23539b94acceSBarry Smith Input Parameters: 2354f6dfbefdSBarry Smith + snes - the `SNES` context 2355c7afd0dbSLois Curfman McInnes - x - input vector 23569b94acceSBarry Smith 23579b94acceSBarry Smith Output Parameter: 2358f6dfbefdSBarry Smith . y - function vector, as set by `SNESSetFunction()` 23599b94acceSBarry Smith 2360dc4c0fb0SBarry Smith Level: developer 2361dc4c0fb0SBarry Smith 2362f6dfbefdSBarry Smith Note: 2363f6dfbefdSBarry Smith `SNESComputeFunction()` is typically used within nonlinear solvers 2364bbc1464cSBarry Smith implementations, so users would not generally call this routine themselves. 236536851e7fSLois Curfman McInnes 23661cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeMFFunction()` 23679b94acceSBarry Smith @*/ 2368d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeFunction(SNES snes, Vec x, Vec y) 2369d71ae5a4SJacob Faibussowitsch { 23706cab3a1bSJed Brown DM dm; 2371942e3340SBarry Smith DMSNES sdm; 23729b94acceSBarry Smith 23733a40ed3dSBarry Smith PetscFunctionBegin; 23740700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 23750700a824SBarry Smith PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 23760700a824SBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2377c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, x, 2); 2378c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, y, 3); 2379e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE)); 2380184914b5SBarry Smith 23819566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 23829566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 23830fdf79fbSJacob Faibussowitsch PetscCheck(sdm->ops->computefunction || snes->vec_rhs, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 238432f3f7c2SPeter Brune if (sdm->ops->computefunction) { 238548a46eb9SPierre Jolivet if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0)); 23869566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(x)); 23878ddeebeaSSteve Benbow /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 23888ddeebeaSSteve Benbow snes->domainerror = PETSC_FALSE; 2389800f99ffSJeremy L Thompson { 2390800f99ffSJeremy L Thompson void *ctx; 2391800f99ffSJeremy L Thompson PetscErrorCode (*computefunction)(SNES, Vec, Vec, void *); 2392800f99ffSJeremy L Thompson PetscCall(DMSNESGetFunction(dm, &computefunction, &ctx)); 2393800f99ffSJeremy L Thompson PetscCallBack("SNES callback function", (*computefunction)(snes, x, y, ctx)); 2394800f99ffSJeremy L Thompson } 23959566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(x)); 239648a46eb9SPierre Jolivet if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0)); 23970fdf79fbSJacob Faibussowitsch } else /* if (snes->vec_rhs) */ { 23989566063dSJacob Faibussowitsch PetscCall(MatMult(snes->jacobian, x, y)); 23990fdf79fbSJacob Faibussowitsch } 24001baa6e33SBarry Smith if (snes->vec_rhs) PetscCall(VecAXPY(y, -1.0, snes->vec_rhs)); 2401ae3c334cSLois Curfman McInnes snes->nfuncs++; 2402422a814eSBarry Smith /* 2403422a814eSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2404422a814eSBarry Smith propagate the value to all processes 2405422a814eSBarry Smith */ 24061baa6e33SBarry Smith if (snes->domainerror) PetscCall(VecSetInf(y)); 24073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24089b94acceSBarry Smith } 24099b94acceSBarry Smith 2410c79ef259SPeter Brune /*@ 2411f6dfbefdSBarry Smith SNESComputeMFFunction - Calls the function that has been set with `SNESSetMFFunction()`. 2412bbc1464cSBarry Smith 2413c3339decSBarry Smith Collective 2414bbc1464cSBarry Smith 2415bbc1464cSBarry Smith Input Parameters: 2416f6dfbefdSBarry Smith + snes - the `SNES` context 2417bbc1464cSBarry Smith - x - input vector 2418bbc1464cSBarry Smith 2419bbc1464cSBarry Smith Output Parameter: 2420f6dfbefdSBarry Smith . y - function vector, as set by `SNESSetMFFunction()` 2421bbc1464cSBarry Smith 2422dc4c0fb0SBarry Smith Level: developer 2423dc4c0fb0SBarry Smith 2424bbc1464cSBarry Smith Notes: 2425f6dfbefdSBarry Smith `SNESComputeMFFunction()` is used within the matrix vector products called by the matrix created with `MatCreateSNESMF()` 2426bbc1464cSBarry Smith so users would not generally call this routine themselves. 2427bbc1464cSBarry Smith 2428f6dfbefdSBarry Smith Since this function is intended for use with finite differencing it does not subtract the right hand side vector provided with `SNESSolve()` 2429f6dfbefdSBarry Smith while `SNESComputeFunction()` does. As such, this routine cannot be used with `MatMFFDSetBase()` with a provided F function value even if it applies the 2430f6dfbefdSBarry Smith same function as `SNESComputeFunction()` if a `SNESSolve()` right hand side vector is use because the two functions difference would include this right hand side function. 2431bbc1464cSBarry Smith 24321cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeFunction()`, `MatCreateSNESMF` 2433bbc1464cSBarry Smith @*/ 2434d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeMFFunction(SNES snes, Vec x, Vec y) 2435d71ae5a4SJacob Faibussowitsch { 2436bbc1464cSBarry Smith DM dm; 2437bbc1464cSBarry Smith DMSNES sdm; 2438bbc1464cSBarry Smith 2439bbc1464cSBarry Smith PetscFunctionBegin; 2440bbc1464cSBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2441bbc1464cSBarry Smith PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2442bbc1464cSBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2443bbc1464cSBarry Smith PetscCheckSameComm(snes, 1, x, 2); 2444bbc1464cSBarry Smith PetscCheckSameComm(snes, 1, y, 3); 2445e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE)); 2446bbc1464cSBarry Smith 24479566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 24489566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 24499566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0)); 24509566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(x)); 2451bbc1464cSBarry Smith /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 2452bbc1464cSBarry Smith snes->domainerror = PETSC_FALSE; 2453792fecdfSBarry Smith PetscCallBack("SNES callback function", (*sdm->ops->computemffunction)(snes, x, y, sdm->mffunctionctx)); 24549566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(x)); 24559566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0)); 2456bbc1464cSBarry Smith snes->nfuncs++; 2457bbc1464cSBarry Smith /* 2458bbc1464cSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2459bbc1464cSBarry Smith propagate the value to all processes 2460bbc1464cSBarry Smith */ 24611baa6e33SBarry Smith if (snes->domainerror) PetscCall(VecSetInf(y)); 24623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2463bbc1464cSBarry Smith } 2464bbc1464cSBarry Smith 2465bbc1464cSBarry Smith /*@ 2466f6dfbefdSBarry Smith SNESComputeNGS - Calls the Gauss-Seidel function that has been set with `SNESSetNGS()`. 2467c79ef259SPeter Brune 2468c3339decSBarry Smith Collective 2469c79ef259SPeter Brune 2470c79ef259SPeter Brune Input Parameters: 2471f6dfbefdSBarry Smith + snes - the `SNES` context 2472c79ef259SPeter Brune . x - input vector 2473c79ef259SPeter Brune - b - rhs vector 2474c79ef259SPeter Brune 2475c79ef259SPeter Brune Output Parameter: 2476c79ef259SPeter Brune . x - new solution vector 2477c79ef259SPeter Brune 2478dc4c0fb0SBarry Smith Level: developer 2479dc4c0fb0SBarry Smith 2480f6dfbefdSBarry Smith Note: 2481f6dfbefdSBarry Smith `SNESComputeNGS()` is typically used within composed nonlinear solver 2482c79ef259SPeter Brune implementations, so most users would not generally call this routine 2483c79ef259SPeter Brune themselves. 2484c79ef259SPeter Brune 24851cc06b55SBarry Smith .seealso: [](ch_snes), `SNESNGS`, `SNESSetNGS()`, `SNESComputeFunction()` 2486c79ef259SPeter Brune @*/ 2487d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeNGS(SNES snes, Vec b, Vec x) 2488d71ae5a4SJacob Faibussowitsch { 24896cab3a1bSJed Brown DM dm; 2490942e3340SBarry Smith DMSNES sdm; 2491646217ecSPeter Brune 2492646217ecSPeter Brune PetscFunctionBegin; 2493646217ecSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2494064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 2495064a246eSJacob Faibussowitsch if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 2496064a246eSJacob Faibussowitsch PetscCheckSameComm(snes, 1, x, 3); 2497064a246eSJacob Faibussowitsch if (b) PetscCheckSameComm(snes, 1, b, 2); 2498e0f629ddSJacob Faibussowitsch if (b) PetscCall(VecValidValues_Internal(b, 2, PETSC_TRUE)); 24999566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_NGSEval, snes, x, b, 0)); 25009566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 25019566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 25020fdf79fbSJacob Faibussowitsch PetscCheck(sdm->ops->computegs, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 25039566063dSJacob Faibussowitsch if (b) PetscCall(VecLockReadPush(b)); 2504792fecdfSBarry Smith PetscCallBack("SNES callback NGS", (*sdm->ops->computegs)(snes, x, b, sdm->gsctx)); 25059566063dSJacob Faibussowitsch if (b) PetscCall(VecLockReadPop(b)); 25069566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_NGSEval, snes, x, b, 0)); 25073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2508646217ecSPeter Brune } 2509646217ecSPeter Brune 2510d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESTestJacobian(SNES snes) 2511d71ae5a4SJacob Faibussowitsch { 251212837594SBarry Smith Mat A, B, C, D, jacobian; 2513e885f1abSBarry Smith Vec x = snes->vec_sol, f = snes->vec_func; 2514e885f1abSBarry Smith PetscReal nrm, gnorm; 251581e7118cSBarry Smith PetscReal threshold = 1.e-5; 25160e276705SLisandro Dalcin MatType mattype; 2517e885f1abSBarry Smith PetscInt m, n, M, N; 2518e885f1abSBarry Smith void *functx; 25192cd624f9SStefano Zampini PetscBool complete_print = PETSC_FALSE, threshold_print = PETSC_FALSE, test = PETSC_FALSE, flg, istranspose; 25203325ff46SBarry Smith PetscViewer viewer, mviewer; 2521e885f1abSBarry Smith MPI_Comm comm; 2522e885f1abSBarry Smith PetscInt tabs; 252312837594SBarry Smith static PetscBool directionsprinted = PETSC_FALSE; 25243325ff46SBarry Smith PetscViewerFormat format; 2525e885f1abSBarry Smith 2526e885f1abSBarry Smith PetscFunctionBegin; 2527d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)snes); 25289566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-snes_test_jacobian", "Compare hand-coded and finite difference Jacobians", "None", &test)); 25299566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold, NULL)); 25309566063dSJacob Faibussowitsch PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display", "-snes_test_jacobian_view", "3.13", NULL)); 25314ead3382SBarry Smith PetscCall(PetscOptionsViewer("-snes_test_jacobian_view", "View difference between hand-coded and finite difference Jacobians element entries", "None", &mviewer, &format, &complete_print)); 25329566063dSJacob Faibussowitsch PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display_threshold", "-snes_test_jacobian", "3.13", "-snes_test_jacobian accepts an optional threshold (since v3.10)")); 25334ead3382SBarry Smith /* Cannot remove the what otherwise would be redundant call to (PetscOptionsReal("-snes_test_jacobian_display_threshold") below because its usage is different than the replacement usage */ 25349566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_test_jacobian_display_threshold", "Display difference between hand-coded and finite difference Jacobians which exceed input threshold", "None", threshold, &threshold, &threshold_print)); 2535d0609cedSBarry Smith PetscOptionsEnd(); 25363ba16761SJacob Faibussowitsch if (!test) PetscFunctionReturn(PETSC_SUCCESS); 2537e885f1abSBarry Smith 25389566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)snes, &comm)); 25399566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(comm, &viewer)); 25409566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tabs)); 25419566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel)); 25429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Jacobian -------------\n")); 254312837594SBarry Smith if (!complete_print && !directionsprinted) { 25449566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n")); 25459566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " of hand-coded and finite difference Jacobian entries greater than <threshold>.\n")); 254612837594SBarry Smith } 254712837594SBarry Smith if (!directionsprinted) { 25489566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n")); 25499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " O(1.e-8), the hand-coded Jacobian is probably correct.\n")); 255012837594SBarry Smith directionsprinted = PETSC_TRUE; 2551e885f1abSBarry Smith } 25521baa6e33SBarry Smith if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format)); 2553e885f1abSBarry Smith 25549566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes->jacobian, MATMFFD, &flg)); 255512837594SBarry Smith if (!flg) jacobian = snes->jacobian; 255612837594SBarry Smith else jacobian = snes->jacobian_pre; 255712837594SBarry Smith 2558a82339d0SMatthew G. Knepley if (!x) { 25599566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(jacobian, &x, NULL)); 2560a82339d0SMatthew G. Knepley } else { 25619566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)x)); 2562a82339d0SMatthew G. Knepley } 2563a82339d0SMatthew G. Knepley if (!f) { 25649566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &f)); 2565a82339d0SMatthew G. Knepley } else { 25669566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)f)); 2567a82339d0SMatthew G. Knepley } 2568a82339d0SMatthew G. Knepley /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */ 25699566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, x, f)); 25709566063dSJacob Faibussowitsch PetscCall(VecDestroy(&f)); 25719566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESKSPTRANSPOSEONLY, &istranspose)); 257212837594SBarry Smith while (jacobian) { 25732cd624f9SStefano Zampini Mat JT = NULL, Jsave = NULL; 25742cd624f9SStefano Zampini 25752cd624f9SStefano Zampini if (istranspose) { 25769566063dSJacob Faibussowitsch PetscCall(MatCreateTranspose(jacobian, &JT)); 25772cd624f9SStefano Zampini Jsave = jacobian; 25782cd624f9SStefano Zampini jacobian = JT; 25792cd624f9SStefano Zampini } 25809566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)jacobian, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ, "")); 258112837594SBarry Smith if (flg) { 258212837594SBarry Smith A = jacobian; 25839566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 258412837594SBarry Smith } else { 25859566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(jacobian, MATAIJ, &A)); 258612837594SBarry Smith } 2587e885f1abSBarry Smith 25889566063dSJacob Faibussowitsch PetscCall(MatGetType(A, &mattype)); 25899566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &M, &N)); 25909566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, &n)); 25919566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 25929566063dSJacob Faibussowitsch PetscCall(MatSetType(B, mattype)); 25939566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, m, n, M, N)); 25949566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizesFromMats(B, A, A)); 25959566063dSJacob Faibussowitsch PetscCall(MatSetUp(B)); 25969566063dSJacob Faibussowitsch PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 2597e885f1abSBarry Smith 25989566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 25999566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobianDefault(snes, x, B, B, functx)); 260012837594SBarry Smith 26019566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &D)); 26029566063dSJacob Faibussowitsch PetscCall(MatAYPX(D, -1.0, A, DIFFERENT_NONZERO_PATTERN)); 26039566063dSJacob Faibussowitsch PetscCall(MatNorm(D, NORM_FROBENIUS, &nrm)); 26049566063dSJacob Faibussowitsch PetscCall(MatNorm(A, NORM_FROBENIUS, &gnorm)); 26059566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 260612837594SBarry Smith if (!gnorm) gnorm = 1; /* just in case */ 26079566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n", (double)(nrm / gnorm), (double)nrm)); 260812837594SBarry Smith 2609e885f1abSBarry Smith if (complete_print) { 26109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded Jacobian ----------\n")); 26119566063dSJacob Faibussowitsch PetscCall(MatView(A, mviewer)); 26129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Finite difference Jacobian ----------\n")); 26139566063dSJacob Faibussowitsch PetscCall(MatView(B, mviewer)); 2614e885f1abSBarry Smith } 2615e885f1abSBarry Smith 2616df10fb39SFande Kong if (threshold_print || complete_print) { 2617e885f1abSBarry Smith PetscInt Istart, Iend, *ccols, bncols, cncols, j, row; 2618e885f1abSBarry Smith PetscScalar *cvals; 2619e885f1abSBarry Smith const PetscInt *bcols; 2620e885f1abSBarry Smith const PetscScalar *bvals; 2621e885f1abSBarry Smith 26229566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &C)); 26239566063dSJacob Faibussowitsch PetscCall(MatSetType(C, mattype)); 26249566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, M, N)); 26259566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizesFromMats(C, A, A)); 26269566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 26279566063dSJacob Faibussowitsch PetscCall(MatSetOption(C, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 26280e276705SLisandro Dalcin 26299566063dSJacob Faibussowitsch PetscCall(MatAYPX(B, -1.0, A, DIFFERENT_NONZERO_PATTERN)); 26309566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(B, &Istart, &Iend)); 2631e885f1abSBarry Smith 2632e885f1abSBarry Smith for (row = Istart; row < Iend; row++) { 26339566063dSJacob Faibussowitsch PetscCall(MatGetRow(B, row, &bncols, &bcols, &bvals)); 26349566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(bncols, &ccols, bncols, &cvals)); 2635e885f1abSBarry Smith for (j = 0, cncols = 0; j < bncols; j++) { 263623a52b1dSBarry Smith if (PetscAbsScalar(bvals[j]) > threshold) { 2637e885f1abSBarry Smith ccols[cncols] = bcols[j]; 2638e885f1abSBarry Smith cvals[cncols] = bvals[j]; 2639e885f1abSBarry Smith cncols += 1; 2640e885f1abSBarry Smith } 2641e885f1abSBarry Smith } 264248a46eb9SPierre Jolivet if (cncols) PetscCall(MatSetValues(C, 1, &row, cncols, ccols, cvals, INSERT_VALUES)); 26439566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(B, row, &bncols, &bcols, &bvals)); 26449566063dSJacob Faibussowitsch PetscCall(PetscFree2(ccols, cvals)); 2645e885f1abSBarry Smith } 26469566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY)); 26479566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY)); 26489566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n", (double)threshold)); 26499566063dSJacob Faibussowitsch PetscCall(MatView(C, complete_print ? mviewer : viewer)); 26509566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2651e885f1abSBarry Smith } 26529566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 26539566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 26549566063dSJacob Faibussowitsch PetscCall(MatDestroy(&JT)); 26552cd624f9SStefano Zampini if (Jsave) jacobian = Jsave; 265612837594SBarry Smith if (jacobian != snes->jacobian_pre) { 265712837594SBarry Smith jacobian = snes->jacobian_pre; 26589566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Jacobian for preconditioner -------------\n")); 26599371c9d4SSatish Balay } else jacobian = NULL; 266012837594SBarry Smith } 26619566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 26621baa6e33SBarry Smith if (complete_print) PetscCall(PetscViewerPopFormat(mviewer)); 26639566063dSJacob Faibussowitsch if (mviewer) PetscCall(PetscViewerDestroy(&mviewer)); 26649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tabs)); 26653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2666e885f1abSBarry Smith } 2667e885f1abSBarry Smith 266862fef451SLois Curfman McInnes /*@ 2669f6dfbefdSBarry Smith SNESComputeJacobian - Computes the Jacobian matrix that has been set with `SNESSetJacobian()`. 267062fef451SLois Curfman McInnes 2671c3339decSBarry Smith Collective 2672c7afd0dbSLois Curfman McInnes 267362fef451SLois Curfman McInnes Input Parameters: 2674f6dfbefdSBarry Smith + snes - the `SNES` context 2675e4094ef1SJacob Faibussowitsch - X - input vector 267662fef451SLois Curfman McInnes 267762fef451SLois Curfman McInnes Output Parameters: 2678c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 2679f6dfbefdSBarry Smith - B - optional matrix for building the preconditioner 2680fee21e36SBarry Smith 2681e35cf81dSBarry Smith Options Database Keys: 268267b8a455SSatish Balay + -snes_lag_preconditioner <lag> - how often to rebuild preconditioner 268367b8a455SSatish Balay . -snes_lag_jacobian <lag> - how often to rebuild Jacobian 2684455a5933SJed Brown . -snes_test_jacobian <optional threshold> - compare the user provided Jacobian with one compute via finite differences to check for errors. If a threshold is given, display only those entries whose difference is greater than the threshold. 2685455a5933SJed Brown . -snes_test_jacobian_view - display the user provided Jacobian, the finite difference Jacobian and the difference between them to help users detect the location of errors in the user provided Jacobian 2686693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2687693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2688693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 26894c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 269094d6a431SBarry Smith . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2691a5b23f4aSJose E. Roman . -snes_compare_coloring_display - Compute the finite difference Jacobian using coloring and display verbose differences 2692c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2693dc4c0fb0SBarry Smith . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by `-snes_compare_coloring_threshold` 2694dc4c0fb0SBarry Smith . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by `-snes_compare_coloring_threshold` 2695a5b23f4aSJose E. Roman . -snes_compare_coloring_draw - Compute the finite difference Jacobian using coloring and draw differences 2696a5b23f4aSJose E. Roman - -snes_compare_coloring_draw_contour - Compute the finite difference Jacobian using coloring and show contours of matrices and differences 2697c01495d3SJed Brown 2698dc4c0fb0SBarry Smith Level: developer 2699dc4c0fb0SBarry Smith 2700f6dfbefdSBarry Smith Note: 270162fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 270262fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 270362fef451SLois Curfman McInnes 2704e4094ef1SJacob Faibussowitsch Developer Notes: 2705dc4c0fb0SBarry Smith This has duplicative ways of checking the accuracy of the user provided Jacobian (see the options above). This is for historical reasons, the routine `SNESTestJacobian()` use to used 2706dc4c0fb0SBarry Smith for with the `SNESType` of test that has been removed. 2707e885f1abSBarry Smith 27081cc06b55SBarry Smith .seealso: [](ch_snes), `SNESSetJacobian()`, `KSPSetOperators()`, `MatStructure`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 270962fef451SLois Curfman McInnes @*/ 2710d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeJacobian(SNES snes, Vec X, Mat A, Mat B) 2711d71ae5a4SJacob Faibussowitsch { 2712ace3abfcSBarry Smith PetscBool flag; 27136cab3a1bSJed Brown DM dm; 2714942e3340SBarry Smith DMSNES sdm; 2715e0e3a89bSBarry Smith KSP ksp; 27163a40ed3dSBarry Smith 27173a40ed3dSBarry Smith PetscFunctionBegin; 27180700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 27190700a824SBarry Smith PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 2720c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, X, 2); 2721e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(X, 2, PETSC_TRUE)); 27229566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 27239566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 27243232da50SPeter Brune 272501c1178eSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix-free */ 2726fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2727fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2728f5af7f23SKarl Rupp 27299566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n")); 2730fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 27319566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is -1\n")); 27329566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag)); 2733ebd3b9afSBarry Smith if (flag) { 27349566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27359566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 2736ebd3b9afSBarry Smith } 27373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 273837ec4e1aSPeter Brune } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 273963a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagjacobian, snes->iter)); 27409566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag)); 2741ebd3b9afSBarry Smith if (flag) { 27429566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27439566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 2744ebd3b9afSBarry Smith } 27453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2746e35cf81dSBarry Smith } 2747efd4aadfSBarry Smith if (snes->npc && snes->npcside == PC_LEFT) { 27489566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27499566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 27503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2751d728fb7dSPeter Brune } 2752e35cf81dSBarry Smith 27539566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_JacobianEval, snes, X, A, B)); 27549566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 2755800f99ffSJeremy L Thompson { 2756800f99ffSJeremy L Thompson void *ctx; 2757800f99ffSJeremy L Thompson PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *); 2758800f99ffSJeremy L Thompson PetscCall(DMSNESGetJacobian(dm, &J, &ctx)); 2759800f99ffSJeremy L Thompson PetscCallBack("SNES callback Jacobian", (*J)(snes, X, A, B, ctx)); 2760800f99ffSJeremy L Thompson } 27619566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 27629566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_JacobianEval, snes, X, A, B)); 276328d58a37SPierre Jolivet 276428d58a37SPierre Jolivet /* attach latest linearization point to the preconditioning matrix */ 27659566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)B, "__SNES_latest_X", (PetscObject)X)); 2766a8054027SBarry Smith 2767e0e3a89bSBarry Smith /* the next line ensures that snes->ksp exists */ 27689566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 27693b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 27709566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Rebuilding preconditioner exactly once since lag is -2\n")); 27719566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE)); 27723b4f5425SBarry Smith snes->lagpreconditioner = -1; 27733b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 27749566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is -1\n")); 27759566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE)); 277637ec4e1aSPeter Brune } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 277763a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagpreconditioner, snes->iter)); 27789566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE)); 2779d1e9a80fSBarry Smith } else { 27809566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Rebuilding preconditioner\n")); 27819566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE)); 2782a8054027SBarry Smith } 2783a8054027SBarry Smith 27849566063dSJacob Faibussowitsch PetscCall(SNESTestJacobian(snes)); 27856d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 278694ab13aaSBarry Smith /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 278794ab13aaSBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2788693365a8SJed Brown { 2789693365a8SJed Brown PetscBool flag = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_operator = PETSC_FALSE; 27909566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit", NULL, NULL, &flag)); 27919566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw", NULL, NULL, &flag_draw)); 27929566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw_contour", NULL, NULL, &flag_contour)); 27939566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_operator", NULL, NULL, &flag_operator)); 2794693365a8SJed Brown if (flag || flag_draw || flag_contour) { 27950298fd71SBarry Smith Mat Bexp_mine = NULL, Bexp, FDexp; 2796693365a8SJed Brown PetscViewer vdraw, vstdout; 27976b3a5b13SJed Brown PetscBool flg; 2798693365a8SJed Brown if (flag_operator) { 27999566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(A, MATAIJ, &Bexp_mine)); 2800693365a8SJed Brown Bexp = Bexp_mine; 2801693365a8SJed Brown } else { 2802693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 28039566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)B, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPIBAIJ, "")); 280494ab13aaSBarry Smith if (flg) Bexp = B; 2805693365a8SJed Brown else { 2806693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 28079566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(B, MATAIJ, &Bexp_mine)); 2808693365a8SJed Brown Bexp = Bexp_mine; 2809693365a8SJed Brown } 2810693365a8SJed Brown } 28119566063dSJacob Faibussowitsch PetscCall(MatConvert(Bexp, MATSAME, MAT_INITIAL_MATRIX, &FDexp)); 28129566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobianDefault(snes, X, FDexp, FDexp, NULL)); 28139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout)); 2814693365a8SJed Brown if (flag_draw || flag_contour) { 28159566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Explicit Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw)); 28169566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 28170298fd71SBarry Smith } else vdraw = NULL; 28189566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit %s\n", flag_operator ? "Jacobian" : "preconditioning Jacobian")); 28199566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(Bexp, vstdout)); 28209566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(Bexp, vdraw)); 28219566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Finite difference Jacobian\n")); 28229566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(FDexp, vstdout)); 28239566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(FDexp, vdraw)); 28249566063dSJacob Faibussowitsch PetscCall(MatAYPX(FDexp, -1.0, Bexp, SAME_NONZERO_PATTERN)); 28259566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian\n")); 28269566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(FDexp, vstdout)); 2827693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 28289566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 28299566063dSJacob Faibussowitsch PetscCall(MatView(FDexp, vdraw)); 28309566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(vdraw)); 2831693365a8SJed Brown } 28329566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 28339566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&vdraw)); 28349566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bexp_mine)); 28359566063dSJacob Faibussowitsch PetscCall(MatDestroy(&FDexp)); 2836693365a8SJed Brown } 2837693365a8SJed Brown } 28384c30e9fbSJed Brown { 28396719d8e4SJed Brown PetscBool flag = PETSC_FALSE, flag_display = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_threshold = PETSC_FALSE; 28406719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON, threshold_rtol = 10 * PETSC_SQRT_MACHINE_EPSILON; 28419566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring", NULL, NULL, &flag)); 28429566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_display", NULL, NULL, &flag_display)); 28439566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw", NULL, NULL, &flag_draw)); 28449566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw_contour", NULL, NULL, &flag_contour)); 28459566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold", NULL, NULL, &flag_threshold)); 284627b0f280SBarry Smith if (flag_threshold) { 28479566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_rtol", &threshold_rtol, NULL)); 28489566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_atol", &threshold_atol, NULL)); 284927b0f280SBarry Smith } 28506719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 28514c30e9fbSJed Brown Mat Bfd; 28524c30e9fbSJed Brown PetscViewer vdraw, vstdout; 2853335efc43SPeter Brune MatColoring coloring; 28544c30e9fbSJed Brown ISColoring iscoloring; 28554c30e9fbSJed Brown MatFDColoring matfdcoloring; 28564c30e9fbSJed Brown PetscErrorCode (*func)(SNES, Vec, Vec, void *); 28574c30e9fbSJed Brown void *funcctx; 28586719d8e4SJed Brown PetscReal norm1, norm2, normmax; 28594c30e9fbSJed Brown 28609566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &Bfd)); 28619566063dSJacob Faibussowitsch PetscCall(MatColoringCreate(Bfd, &coloring)); 28629566063dSJacob Faibussowitsch PetscCall(MatColoringSetType(coloring, MATCOLORINGSL)); 28639566063dSJacob Faibussowitsch PetscCall(MatColoringSetFromOptions(coloring)); 28649566063dSJacob Faibussowitsch PetscCall(MatColoringApply(coloring, &iscoloring)); 28659566063dSJacob Faibussowitsch PetscCall(MatColoringDestroy(&coloring)); 28669566063dSJacob Faibussowitsch PetscCall(MatFDColoringCreate(Bfd, iscoloring, &matfdcoloring)); 28679566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 28689566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetUp(Bfd, iscoloring, matfdcoloring)); 28699566063dSJacob Faibussowitsch PetscCall(ISColoringDestroy(&iscoloring)); 28704c30e9fbSJed Brown 28714c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 28729566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, &func, &funcctx)); 28739566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFunction(matfdcoloring, (PetscErrorCode(*)(void))func, funcctx)); 28749566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring, ((PetscObject)snes)->prefix)); 28759566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring, "coloring_")); 28769566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 28779566063dSJacob Faibussowitsch PetscCall(MatFDColoringApply(Bfd, matfdcoloring, X, snes)); 28789566063dSJacob Faibussowitsch PetscCall(MatFDColoringDestroy(&matfdcoloring)); 28794c30e9fbSJed Brown 28809566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout)); 28814c30e9fbSJed Brown if (flag_draw || flag_contour) { 28829566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Colored Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw)); 28839566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 28840298fd71SBarry Smith } else vdraw = NULL; 28859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit preconditioning Jacobian\n")); 28869566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(B, vstdout)); 28879566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(B, vdraw)); 28889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Colored Finite difference Jacobian\n")); 28899566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(Bfd, vstdout)); 28909566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(Bfd, vdraw)); 28919566063dSJacob Faibussowitsch PetscCall(MatAYPX(Bfd, -1.0, B, SAME_NONZERO_PATTERN)); 28929566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_1, &norm1)); 28939566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_FROBENIUS, &norm2)); 28949566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_MAX, &normmax)); 28959566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n", (double)norm1, (double)norm2, (double)normmax)); 28969566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(Bfd, vstdout)); 28974c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 28989566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 28999566063dSJacob Faibussowitsch PetscCall(MatView(Bfd, vdraw)); 29009566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(vdraw)); 29014c30e9fbSJed Brown } 29029566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 29036719d8e4SJed Brown 29046719d8e4SJed Brown if (flag_threshold) { 29056719d8e4SJed Brown PetscInt bs, rstart, rend, i; 29069566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(B, &bs)); 29079566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(B, &rstart, &rend)); 29086719d8e4SJed Brown for (i = rstart; i < rend; i++) { 29096719d8e4SJed Brown const PetscScalar *ba, *ca; 29106719d8e4SJed Brown const PetscInt *bj, *cj; 29116719d8e4SJed Brown PetscInt bn, cn, j, maxentrycol = -1, maxdiffcol = -1, maxrdiffcol = -1; 29126719d8e4SJed Brown PetscReal maxentry = 0, maxdiff = 0, maxrdiff = 0; 29139566063dSJacob Faibussowitsch PetscCall(MatGetRow(B, i, &bn, &bj, &ba)); 29149566063dSJacob Faibussowitsch PetscCall(MatGetRow(Bfd, i, &cn, &cj, &ca)); 29155f80ce2aSJacob Faibussowitsch PetscCheck(bn == cn, ((PetscObject)A)->comm, PETSC_ERR_PLIB, "Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 29166719d8e4SJed Brown for (j = 0; j < bn; j++) { 29176719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j])); 29186719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 29196719d8e4SJed Brown maxentrycol = bj[j]; 29206719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 29216719d8e4SJed Brown } 29226719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 29236719d8e4SJed Brown maxdiffcol = bj[j]; 29246719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 29256719d8e4SJed Brown } 29266719d8e4SJed Brown if (rdiff > maxrdiff) { 29276719d8e4SJed Brown maxrdiffcol = bj[j]; 29286719d8e4SJed Brown maxrdiff = rdiff; 29296719d8e4SJed Brown } 29306719d8e4SJed Brown } 29316719d8e4SJed Brown if (maxrdiff > 1) { 293263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "row %" PetscInt_FMT " (maxentry=%g at %" PetscInt_FMT ", maxdiff=%g at %" PetscInt_FMT ", maxrdiff=%g at %" PetscInt_FMT "):", i, (double)maxentry, maxentrycol, (double)maxdiff, maxdiffcol, (double)maxrdiff, maxrdiffcol)); 29336719d8e4SJed Brown for (j = 0; j < bn; j++) { 29346719d8e4SJed Brown PetscReal rdiff; 29356719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j])); 293648a46eb9SPierre Jolivet if (rdiff > 1) PetscCall(PetscViewerASCIIPrintf(vstdout, " (%" PetscInt_FMT ",%g:%g)", bj[j], (double)PetscRealPart(ba[j]), (double)PetscRealPart(ca[j]))); 29376719d8e4SJed Brown } 293863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "\n")); 29396719d8e4SJed Brown } 29409566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(B, i, &bn, &bj, &ba)); 29419566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(Bfd, i, &cn, &cj, &ca)); 29426719d8e4SJed Brown } 29436719d8e4SJed Brown } 29449566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&vdraw)); 29459566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bfd)); 29464c30e9fbSJed Brown } 29474c30e9fbSJed Brown } 29483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29499b94acceSBarry Smith } 29509b94acceSBarry Smith 2951bf388a1fSBarry Smith /*MC 2952f6dfbefdSBarry Smith SNESJacobianFunction - Function used by `SNES` to compute the nonlinear Jacobian of the function to be solved by `SNES` 2953bf388a1fSBarry Smith 2954bf388a1fSBarry Smith Synopsis: 2955411c0326SBarry Smith #include "petscsnes.h" 2956411c0326SBarry Smith PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 2957bf388a1fSBarry Smith 2958c3339decSBarry Smith Collective 29591843f636SBarry Smith 29601843f636SBarry Smith Input Parameters: 29611843f636SBarry Smith + x - input vector, the Jacobian is to be computed at this value 2962bf388a1fSBarry Smith - ctx - [optional] user-defined Jacobian context 2963bf388a1fSBarry Smith 29641843f636SBarry Smith Output Parameters: 29651843f636SBarry Smith + Amat - the matrix that defines the (approximate) Jacobian 2966dc4c0fb0SBarry Smith - Pmat - the matrix to be used in constructing the preconditioner, usually the same as `Amat`. 29671843f636SBarry Smith 2968878cb397SSatish Balay Level: intermediate 2969878cb397SSatish Balay 29701cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESSetJacobian()`, `SNESGetJacobian()` 2971bf388a1fSBarry Smith M*/ 2972bf388a1fSBarry Smith 29739b94acceSBarry Smith /*@C 29749b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2975044dda88SLois Curfman McInnes location to store the matrix. 29769b94acceSBarry Smith 2977c3339decSBarry Smith Logically Collective 2978c7afd0dbSLois Curfman McInnes 29799b94acceSBarry Smith Input Parameters: 2980f6dfbefdSBarry Smith + snes - the `SNES` context 2981e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 2982dc4c0fb0SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as `Amat`. 2983dc4c0fb0SBarry Smith . J - Jacobian evaluation routine (if `NULL` then `SNES` retains any previously set value), see `SNESJacobianFunction` for details 2984c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2985dc4c0fb0SBarry Smith Jacobian evaluation routine (may be `NULL`) (if `NULL` then `SNES` retains any previously set value) 2986dc4c0fb0SBarry Smith 2987dc4c0fb0SBarry Smith Level: beginner 29889b94acceSBarry Smith 29899b94acceSBarry Smith Notes: 2990dc4c0fb0SBarry Smith If the `Amat` matrix and `Pmat` matrix are different you must call `MatAssemblyBegin()`/`MatAssemblyEnd()` on 299116913363SBarry Smith each matrix. 299216913363SBarry Smith 2993dc4c0fb0SBarry Smith If you know the operator `Amat` has a null space you can use `MatSetNullSpace()` and `MatSetTransposeNullSpace()` to supply the null 2994dc4c0fb0SBarry Smith space to `Amat` and the `KSP` solvers will automatically use that null space as needed during the solution process. 2995895c21f2SBarry Smith 2996dc4c0fb0SBarry Smith If using `SNESComputeJacobianDefaultColor()` to assemble a Jacobian, the `ctx` argument 2997f6dfbefdSBarry Smith must be a `MatFDColoring`. 2998a8a26c1eSJed Brown 2999c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 3000f6dfbefdSBarry Smith example is to use the "Picard linearization" which only differentiates through the highest order parts of each term using `SNESSetPicard()` 3001c3cc8fd1SJed Brown 30021cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `KSPSetOperators()`, `SNESSetFunction()`, `MatMFFDComputeJacobian()`, `SNESComputeJacobianDefaultColor()`, `MatStructure`, 3003db781477SPatrick Sanan `SNESSetPicard()`, `SNESJacobianFunction` 30049b94acceSBarry Smith @*/ 3005d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetJacobian(SNES snes, Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx) 3006d71ae5a4SJacob Faibussowitsch { 30076cab3a1bSJed Brown DM dm; 30083a7fca6bSBarry Smith 30093a40ed3dSBarry Smith PetscFunctionBegin; 30100700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3011e5d3d808SBarry Smith if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2); 3012e5d3d808SBarry Smith if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3); 3013e5d3d808SBarry Smith if (Amat) PetscCheckSameComm(snes, 1, Amat, 2); 3014e5d3d808SBarry Smith if (Pmat) PetscCheckSameComm(snes, 1, Pmat, 3); 30159566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 30169566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, J, ctx)); 3017e5d3d808SBarry Smith if (Amat) { 30189566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Amat)); 30199566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian)); 3020f5af7f23SKarl Rupp 3021e5d3d808SBarry Smith snes->jacobian = Amat; 30223a7fca6bSBarry Smith } 3023e5d3d808SBarry Smith if (Pmat) { 30249566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Pmat)); 30259566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian_pre)); 3026f5af7f23SKarl Rupp 3027e5d3d808SBarry Smith snes->jacobian_pre = Pmat; 30283a7fca6bSBarry Smith } 30293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30309b94acceSBarry Smith } 303162fef451SLois Curfman McInnes 3032c2aafc4cSSatish Balay /*@C 3033b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 3034b4fd4287SBarry Smith provided context for evaluating the Jacobian. 3035b4fd4287SBarry Smith 3036f6dfbefdSBarry Smith Not Collective, but `Mat` object will be parallel if `SNES` object is 3037c7afd0dbSLois Curfman McInnes 3038b4fd4287SBarry Smith Input Parameter: 3039b4fd4287SBarry Smith . snes - the nonlinear solver context 3040b4fd4287SBarry Smith 3041b4fd4287SBarry Smith Output Parameters: 3042dc4c0fb0SBarry Smith + Amat - location to stash (approximate) Jacobian matrix (or `NULL`) 3043dc4c0fb0SBarry Smith . Pmat - location to stash matrix used to compute the preconditioner (or `NULL`) 304420f4b53cSBarry Smith . J - location to put Jacobian function (or `NULL`), for calling sequence see `SNESJacobianFunction` 3045dc4c0fb0SBarry Smith - ctx - location to stash Jacobian ctx (or `NULL`) 3046fee21e36SBarry Smith 304736851e7fSLois Curfman McInnes Level: advanced 304836851e7fSLois Curfman McInnes 30491cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `Mat`, `SNESSetJacobian()`, `SNESComputeJacobian()`, `SNESJacobianFunction`, `SNESGetFunction()` 3050b4fd4287SBarry Smith @*/ 3051d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetJacobian(SNES snes, Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES, Vec, Mat, Mat, void *), void **ctx) 3052d71ae5a4SJacob Faibussowitsch { 30536cab3a1bSJed Brown DM dm; 30546cab3a1bSJed Brown 30553a40ed3dSBarry Smith PetscFunctionBegin; 30560700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3057e5d3d808SBarry Smith if (Amat) *Amat = snes->jacobian; 3058e5d3d808SBarry Smith if (Pmat) *Pmat = snes->jacobian_pre; 30599566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 3060800f99ffSJeremy L Thompson PetscCall(DMSNESGetJacobian(dm, J, ctx)); 30613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3062b4fd4287SBarry Smith } 3063b4fd4287SBarry Smith 3064d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes) 3065d71ae5a4SJacob Faibussowitsch { 306658b371f3SBarry Smith DM dm; 306758b371f3SBarry Smith DMSNES sdm; 306858b371f3SBarry Smith 306958b371f3SBarry Smith PetscFunctionBegin; 30709566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 30719566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 307258b371f3SBarry Smith if (!sdm->ops->computejacobian && snes->jacobian_pre) { 307358b371f3SBarry Smith DM dm; 307458b371f3SBarry Smith PetscBool isdense, ismf; 307558b371f3SBarry Smith 30769566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 30779566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &isdense, MATSEQDENSE, MATMPIDENSE, MATDENSE, NULL)); 30789566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &ismf, MATMFFD, MATSHELL, NULL)); 307958b371f3SBarry Smith if (isdense) { 30809566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefault, NULL)); 308158b371f3SBarry Smith } else if (!ismf) { 30829566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefaultColor, NULL)); 308358b371f3SBarry Smith } 308458b371f3SBarry Smith } 30853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 308658b371f3SBarry Smith } 308758b371f3SBarry Smith 30889b94acceSBarry Smith /*@ 30899b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 3090272ac6f2SLois Curfman McInnes of a nonlinear solver. 30919b94acceSBarry Smith 3092c3339decSBarry Smith Collective 3093fee21e36SBarry Smith 30942fe279fdSBarry Smith Input Parameter: 3095f6dfbefdSBarry Smith . snes - the `SNES` context 3096c7afd0dbSLois Curfman McInnes 3097dc4c0fb0SBarry Smith Level: advanced 3098dc4c0fb0SBarry Smith 3099f6dfbefdSBarry Smith Note: 3100f6dfbefdSBarry Smith For basic use of the `SNES` solvers the user need not explicitly call 3101f6dfbefdSBarry Smith `SNESSetUp()`, since these actions will automatically occur during 3102f6dfbefdSBarry Smith the call to `SNESSolve()`. However, if one wishes to control this 3103f6dfbefdSBarry Smith phase separately, `SNESSetUp()` should be called after `SNESCreate()` 3104f6dfbefdSBarry Smith and optional routines of the form SNESSetXXX(), but before `SNESSolve()`. 3105272ac6f2SLois Curfman McInnes 31061cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESCreate()`, `SNESSolve()`, `SNESDestroy()` 31079b94acceSBarry Smith @*/ 3108d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUp(SNES snes) 3109d71ae5a4SJacob Faibussowitsch { 31106cab3a1bSJed Brown DM dm; 3111942e3340SBarry Smith DMSNES sdm; 3112c35f09e5SBarry Smith SNESLineSearch linesearch, pclinesearch; 31136e2a1849SPeter Brune void *lsprectx, *lspostctx; 31149b5c1c08SStefano Zampini PetscBool mf_operator, mf; 31159b5c1c08SStefano Zampini Vec f, fpc; 31169b5c1c08SStefano Zampini void *funcctx; 31179b5c1c08SStefano Zampini void *jacctx, *appctx; 31189b5c1c08SStefano Zampini Mat j, jpre; 31196b2b7091SBarry Smith PetscErrorCode (*precheck)(SNESLineSearch, Vec, Vec, PetscBool *, void *); 31206b2b7091SBarry Smith PetscErrorCode (*postcheck)(SNESLineSearch, Vec, Vec, Vec, PetscBool *, PetscBool *, void *); 31216e2a1849SPeter Brune PetscErrorCode (*func)(SNES, Vec, Vec, void *); 3122d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *); 31233a40ed3dSBarry Smith 31243a40ed3dSBarry Smith PetscFunctionBegin; 31250700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 31263ba16761SJacob Faibussowitsch if (snes->setupcalled) PetscFunctionReturn(PETSC_SUCCESS); 3127fc8bc0e3SRichard Tran Mills PetscCall(PetscLogEventBegin(SNES_SetUp, snes, 0, 0, 0)); 31289b94acceSBarry Smith 312948a46eb9SPierre Jolivet if (!((PetscObject)snes)->type_name) PetscCall(SNESSetType(snes, SNESNEWTONLS)); 313085385478SLisandro Dalcin 31319566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &snes->vec_func, NULL, NULL)); 313258c9b817SLisandro Dalcin 31339566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31349566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 31359566063dSJacob Faibussowitsch PetscCall(SNESSetDefaultComputeJacobian(snes)); 313658b371f3SBarry Smith 313748a46eb9SPierre Jolivet if (!snes->vec_func) PetscCall(DMCreateGlobalVector(dm, &snes->vec_func)); 3138efd51863SBarry Smith 313948a46eb9SPierre Jolivet if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 3140b710008aSBarry Smith 3141d8d34be6SBarry Smith if (snes->linesearch) { 31429566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 31439566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFunction(snes->linesearch, SNESComputeFunction)); 3144d8d34be6SBarry Smith } 31459e764e56SPeter Brune 31469b5c1c08SStefano Zampini PetscCall(SNESGetUseMatrixFree(snes, &mf_operator, &mf)); 3147b552625fSStefano Zampini if (snes->npc && snes->npcside == PC_LEFT) { 3148172a4300SPeter Brune snes->mf = PETSC_TRUE; 3149172a4300SPeter Brune snes->mf_operator = PETSC_FALSE; 3150172a4300SPeter Brune } 3151d8f46077SPeter Brune 3152efd4aadfSBarry Smith if (snes->npc) { 31536e2a1849SPeter Brune /* copy the DM over */ 31549566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31559566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes->npc, dm)); 31566e2a1849SPeter Brune 31579566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &f, &func, &funcctx)); 31589566063dSJacob Faibussowitsch PetscCall(VecDuplicate(f, &fpc)); 31599566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes->npc, fpc, func, funcctx)); 31609566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, &j, &jpre, &jac, &jacctx)); 31619566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes->npc, j, jpre, jac, jacctx)); 31629566063dSJacob Faibussowitsch PetscCall(SNESGetApplicationContext(snes, &appctx)); 31639566063dSJacob Faibussowitsch PetscCall(SNESSetApplicationContext(snes->npc, appctx)); 31649b5c1c08SStefano Zampini PetscCall(SNESSetUseMatrixFree(snes->npc, mf_operator, mf)); 31659566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fpc)); 31666e2a1849SPeter Brune 31676e2a1849SPeter Brune /* copy the function pointers over */ 31689566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)snes->npc)); 31696e2a1849SPeter Brune 31706e2a1849SPeter Brune /* default to 1 iteration */ 31719566063dSJacob Faibussowitsch PetscCall(SNESSetTolerances(snes->npc, 0.0, 0.0, 0.0, 1, snes->npc->max_funcs)); 3172efd4aadfSBarry Smith if (snes->npcside == PC_RIGHT) { 31739566063dSJacob Faibussowitsch PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_FINAL_ONLY)); 3174a9936a0cSPeter Brune } else { 31759566063dSJacob Faibussowitsch PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_NONE)); 3176a9936a0cSPeter Brune } 31779566063dSJacob Faibussowitsch PetscCall(SNESSetFromOptions(snes->npc)); 31786e2a1849SPeter Brune 31796e2a1849SPeter Brune /* copy the line search context over */ 3180d8d34be6SBarry Smith if (snes->linesearch && snes->npc->linesearch) { 31819566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 31829566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes->npc, &pclinesearch)); 31839566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetPreCheck(linesearch, &precheck, &lsprectx)); 31849566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetPostCheck(linesearch, &postcheck, &lspostctx)); 31859566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetPreCheck(pclinesearch, precheck, lsprectx)); 31869566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetPostCheck(pclinesearch, postcheck, lspostctx)); 31879566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch)); 31886e2a1849SPeter Brune } 3189d8d34be6SBarry Smith } 31901baa6e33SBarry Smith if (snes->mf) PetscCall(SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version)); 319148a46eb9SPierre Jolivet if (snes->ops->usercompute && !snes->user) PetscCall((*snes->ops->usercompute)(snes, (void **)&snes->user)); 31926e2a1849SPeter Brune 319337ec4e1aSPeter Brune snes->jac_iter = 0; 319437ec4e1aSPeter Brune snes->pre_iter = 0; 319537ec4e1aSPeter Brune 3196dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, setup); 319758c9b817SLisandro Dalcin 31989566063dSJacob Faibussowitsch PetscCall(SNESSetDefaultComputeJacobian(snes)); 319958b371f3SBarry Smith 3200b552625fSStefano Zampini if (snes->npc && snes->npcside == PC_LEFT) { 32016c67d002SPeter Brune if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 3202d8d34be6SBarry Smith if (snes->linesearch) { 32039566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 32049566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFunction(linesearch, SNESComputeFunctionDefaultNPC)); 32056c67d002SPeter Brune } 32066c67d002SPeter Brune } 3207d8d34be6SBarry Smith } 3208fc8bc0e3SRichard Tran Mills PetscCall(PetscLogEventEnd(SNES_SetUp, snes, 0, 0, 0)); 32097aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 32103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32119b94acceSBarry Smith } 32129b94acceSBarry Smith 321337596af1SLisandro Dalcin /*@ 3214f6dfbefdSBarry Smith SNESReset - Resets a `SNES` context to the snessetupcalled = 0 state and removes any allocated `Vec`s and `Mat`s 321537596af1SLisandro Dalcin 3216c3339decSBarry Smith Collective 321737596af1SLisandro Dalcin 321837596af1SLisandro Dalcin Input Parameter: 3219f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 322037596af1SLisandro Dalcin 3221d25893d9SBarry Smith Level: intermediate 3222d25893d9SBarry Smith 322395452b02SPatrick Sanan Notes: 3224f6dfbefdSBarry Smith Call this if you wish to reuse a `SNES` but with different size vectors 322537596af1SLisandro Dalcin 3226f6dfbefdSBarry Smith Also calls the application context destroy routine set with `SNESSetComputeApplicationContext()` 3227f6dfbefdSBarry Smith 32281cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESDestroy()`, `SNESCreate()`, `SNESSetUp()`, `SNESSolve()` 322937596af1SLisandro Dalcin @*/ 3230d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESReset(SNES snes) 3231d71ae5a4SJacob Faibussowitsch { 323237596af1SLisandro Dalcin PetscFunctionBegin; 323337596af1SLisandro Dalcin PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3234d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 32359566063dSJacob Faibussowitsch PetscCall((*snes->ops->userdestroy)((void **)&snes->user)); 32360298fd71SBarry Smith snes->user = NULL; 3237d25893d9SBarry Smith } 32381baa6e33SBarry Smith if (snes->npc) PetscCall(SNESReset(snes->npc)); 32398a23116dSBarry Smith 3240dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, reset); 32411baa6e33SBarry Smith if (snes->ksp) PetscCall(KSPReset(snes->ksp)); 32429e764e56SPeter Brune 32431baa6e33SBarry Smith if (snes->linesearch) PetscCall(SNESLineSearchReset(snes->linesearch)); 32449e764e56SPeter Brune 32459566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_rhs)); 32469566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 32479566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol_update)); 32489566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_func)); 32499566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian)); 32509566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian_pre)); 32519566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->picard)); 32529566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(snes->nwork, &snes->work)); 32539566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(snes->nvwork, &snes->vwork)); 3254f5af7f23SKarl Rupp 325540fdac6aSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 325640fdac6aSLawrence Mitchell 325737596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 325837596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 32593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 326037596af1SLisandro Dalcin } 326137596af1SLisandro Dalcin 326252baeb72SSatish Balay /*@ 3263f6dfbefdSBarry Smith SNESConvergedReasonViewCancel - Clears all the reason view functions for a `SNES` object. 3264c4421ceaSFande Kong 3265c3339decSBarry Smith Collective 3266c4421ceaSFande Kong 3267c4421ceaSFande Kong Input Parameter: 3268f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 3269c4421ceaSFande Kong 3270c4421ceaSFande Kong Level: intermediate 3271c4421ceaSFande Kong 32721cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESReset()` 3273c4421ceaSFande Kong @*/ 3274d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewCancel(SNES snes) 3275d71ae5a4SJacob Faibussowitsch { 3276c4421ceaSFande Kong PetscInt i; 3277c4421ceaSFande Kong 3278c4421ceaSFande Kong PetscFunctionBegin; 3279c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3280c4421ceaSFande Kong for (i = 0; i < snes->numberreasonviews; i++) { 328148a46eb9SPierre Jolivet if (snes->reasonviewdestroy[i]) PetscCall((*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i])); 3282c4421ceaSFande Kong } 3283c4421ceaSFande Kong snes->numberreasonviews = 0; 32843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3285c4421ceaSFande Kong } 3286c4421ceaSFande Kong 32871fb7b255SJunchao Zhang /*@C 32889b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 3289f6dfbefdSBarry Smith with `SNESCreate()`. 32909b94acceSBarry Smith 3291c3339decSBarry Smith Collective 3292c7afd0dbSLois Curfman McInnes 32939b94acceSBarry Smith Input Parameter: 3294f6dfbefdSBarry Smith . snes - the `SNES` context 32959b94acceSBarry Smith 329636851e7fSLois Curfman McInnes Level: beginner 329736851e7fSLois Curfman McInnes 32981cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESCreate()`, `SNESSolve()` 32999b94acceSBarry Smith @*/ 3300d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESDestroy(SNES *snes) 3301d71ae5a4SJacob Faibussowitsch { 33023a40ed3dSBarry Smith PetscFunctionBegin; 33033ba16761SJacob Faibussowitsch if (!*snes) PetscFunctionReturn(PETSC_SUCCESS); 33046bf464f9SBarry Smith PetscValidHeaderSpecific((*snes), SNES_CLASSID, 1); 33059371c9d4SSatish Balay if (--((PetscObject)(*snes))->refct > 0) { 33069371c9d4SSatish Balay *snes = NULL; 33073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33089371c9d4SSatish Balay } 3309d4bb536fSBarry Smith 33109566063dSJacob Faibussowitsch PetscCall(SNESReset((*snes))); 33119566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&(*snes)->npc)); 33126b8b9a38SLisandro Dalcin 3313e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 33149566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsViewOff((PetscObject)*snes)); 3315dbbe0bcdSBarry Smith PetscTryTypeMethod((*snes), destroy); 33166d4c513bSLisandro Dalcin 33179566063dSJacob Faibussowitsch if ((*snes)->dm) PetscCall(DMCoarsenHookRemove((*snes)->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, *snes)); 33189566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*snes)->dm)); 33199566063dSJacob Faibussowitsch PetscCall(KSPDestroy(&(*snes)->ksp)); 33209566063dSJacob Faibussowitsch PetscCall(SNESLineSearchDestroy(&(*snes)->linesearch)); 33216b8b9a38SLisandro Dalcin 33229566063dSJacob Faibussowitsch PetscCall(PetscFree((*snes)->kspconvctx)); 332348a46eb9SPierre Jolivet if ((*snes)->ops->convergeddestroy) PetscCall((*(*snes)->ops->convergeddestroy)((*snes)->cnvP)); 332448a46eb9SPierre Jolivet if ((*snes)->conv_hist_alloc) PetscCall(PetscFree2((*snes)->conv_hist, (*snes)->conv_hist_its)); 33259566063dSJacob Faibussowitsch PetscCall(SNESMonitorCancel((*snes))); 33269566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonViewCancel((*snes))); 33279566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(snes)); 33283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33299b94acceSBarry Smith } 33309b94acceSBarry Smith 33319b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 33329b94acceSBarry Smith 3333a8054027SBarry Smith /*@ 3334a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 3335a8054027SBarry Smith 3336c3339decSBarry Smith Logically Collective 3337a8054027SBarry Smith 3338a8054027SBarry Smith Input Parameters: 3339f6dfbefdSBarry Smith + snes - the `SNES` context 3340d8e291bfSBarry Smith - lag - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 33413b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3342a8054027SBarry Smith 3343a8054027SBarry Smith Options Database Keys: 334479a4f3cfSmarkadams4 + -snes_lag_jacobian_persists <true,false> - sets the persistence through multiple SNES solves 33453d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 334679a4f3cfSmarkadams4 . -snes_lag_preconditioner_persists <true,false> - sets the persistence through multiple SNES solves 33473d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3348a8054027SBarry Smith 3349a8054027SBarry Smith Notes: 3350e4094ef1SJacob Faibussowitsch 3351dc4c0fb0SBarry Smith Level: intermediate 3352dc4c0fb0SBarry Smith 3353a8054027SBarry Smith The default is 1 3354f6dfbefdSBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagPreconditionerPersists()` was called 3355d8e291bfSBarry Smith 3356f6dfbefdSBarry Smith `SNESSetLagPreconditionerPersists()` allows using the same uniform lagging (for example every second linear solve) across multiple nonlinear solves. 3357a8054027SBarry Smith 33581cc06b55SBarry Smith .seealso: [](ch_snes), `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetLagPreconditionerPersists()`, 3359f6dfbefdSBarry Smith `SNESSetLagJacobianPersists()`, `SNES`, `SNESSolve()` 3360a8054027SBarry Smith @*/ 3361d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagPreconditioner(SNES snes, PetscInt lag) 3362d71ae5a4SJacob Faibussowitsch { 3363a8054027SBarry Smith PetscFunctionBegin; 33640700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 33655f80ce2aSJacob Faibussowitsch PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater"); 33665f80ce2aSJacob Faibussowitsch PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0"); 3367c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, lag, 2); 3368a8054027SBarry Smith snes->lagpreconditioner = lag; 33693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3370a8054027SBarry Smith } 3371a8054027SBarry Smith 3372efd51863SBarry Smith /*@ 3373f6dfbefdSBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that `SNES` will do 3374efd51863SBarry Smith 3375c3339decSBarry Smith Logically Collective 3376efd51863SBarry Smith 3377efd51863SBarry Smith Input Parameters: 3378f6dfbefdSBarry Smith + snes - the `SNES` context 3379efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 3380efd51863SBarry Smith 3381f6dfbefdSBarry Smith Options Database Key: 338267b8a455SSatish Balay . -snes_grid_sequence <steps> - Use grid sequencing to generate initial guess 3383efd51863SBarry Smith 3384efd51863SBarry Smith Level: intermediate 3385efd51863SBarry Smith 3386f6dfbefdSBarry Smith Note: 3387f6dfbefdSBarry Smith Use `SNESGetSolution()` to extract the fine grid solution after grid sequencing. 3388c0df2a02SJed Brown 33891cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetGridSequence()` 3390efd51863SBarry Smith @*/ 3391d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetGridSequence(SNES snes, PetscInt steps) 3392d71ae5a4SJacob Faibussowitsch { 3393efd51863SBarry Smith PetscFunctionBegin; 3394efd51863SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3395efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes, steps, 2); 3396efd51863SBarry Smith snes->gridsequence = steps; 33973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3398efd51863SBarry Smith } 3399efd51863SBarry Smith 3400fa19ca70SBarry Smith /*@ 3401f6dfbefdSBarry Smith SNESGetGridSequence - gets the number of steps of grid sequencing that `SNES` will do 3402fa19ca70SBarry Smith 3403c3339decSBarry Smith Logically Collective 3404fa19ca70SBarry Smith 3405fa19ca70SBarry Smith Input Parameter: 3406f6dfbefdSBarry Smith . snes - the `SNES` context 3407fa19ca70SBarry Smith 3408fa19ca70SBarry Smith Output Parameter: 3409fa19ca70SBarry Smith . steps - the number of refinements to do, defaults to 0 3410fa19ca70SBarry Smith 3411f6dfbefdSBarry Smith Options Database Key: 341267b8a455SSatish Balay . -snes_grid_sequence <steps> - set number of refinements 3413fa19ca70SBarry Smith 3414fa19ca70SBarry Smith Level: intermediate 3415fa19ca70SBarry Smith 3416f6dfbefdSBarry Smith Note: 3417f6dfbefdSBarry Smith Use `SNESGetSolution()` to extract the fine grid solution after grid sequencing. 3418fa19ca70SBarry Smith 34191cc06b55SBarry Smith .seealso: [](ch_snes), `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetGridSequence()` 3420fa19ca70SBarry Smith @*/ 3421d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetGridSequence(SNES snes, PetscInt *steps) 3422d71ae5a4SJacob Faibussowitsch { 3423fa19ca70SBarry Smith PetscFunctionBegin; 3424fa19ca70SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3425fa19ca70SBarry Smith *steps = snes->gridsequence; 34263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3427fa19ca70SBarry Smith } 3428fa19ca70SBarry Smith 3429a8054027SBarry Smith /*@ 3430f6dfbefdSBarry Smith SNESGetLagPreconditioner - Return how often the preconditioner is rebuilt 3431a8054027SBarry Smith 34323f9fe445SBarry Smith Not Collective 3433a8054027SBarry Smith 3434a8054027SBarry Smith Input Parameter: 3435f6dfbefdSBarry Smith . snes - the `SNES` context 3436a8054027SBarry Smith 3437a8054027SBarry Smith Output Parameter: 3438a8054027SBarry 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 34393b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3440a8054027SBarry Smith 3441a8054027SBarry Smith Options Database Keys: 344279a4f3cfSmarkadams4 + -snes_lag_jacobian_persists <true,false> - sets the persistence through multiple SNES solves 34433d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 344479a4f3cfSmarkadams4 . -snes_lag_preconditioner_persists <true,false> - sets the persistence through multiple SNES solves 34453d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3446a8054027SBarry Smith 3447dc4c0fb0SBarry Smith Level: intermediate 3448dc4c0fb0SBarry Smith 3449a8054027SBarry Smith Notes: 3450a8054027SBarry Smith The default is 1 3451f6dfbefdSBarry Smith 3452a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3453a8054027SBarry Smith 34541cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3455a8054027SBarry Smith @*/ 3456d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLagPreconditioner(SNES snes, PetscInt *lag) 3457d71ae5a4SJacob Faibussowitsch { 3458a8054027SBarry Smith PetscFunctionBegin; 34590700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3460a8054027SBarry Smith *lag = snes->lagpreconditioner; 34613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3462a8054027SBarry Smith } 3463a8054027SBarry Smith 3464e35cf81dSBarry Smith /*@ 3465f6dfbefdSBarry Smith SNESSetLagJacobian - Set when the Jacobian is rebuilt in the nonlinear solve. See `SNESSetLagPreconditioner()` for determining how 3466e35cf81dSBarry Smith often the preconditioner is rebuilt. 3467e35cf81dSBarry Smith 3468c3339decSBarry Smith Logically Collective 3469e35cf81dSBarry Smith 3470e35cf81dSBarry Smith Input Parameters: 3471f6dfbefdSBarry Smith + snes - the `SNES` context 3472e35cf81dSBarry 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 3473fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 3474e35cf81dSBarry Smith 3475e35cf81dSBarry Smith Options Database Keys: 347679a4f3cfSmarkadams4 + -snes_lag_jacobian_persists <true,false> - sets the persistence through multiple SNES solves 34773d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 347879a4f3cfSmarkadams4 . -snes_lag_preconditioner_persists <true,false> - sets the persistence through multiple SNES solves 34793d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag. 3480e35cf81dSBarry Smith 3481dc4c0fb0SBarry Smith Level: intermediate 3482dc4c0fb0SBarry Smith 3483e35cf81dSBarry Smith Notes: 3484e35cf81dSBarry Smith The default is 1 3485f6dfbefdSBarry Smith 3486e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3487f6dfbefdSBarry Smith 3488fe3ffe1eSBarry 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 3489fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 3490e35cf81dSBarry Smith 34911cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagPreconditioner()`, `SNESGetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3492e35cf81dSBarry Smith @*/ 3493d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagJacobian(SNES snes, PetscInt lag) 3494d71ae5a4SJacob Faibussowitsch { 3495e35cf81dSBarry Smith PetscFunctionBegin; 34960700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 34975f80ce2aSJacob Faibussowitsch PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater"); 34985f80ce2aSJacob Faibussowitsch PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0"); 3499c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, lag, 2); 3500e35cf81dSBarry Smith snes->lagjacobian = lag; 35013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3502e35cf81dSBarry Smith } 3503e35cf81dSBarry Smith 3504e35cf81dSBarry Smith /*@ 3505f6dfbefdSBarry Smith SNESGetLagJacobian - Get how often the Jacobian is rebuilt. See `SNESGetLagPreconditioner()` to determine when the preconditioner is rebuilt 3506e35cf81dSBarry Smith 35073f9fe445SBarry Smith Not Collective 3508e35cf81dSBarry Smith 3509e35cf81dSBarry Smith Input Parameter: 3510f6dfbefdSBarry Smith . snes - the `SNES` context 3511e35cf81dSBarry Smith 3512e35cf81dSBarry Smith Output Parameter: 3513e35cf81dSBarry 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 3514e35cf81dSBarry Smith the Jacobian is built etc. 3515e35cf81dSBarry Smith 3516dc4c0fb0SBarry Smith Level: intermediate 3517dc4c0fb0SBarry Smith 3518e35cf81dSBarry Smith Notes: 3519e35cf81dSBarry Smith The default is 1 3520f6dfbefdSBarry Smith 3521f6dfbefdSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagJacobianPersists()` was called. 3522e35cf81dSBarry Smith 35231cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetLagJacobian()`, `SNESSetLagPreconditioner()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3524e35cf81dSBarry Smith 3525e35cf81dSBarry Smith @*/ 3526d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLagJacobian(SNES snes, PetscInt *lag) 3527d71ae5a4SJacob Faibussowitsch { 3528e35cf81dSBarry Smith PetscFunctionBegin; 35290700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3530e35cf81dSBarry Smith *lag = snes->lagjacobian; 35313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3532e35cf81dSBarry Smith } 3533e35cf81dSBarry Smith 353437ec4e1aSPeter Brune /*@ 3535f6dfbefdSBarry Smith SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple nonlinear solves 353637ec4e1aSPeter Brune 3537c3339decSBarry Smith Logically collective 353837ec4e1aSPeter Brune 3539d8d19677SJose E. Roman Input Parameters: 3540f6dfbefdSBarry Smith + snes - the `SNES` context 35419d7e2deaSPeter Brune - flg - jacobian lagging persists if true 354237ec4e1aSPeter Brune 354337ec4e1aSPeter Brune Options Database Keys: 354479a4f3cfSmarkadams4 + -snes_lag_jacobian_persists <true,false> - sets the persistence through multiple SNES solves 35453d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 354679a4f3cfSmarkadams4 . -snes_lag_preconditioner_persists <true,false> - sets the persistence through multiple SNES solves 35473d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 35483d5a8a6aSBarry Smith 3549dc4c0fb0SBarry Smith Level: advanced 3550dc4c0fb0SBarry Smith 355195452b02SPatrick Sanan Notes: 3552f6dfbefdSBarry Smith Normally when `SNESSetLagJacobian()` is used, the Jacobian is always rebuilt at the beginning of each new nonlinear solve, this removes that. 3553f6dfbefdSBarry Smith 355495452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 355537ec4e1aSPeter Brune several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 355637ec4e1aSPeter Brune timesteps may present huge efficiency gains. 355737ec4e1aSPeter Brune 355842747ad1SJacob Faibussowitsch .seealso: [](ch_snes), `SNES`, `SNESSetLagPreconditionerPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()` 355937ec4e1aSPeter Brune @*/ 3560d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagJacobianPersists(SNES snes, PetscBool flg) 3561d71ae5a4SJacob Faibussowitsch { 356237ec4e1aSPeter Brune PetscFunctionBegin; 356337ec4e1aSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 356437ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes, flg, 2); 356537ec4e1aSPeter Brune snes->lagjac_persist = flg; 35663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 356737ec4e1aSPeter Brune } 356837ec4e1aSPeter Brune 356937ec4e1aSPeter Brune /*@ 3570d8e291bfSBarry Smith SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple nonlinear solves 357137ec4e1aSPeter Brune 3572c3339decSBarry Smith Logically Collective 357337ec4e1aSPeter Brune 3574d8d19677SJose E. Roman Input Parameters: 3575f6dfbefdSBarry Smith + snes - the `SNES` context 35769d7e2deaSPeter Brune - flg - preconditioner lagging persists if true 357737ec4e1aSPeter Brune 357837ec4e1aSPeter Brune Options Database Keys: 357979a4f3cfSmarkadams4 + -snes_lag_jacobian_persists <true,false> - sets the persistence through multiple SNES solves 35803d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 358179a4f3cfSmarkadams4 . -snes_lag_preconditioner_persists <true,false> - sets the persistence through multiple SNES solves 35823d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 358337ec4e1aSPeter Brune 3584dc4c0fb0SBarry Smith Level: developer 3585dc4c0fb0SBarry Smith 358695452b02SPatrick Sanan Notes: 3587f6dfbefdSBarry Smith Normally when `SNESSetLagPreconditioner()` is used, the preconditioner is always rebuilt at the beginning of each new nonlinear solve, this removes that. 3588f6dfbefdSBarry Smith 358995452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 359037ec4e1aSPeter Brune by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 359137ec4e1aSPeter Brune several timesteps may present huge efficiency gains. 359237ec4e1aSPeter Brune 35931cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetLagJacobianPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagPreconditioner()` 359437ec4e1aSPeter Brune @*/ 3595d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes, PetscBool flg) 3596d71ae5a4SJacob Faibussowitsch { 359737ec4e1aSPeter Brune PetscFunctionBegin; 359837ec4e1aSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 359937ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes, flg, 2); 360037ec4e1aSPeter Brune snes->lagpre_persist = flg; 36013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 360237ec4e1aSPeter Brune } 360337ec4e1aSPeter Brune 36049b94acceSBarry Smith /*@ 3605f6dfbefdSBarry Smith SNESSetForceIteration - force `SNESSolve()` to take at least one iteration regardless of the initial residual norm 3606be5caee7SBarry Smith 3607c3339decSBarry Smith Logically Collective 3608be5caee7SBarry Smith 3609be5caee7SBarry Smith Input Parameters: 3610f6dfbefdSBarry Smith + snes - the `SNES` context 3611f6dfbefdSBarry Smith - force - `PETSC_TRUE` require at least one iteration 3612be5caee7SBarry Smith 3613f6dfbefdSBarry Smith Options Database Key: 3614be5caee7SBarry Smith . -snes_force_iteration <force> - Sets forcing an iteration 3615be5caee7SBarry Smith 3616dc4c0fb0SBarry Smith Level: intermediate 3617dc4c0fb0SBarry Smith 3618f6dfbefdSBarry Smith Note: 3619f6dfbefdSBarry Smith This is used sometimes with `TS` to prevent `TS` from detecting a false steady state solution 3620be5caee7SBarry Smith 36211cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `TS`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 3622be5caee7SBarry Smith @*/ 3623d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetForceIteration(SNES snes, PetscBool force) 3624d71ae5a4SJacob Faibussowitsch { 3625be5caee7SBarry Smith PetscFunctionBegin; 3626be5caee7SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3627be5caee7SBarry Smith snes->forceiteration = force; 36283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3629be5caee7SBarry Smith } 3630be5caee7SBarry Smith 363185216dc7SFande Kong /*@ 3632f6dfbefdSBarry Smith SNESGetForceIteration - Check whether or not `SNESSolve()` take at least one iteration regardless of the initial residual norm 363385216dc7SFande Kong 3634c3339decSBarry Smith Logically Collective 363585216dc7SFande Kong 36362fe279fdSBarry Smith Input Parameter: 3637f6dfbefdSBarry Smith . snes - the `SNES` context 363885216dc7SFande Kong 363985216dc7SFande Kong Output Parameter: 3640dc4c0fb0SBarry Smith . force - `PETSC_TRUE` requires at least one iteration. 364185216dc7SFande Kong 364206dd6b0eSSatish Balay Level: intermediate 364306dd6b0eSSatish Balay 36441cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetForceIteration()`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 364585216dc7SFande Kong @*/ 3646d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetForceIteration(SNES snes, PetscBool *force) 3647d71ae5a4SJacob Faibussowitsch { 364885216dc7SFande Kong PetscFunctionBegin; 364985216dc7SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 365085216dc7SFande Kong *force = snes->forceiteration; 36513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 365285216dc7SFande Kong } 3653be5caee7SBarry Smith 3654be5caee7SBarry Smith /*@ 3655f6dfbefdSBarry Smith SNESSetTolerances - Sets `SNES` various parameters used in convergence tests. 36569b94acceSBarry Smith 3657c3339decSBarry Smith Logically Collective 3658c7afd0dbSLois Curfman McInnes 36599b94acceSBarry Smith Input Parameters: 3660f6dfbefdSBarry Smith + snes - the `SNES` context 366170441072SBarry Smith . abstol - absolute convergence tolerance 366233174efeSLois Curfman McInnes . rtol - relative convergence tolerance 36635358d0d4SBarry Smith . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 3664f6dfbefdSBarry Smith . maxit - maximum number of iterations, default 50. 3665f6dfbefdSBarry Smith - maxf - maximum number of function evaluations (-1 indicates no limit), default 1000 3666fee21e36SBarry Smith 366733174efeSLois Curfman McInnes Options Database Keys: 366870441072SBarry Smith + -snes_atol <abstol> - Sets abstol 3669c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 3670c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 3671c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 3672c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 36739b94acceSBarry Smith 367436851e7fSLois Curfman McInnes Level: intermediate 367536851e7fSLois Curfman McInnes 36761cc06b55SBarry Smith .seealso: [](ch_snes), `SNESolve()`, `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`, `SNESSetForceIteration()` 36779b94acceSBarry Smith @*/ 3678d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetTolerances(SNES snes, PetscReal abstol, PetscReal rtol, PetscReal stol, PetscInt maxit, PetscInt maxf) 3679d71ae5a4SJacob Faibussowitsch { 36803a40ed3dSBarry Smith PetscFunctionBegin; 36810700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3682c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, abstol, 2); 3683c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol, 3); 3684c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, stol, 4); 3685c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxit, 5); 3686c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxf, 6); 3687c5eb9154SBarry Smith 368813bcc0bdSJacob Faibussowitsch if (abstol != (PetscReal)PETSC_DEFAULT) { 36895f80ce2aSJacob Faibussowitsch PetscCheck(abstol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Absolute tolerance %g must be non-negative", (double)abstol); 3690ab54825eSJed Brown snes->abstol = abstol; 3691ab54825eSJed Brown } 369213bcc0bdSJacob Faibussowitsch if (rtol != (PetscReal)PETSC_DEFAULT) { 36935f80ce2aSJacob Faibussowitsch PetscCheck(rtol >= 0.0 && 1.0 > rtol, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Relative tolerance %g must be non-negative and less than 1.0", (double)rtol); 3694ab54825eSJed Brown snes->rtol = rtol; 3695ab54825eSJed Brown } 369613bcc0bdSJacob Faibussowitsch if (stol != (PetscReal)PETSC_DEFAULT) { 36975f80ce2aSJacob Faibussowitsch PetscCheck(stol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Step tolerance %g must be non-negative", (double)stol); 3698c60f73f4SPeter Brune snes->stol = stol; 3699ab54825eSJed Brown } 3700ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 370163a3b9bcSJacob Faibussowitsch PetscCheck(maxit >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of iterations %" PetscInt_FMT " must be non-negative", maxit); 3702ab54825eSJed Brown snes->max_its = maxit; 3703ab54825eSJed Brown } 3704ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 370563a3b9bcSJacob Faibussowitsch PetscCheck(maxf >= -1, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of function evaluations %" PetscInt_FMT " must be -1 or nonnegative", maxf); 3706ab54825eSJed Brown snes->max_funcs = maxf; 3707ab54825eSJed Brown } 370888976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 37093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37109b94acceSBarry Smith } 37119b94acceSBarry Smith 3712e4d06f11SPatrick Farrell /*@ 3713f6dfbefdSBarry Smith SNESSetDivergenceTolerance - Sets the divergence tolerance used for the `SNES` divergence test. 3714e4d06f11SPatrick Farrell 3715c3339decSBarry Smith Logically Collective 3716e4d06f11SPatrick Farrell 3717e4d06f11SPatrick Farrell Input Parameters: 3718f6dfbefdSBarry Smith + snes - the `SNES` context 3719f6dfbefdSBarry Smith - divtol - the divergence tolerance. Use -1 to deactivate the test, default is 1e4 3720e4d06f11SPatrick Farrell 3721f6dfbefdSBarry Smith Options Database Key: 3722dc4c0fb0SBarry Smith . -snes_divergence_tolerance <divtol> - Sets `divtol` 3723e4d06f11SPatrick Farrell 3724e4d06f11SPatrick Farrell Level: intermediate 3725e4d06f11SPatrick Farrell 37261cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetTolerances()`, `SNESGetDivergenceTolerance` 3727e4d06f11SPatrick Farrell @*/ 3728d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetDivergenceTolerance(SNES snes, PetscReal divtol) 3729d71ae5a4SJacob Faibussowitsch { 3730e4d06f11SPatrick Farrell PetscFunctionBegin; 3731e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3732e4d06f11SPatrick Farrell PetscValidLogicalCollectiveReal(snes, divtol, 2); 3733e4d06f11SPatrick Farrell 373413bcc0bdSJacob Faibussowitsch if (divtol != (PetscReal)PETSC_DEFAULT) { 3735e4d06f11SPatrick Farrell snes->divtol = divtol; 37369371c9d4SSatish Balay } else { 3737e4d06f11SPatrick Farrell snes->divtol = 1.0e4; 3738e4d06f11SPatrick Farrell } 37393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3740e4d06f11SPatrick Farrell } 3741e4d06f11SPatrick Farrell 37429b94acceSBarry Smith /*@ 374333174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 374433174efeSLois Curfman McInnes 3745c7afd0dbSLois Curfman McInnes Not Collective 3746c7afd0dbSLois Curfman McInnes 374733174efeSLois Curfman McInnes Input Parameters: 3748f6dfbefdSBarry Smith + snes - the `SNES` context 374985385478SLisandro Dalcin . atol - absolute convergence tolerance 375033174efeSLois Curfman McInnes . rtol - relative convergence tolerance 375133174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 375233174efeSLois Curfman McInnes of the change in the solution between steps 375333174efeSLois Curfman McInnes . maxit - maximum number of iterations 3754c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 3755fee21e36SBarry Smith 375636851e7fSLois Curfman McInnes Level: intermediate 375736851e7fSLois Curfman McInnes 3758dc4c0fb0SBarry Smith Note: 3759dc4c0fb0SBarry Smith The user can specify `NULL` for any parameter that is not needed. 3760dc4c0fb0SBarry Smith 37611cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetTolerances()` 376233174efeSLois Curfman McInnes @*/ 3763d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetTolerances(SNES snes, PetscReal *atol, PetscReal *rtol, PetscReal *stol, PetscInt *maxit, PetscInt *maxf) 3764d71ae5a4SJacob Faibussowitsch { 37653a40ed3dSBarry Smith PetscFunctionBegin; 37660700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 376785385478SLisandro Dalcin if (atol) *atol = snes->abstol; 376833174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 3769c60f73f4SPeter Brune if (stol) *stol = snes->stol; 377033174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 377133174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 37723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 377333174efeSLois Curfman McInnes } 377433174efeSLois Curfman McInnes 3775e4d06f11SPatrick Farrell /*@ 3776e4d06f11SPatrick Farrell SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test. 3777e4d06f11SPatrick Farrell 3778e4d06f11SPatrick Farrell Not Collective 3779e4d06f11SPatrick Farrell 3780e4d06f11SPatrick Farrell Input Parameters: 3781f6dfbefdSBarry Smith + snes - the `SNES` context 3782e4d06f11SPatrick Farrell - divtol - divergence tolerance 3783e4d06f11SPatrick Farrell 3784e4d06f11SPatrick Farrell Level: intermediate 3785e4d06f11SPatrick Farrell 37861cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetDivergenceTolerance()` 3787e4d06f11SPatrick Farrell @*/ 3788d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetDivergenceTolerance(SNES snes, PetscReal *divtol) 3789d71ae5a4SJacob Faibussowitsch { 3790e4d06f11SPatrick Farrell PetscFunctionBegin; 3791e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3792e4d06f11SPatrick Farrell if (divtol) *divtol = snes->divtol; 37933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3794e4d06f11SPatrick Farrell } 3795e4d06f11SPatrick Farrell 379633174efeSLois Curfman McInnes /*@ 37979b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 37989b94acceSBarry Smith 3799c3339decSBarry Smith Logically Collective 3800fee21e36SBarry Smith 3801c7afd0dbSLois Curfman McInnes Input Parameters: 3802f6dfbefdSBarry Smith + snes - the `SNES` context 3803c7afd0dbSLois Curfman McInnes - tol - tolerance 3804c7afd0dbSLois Curfman McInnes 38059b94acceSBarry Smith Options Database Key: 38064a221d59SStefano Zampini . -snes_tr_tol <tol> - Sets tol 38079b94acceSBarry Smith 380836851e7fSLois Curfman McInnes Level: intermediate 380936851e7fSLois Curfman McInnes 38101cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESNEWTONTR`, `SNESSetTolerances()` 38119b94acceSBarry Smith @*/ 3812d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetTrustRegionTolerance(SNES snes, PetscReal tol) 3813d71ae5a4SJacob Faibussowitsch { 38143a40ed3dSBarry Smith PetscFunctionBegin; 38150700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3816c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, tol, 2); 38179b94acceSBarry Smith snes->deltatol = tol; 38183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38199b94acceSBarry Smith } 38209b94acceSBarry Smith 38216ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *); 38226ba87a44SLisandro Dalcin 3823d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorLGRange(SNES snes, PetscInt n, PetscReal rnorm, void *monctx) 3824d71ae5a4SJacob Faibussowitsch { 3825b271bb04SBarry Smith PetscDrawLG lg; 3826b271bb04SBarry Smith PetscReal x, y, per; 3827b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 3828b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 3829b271bb04SBarry Smith PetscDraw draw; 3830b271bb04SBarry Smith 3831459f5d12SBarry Smith PetscFunctionBegin; 38324d4332d5SBarry Smith PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 4); 38339566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 0, &lg)); 38349566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 38359566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 38369566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "Residual norm")); 3837b271bb04SBarry Smith x = (PetscReal)n; 383877b4d14cSPeter Brune if (rnorm > 0.0) y = PetscLog10Real(rnorm); 383994c9c6d3SKarl Rupp else y = -15.0; 38409566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 38416934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38429566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38439566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3844b271bb04SBarry Smith } 3845b271bb04SBarry Smith 38469566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 1, &lg)); 38479566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 38489566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 3849aaa8cc7dSPierre Jolivet PetscCall(PetscDrawSetTitle(draw, "% elements > .2*max element")); 38509566063dSJacob Faibussowitsch PetscCall(SNESMonitorRange_Private(snes, n, &per)); 3851b271bb04SBarry Smith x = (PetscReal)n; 3852b271bb04SBarry Smith y = 100.0 * per; 38539566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 38546934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38559566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38569566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3857b271bb04SBarry Smith } 3858b271bb04SBarry Smith 38599566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 2, &lg)); 38609371c9d4SSatish Balay if (!n) { 38619371c9d4SSatish Balay prev = rnorm; 38629371c9d4SSatish Balay PetscCall(PetscDrawLGReset(lg)); 38639371c9d4SSatish Balay } 38649566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 38659566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm")); 3866b271bb04SBarry Smith x = (PetscReal)n; 3867b271bb04SBarry Smith y = (prev - rnorm) / prev; 38689566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 38696934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38709566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38719566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3872b271bb04SBarry Smith } 3873b271bb04SBarry Smith 38749566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 3, &lg)); 38759566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 38769566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 38779566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm*(% > .2 max)")); 3878b271bb04SBarry Smith x = (PetscReal)n; 3879b271bb04SBarry Smith y = (prev - rnorm) / (prev * per); 3880b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 38819566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 3882b271bb04SBarry Smith } 38836934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38849566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38859566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3886b271bb04SBarry Smith } 3887b271bb04SBarry Smith prev = rnorm; 38883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3889b271bb04SBarry Smith } 3890b271bb04SBarry Smith 3891228d79bcSJed Brown /*@ 38922d157150SStefano Zampini SNESConverged - Run the convergence test and update the `SNESConvergedReason`. 38932d157150SStefano Zampini 38942d157150SStefano Zampini Collective 38952d157150SStefano Zampini 38962d157150SStefano Zampini Input Parameters: 38972d157150SStefano Zampini + snes - the `SNES` context 38982d157150SStefano Zampini . it - current iteration 38992d157150SStefano Zampini . xnorm - 2-norm of current iterate 39002d157150SStefano Zampini . snorm - 2-norm of current step 39012d157150SStefano Zampini - fnorm - 2-norm of function 39022d157150SStefano Zampini 39032d157150SStefano Zampini Level: developer 39042d157150SStefano Zampini 39052d157150SStefano Zampini Note: 39062d157150SStefano Zampini This routine is called by the `SNES` implementations. 39072d157150SStefano Zampini It does not typically need to be called by the user. 39082d157150SStefano Zampini 3909be50c303SSatish Balay .seealso: [](ch_snes), `SNES`, `SNESSolve`, `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()` 39102d157150SStefano Zampini @*/ 39112d157150SStefano Zampini PetscErrorCode SNESConverged(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm) 39122d157150SStefano Zampini { 39132d157150SStefano Zampini PetscFunctionBegin; 39142d157150SStefano Zampini if (!snes->reason) { 39152d157150SStefano Zampini if (snes->normschedule == SNES_NORM_ALWAYS) PetscUseTypeMethod(snes, converged, it, xnorm, snorm, fnorm, &snes->reason, snes->cnvP); 39162d157150SStefano Zampini if (it == snes->max_its && !snes->reason) { 39172d157150SStefano Zampini if (snes->normschedule == SNES_NORM_ALWAYS) { 39182d157150SStefano Zampini PetscCall(PetscInfo(snes, "Maximum number of iterations has been reached: %" PetscInt_FMT "\n", snes->max_its)); 39192d157150SStefano Zampini snes->reason = SNES_DIVERGED_MAX_IT; 39202d157150SStefano Zampini } else snes->reason = SNES_CONVERGED_ITS; 39212d157150SStefano Zampini } 39222d157150SStefano Zampini } 39232d157150SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 39242d157150SStefano Zampini } 39252d157150SStefano Zampini 39262d157150SStefano Zampini /*@ 3927228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 3928228d79bcSJed Brown 3929c3339decSBarry Smith Collective 3930228d79bcSJed Brown 3931228d79bcSJed Brown Input Parameters: 3932f6dfbefdSBarry Smith + snes - nonlinear solver context obtained from `SNESCreate()` 3933228d79bcSJed Brown . iter - iteration number 3934228d79bcSJed Brown - rnorm - relative norm of the residual 3935228d79bcSJed Brown 3936dc4c0fb0SBarry Smith Level: developer 3937dc4c0fb0SBarry Smith 3938f6dfbefdSBarry Smith Note: 3939f6dfbefdSBarry Smith This routine is called by the `SNES` implementations. 3940228d79bcSJed Brown It does not typically need to be called by the user. 3941228d79bcSJed Brown 39421cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESMonitorSet()` 3943228d79bcSJed Brown @*/ 3944d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitor(SNES snes, PetscInt iter, PetscReal rnorm) 3945d71ae5a4SJacob Faibussowitsch { 39467a03ce2fSLisandro Dalcin PetscInt i, n = snes->numbermonitors; 39477a03ce2fSLisandro Dalcin 39487a03ce2fSLisandro Dalcin PetscFunctionBegin; 39499566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(snes->vec_sol)); 395048a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall((*snes->monitor[i])(snes, iter, rnorm, snes->monitorcontext[i])); 39519566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(snes->vec_sol)); 39523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39537a03ce2fSLisandro Dalcin } 39547a03ce2fSLisandro Dalcin 39559b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 39569b94acceSBarry Smith 3957bf388a1fSBarry Smith /*MC 3958f6dfbefdSBarry Smith SNESMonitorFunction - functional form passed to `SNESMonitorSet()` to monitor convergence of nonlinear solver 3959bf388a1fSBarry Smith 3960bf388a1fSBarry Smith Synopsis: 3961aaa7dc30SBarry Smith #include <petscsnes.h> 396237fdd005SBarry Smith PetscErrorCode SNESMonitorFunction(SNES snes, PetscInt its, PetscReal norm, void *mctx) 3963bf388a1fSBarry Smith 3964c3339decSBarry Smith Collective 39651843f636SBarry Smith 39661843f636SBarry Smith Input Parameters: 3967f6dfbefdSBarry Smith + snes - the `SNES` context 3968bf388a1fSBarry Smith . its - iteration number 3969bf388a1fSBarry Smith . norm - 2-norm function value (may be estimated) 3970bf388a1fSBarry Smith - mctx - [optional] monitoring context 3971bf388a1fSBarry Smith 3972878cb397SSatish Balay Level: advanced 3973878cb397SSatish Balay 39741cc06b55SBarry Smith .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorSet()`, `SNESMonitorGet()` 3975bf388a1fSBarry Smith M*/ 3976bf388a1fSBarry Smith 39779b94acceSBarry Smith /*@C 3978a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 39799b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 39809b94acceSBarry Smith progress. 39819b94acceSBarry Smith 3982c3339decSBarry Smith Logically Collective 3983fee21e36SBarry Smith 3984c7afd0dbSLois Curfman McInnes Input Parameters: 3985f6dfbefdSBarry Smith + snes - the `SNES` context 398620f4b53cSBarry Smith . f - the monitor function, for the calling sequence see `SNESMonitorFunction` 3987b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 3988dc4c0fb0SBarry Smith monitor routine (use `NULL` if no context is desired) 3989dc4c0fb0SBarry Smith - monitordestroy - [optional] routine that frees monitor context (may be `NULL`) 39909b94acceSBarry Smith 39919665c990SLois Curfman McInnes Options Database Keys: 3992f6dfbefdSBarry Smith + -snes_monitor - sets `SNESMonitorDefault()` 3993798534f6SMatthew G. Knepley . -snes_monitor draw::draw_lg - sets line graph monitor, 3994dc4c0fb0SBarry Smith - -snes_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to `SNESMonitorSet()`, but does not cancel those set via 3995c7afd0dbSLois Curfman McInnes the options database. 39969665c990SLois Curfman McInnes 3997dc4c0fb0SBarry Smith Level: intermediate 3998dc4c0fb0SBarry Smith 3999f6dfbefdSBarry Smith Note: 40006bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 4001f6dfbefdSBarry Smith `SNESMonitorSet()` multiple times; all will be called in the 40026bc08f3fSLois Curfman McInnes order in which they were set. 4003639f9d9dSBarry Smith 4004e4094ef1SJacob Faibussowitsch Fortran Notes: 4005f6dfbefdSBarry Smith Only a single monitor function can be set for each `SNES` object 4006025f1a04SBarry Smith 40071cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESMonitorDefault()`, `SNESMonitorCancel()`, `SNESMonitorFunction` 40089b94acceSBarry Smith @*/ 4009d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSet(SNES snes, PetscErrorCode (*f)(SNES, PetscInt, PetscReal, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **)) 4010d71ae5a4SJacob Faibussowitsch { 4011b90d0a6eSBarry Smith PetscInt i; 401278064530SBarry Smith PetscBool identical; 4013b90d0a6eSBarry Smith 40143a40ed3dSBarry Smith PetscFunctionBegin; 40150700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4016b90d0a6eSBarry Smith for (i = 0; i < snes->numbermonitors; i++) { 40179566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, mctx, monitordestroy, (PetscErrorCode(*)(void))snes->monitor[i], snes->monitorcontext[i], snes->monitordestroy[i], &identical)); 40183ba16761SJacob Faibussowitsch if (identical) PetscFunctionReturn(PETSC_SUCCESS); 4019649052a6SBarry Smith } 40205f80ce2aSJacob Faibussowitsch PetscCheck(snes->numbermonitors < MAXSNESMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 40216e4dcb14SBarry Smith snes->monitor[snes->numbermonitors] = f; 4022b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 4023639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void *)mctx; 40243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40259b94acceSBarry Smith } 40269b94acceSBarry Smith 4027a278d85bSSatish Balay /*@ 4028f6dfbefdSBarry Smith SNESMonitorCancel - Clears all the monitor functions for a `SNES` object. 40295cd90555SBarry Smith 4030c3339decSBarry Smith Logically Collective 4031c7afd0dbSLois Curfman McInnes 40322fe279fdSBarry Smith Input Parameter: 4033f6dfbefdSBarry Smith . snes - the `SNES` context 40345cd90555SBarry Smith 40351a480d89SAdministrator Options Database Key: 4036a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 4037dc4c0fb0SBarry Smith into a code by calls to `SNESMonitorSet()`, but does not cancel those 4038c7afd0dbSLois Curfman McInnes set via the options database 40395cd90555SBarry Smith 4040dc4c0fb0SBarry Smith Level: intermediate 4041dc4c0fb0SBarry Smith 4042f6dfbefdSBarry Smith Note: 4043f6dfbefdSBarry Smith There is no way to clear one specific monitor from a `SNES` object. 40445cd90555SBarry Smith 40451cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESMonitorGet()`, `SNESMonitorDefault()`, `SNESMonitorSet()` 40465cd90555SBarry Smith @*/ 4047d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorCancel(SNES snes) 4048d71ae5a4SJacob Faibussowitsch { 4049d952e501SBarry Smith PetscInt i; 4050d952e501SBarry Smith 40515cd90555SBarry Smith PetscFunctionBegin; 40520700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4053d952e501SBarry Smith for (i = 0; i < snes->numbermonitors; i++) { 405448a46eb9SPierre Jolivet if (snes->monitordestroy[i]) PetscCall((*snes->monitordestroy[i])(&snes->monitorcontext[i])); 4055d952e501SBarry Smith } 40565cd90555SBarry Smith snes->numbermonitors = 0; 40573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40585cd90555SBarry Smith } 40595cd90555SBarry Smith 4060bf388a1fSBarry Smith /*MC 4061bf388a1fSBarry Smith SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 4062bf388a1fSBarry Smith 4063bf388a1fSBarry Smith Synopsis: 4064aaa7dc30SBarry Smith #include <petscsnes.h> 406537fdd005SBarry Smith PetscErrorCode SNESConvergenceTest(SNES snes, PetscInt it, PetscReal xnorm, PetscReal gnorm, PetscReal f, SNESConvergedReason *reason, void *cctx) 4066bf388a1fSBarry Smith 4067c3339decSBarry Smith Collective 40681843f636SBarry Smith 40691843f636SBarry Smith Input Parameters: 4070f6dfbefdSBarry Smith + snes - the `SNES` context 4071bf388a1fSBarry Smith . it - current iteration (0 is the first and is before any Newton step) 4072bf388a1fSBarry Smith . xnorm - 2-norm of current iterate 4073bf388a1fSBarry Smith . gnorm - 2-norm of current step 40741843f636SBarry Smith . f - 2-norm of function 40751843f636SBarry Smith - cctx - [optional] convergence context 40761843f636SBarry Smith 40771843f636SBarry Smith Output Parameter: 40781843f636SBarry Smith . reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected 4079bf388a1fSBarry Smith 4080878cb397SSatish Balay Level: intermediate 4081bf388a1fSBarry Smith 40821cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSolve`, `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()` 4083bf388a1fSBarry Smith M*/ 4084bf388a1fSBarry Smith 40859b94acceSBarry Smith /*@C 40869b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 40879b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 40889b94acceSBarry Smith 4089c3339decSBarry Smith Logically Collective 4090fee21e36SBarry Smith 4091c7afd0dbSLois Curfman McInnes Input Parameters: 4092f6dfbefdSBarry Smith + snes - the `SNES` context 4093e4094ef1SJacob Faibussowitsch . SNESConvergenceTestFunction - routine to test for convergence 4094dc4c0fb0SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be `NULL`) 4095dc4c0fb0SBarry Smith - destroy - [optional] destructor for the context (may be `NULL`; `PETSC_NULL_FUNCTION` in Fortran) 40969b94acceSBarry Smith 409736851e7fSLois Curfman McInnes Level: advanced 409836851e7fSLois Curfman McInnes 40991cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESConvergedDefault()`, `SNESConvergedSkip()`, `SNESConvergenceTestFunction` 41009b94acceSBarry Smith @*/ 4101d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergenceTest(SNES snes, PetscErrorCode (*SNESConvergenceTestFunction)(SNES, PetscInt, PetscReal, PetscReal, PetscReal, SNESConvergedReason *, void *), void *cctx, PetscErrorCode (*destroy)(void *)) 4102d71ae5a4SJacob Faibussowitsch { 41033a40ed3dSBarry Smith PetscFunctionBegin; 41040700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4105e2a6519dSDmitry Karpeev if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 41061baa6e33SBarry Smith if (snes->ops->convergeddestroy) PetscCall((*snes->ops->convergeddestroy)(snes->cnvP)); 4107bf388a1fSBarry Smith snes->ops->converged = SNESConvergenceTestFunction; 41087f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 410985385478SLisandro Dalcin snes->cnvP = cctx; 41103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 41119b94acceSBarry Smith } 41129b94acceSBarry Smith 411352baeb72SSatish Balay /*@ 4114f6dfbefdSBarry Smith SNESGetConvergedReason - Gets the reason the `SNES` iteration was stopped. 4115184914b5SBarry Smith 4116184914b5SBarry Smith Not Collective 4117184914b5SBarry Smith 4118184914b5SBarry Smith Input Parameter: 4119f6dfbefdSBarry Smith . snes - the `SNES` context 4120184914b5SBarry Smith 4121184914b5SBarry Smith Output Parameter: 4122f6dfbefdSBarry Smith . reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` for the individual convergence tests for complete lists 4123184914b5SBarry Smith 4124f6dfbefdSBarry Smith Options Database Key: 41256a4d7782SBarry Smith . -snes_converged_reason - prints the reason to standard out 41266a4d7782SBarry Smith 4127184914b5SBarry Smith Level: intermediate 4128184914b5SBarry Smith 4129f6dfbefdSBarry Smith Note: 4130f6dfbefdSBarry Smith Should only be called after the call the `SNESSolve()` is complete, if it is called earlier it returns the value `SNES__CONVERGED_ITERATING`. 4131184914b5SBarry Smith 41321cc06b55SBarry Smith .seealso: [](ch_snes), `SNESSolve()`, `SNESSetConvergenceTest()`, `SNESSetConvergedReason()`, `SNESConvergedReason`, `SNESGetConvergedReasonString()` 4133184914b5SBarry Smith @*/ 4134d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergedReason(SNES snes, SNESConvergedReason *reason) 4135d71ae5a4SJacob Faibussowitsch { 4136184914b5SBarry Smith PetscFunctionBegin; 41370700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 41384f572ea9SToby Isaac PetscAssertPointer(reason, 2); 4139184914b5SBarry Smith *reason = snes->reason; 41403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4141184914b5SBarry Smith } 4142184914b5SBarry Smith 4143c4421ceaSFande Kong /*@C 4144f6dfbefdSBarry Smith SNESGetConvergedReasonString - Return a human readable string for `SNESConvergedReason` 4145c4421ceaSFande Kong 4146c4421ceaSFande Kong Not Collective 4147c4421ceaSFande Kong 4148c4421ceaSFande Kong Input Parameter: 4149f6dfbefdSBarry Smith . snes - the `SNES` context 4150c4421ceaSFande Kong 4151c4421ceaSFande Kong Output Parameter: 4152dc4c0fb0SBarry Smith . strreason - a human readable string that describes `SNES` converged reason 4153c4421ceaSFande Kong 415499c90e12SSatish Balay Level: beginner 4155c4421ceaSFande Kong 41561cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESGetConvergedReason()` 4157c4421ceaSFande Kong @*/ 4158d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char **strreason) 4159d71ae5a4SJacob Faibussowitsch { 4160c4421ceaSFande Kong PetscFunctionBegin; 4161c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 41624f572ea9SToby Isaac PetscAssertPointer(strreason, 2); 4163c4421ceaSFande Kong *strreason = SNESConvergedReasons[snes->reason]; 41643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4165c4421ceaSFande Kong } 4166c4421ceaSFande Kong 416733866048SMatthew G. Knepley /*@ 4168f6dfbefdSBarry Smith SNESSetConvergedReason - Sets the reason the `SNES` iteration was stopped. 416933866048SMatthew G. Knepley 417033866048SMatthew G. Knepley Not Collective 417133866048SMatthew G. Knepley 417233866048SMatthew G. Knepley Input Parameters: 4173f6dfbefdSBarry Smith + snes - the `SNES` context 4174f6dfbefdSBarry Smith - reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` or the 417533866048SMatthew G. Knepley manual pages for the individual convergence tests for complete lists 417633866048SMatthew G. Knepley 4177f6dfbefdSBarry Smith Level: developer 4178f6dfbefdSBarry Smith 4179e4094ef1SJacob Faibussowitsch Developer Notes: 4180f6dfbefdSBarry Smith Called inside the various `SNESSolve()` implementations 418133866048SMatthew G. Knepley 41821cc06b55SBarry Smith .seealso: [](ch_snes), `SNESGetConvergedReason()`, `SNESSetConvergenceTest()`, `SNESConvergedReason` 418333866048SMatthew G. Knepley @*/ 4184d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergedReason(SNES snes, SNESConvergedReason reason) 4185d71ae5a4SJacob Faibussowitsch { 418633866048SMatthew G. Knepley PetscFunctionBegin; 418733866048SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 418833866048SMatthew G. Knepley snes->reason = reason; 41893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 419033866048SMatthew G. Knepley } 419133866048SMatthew G. Knepley 4192c9005455SLois Curfman McInnes /*@ 4193c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 4194c9005455SLois Curfman McInnes 4195c3339decSBarry Smith Logically Collective 4196fee21e36SBarry Smith 4197c7afd0dbSLois Curfman McInnes Input Parameters: 4198f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 41998c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 4200cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 4201758f92a0SBarry Smith . na - size of a and its 4202f6dfbefdSBarry Smith - reset - `PETSC_TRUE` indicates each new nonlinear solve resets the history counter to zero, 4203758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 4204c7afd0dbSLois Curfman McInnes 4205dc4c0fb0SBarry Smith Level: intermediate 4206dc4c0fb0SBarry Smith 4207308dcc3eSBarry Smith Notes: 4208dc4c0fb0SBarry Smith If 'a' and 'its' are `NULL` then space is allocated for the history. If 'na' `PETSC_DECIDE` or `PETSC_DEFAULT` then a 4209308dcc3eSBarry Smith default array of length 10000 is allocated. 4210308dcc3eSBarry Smith 4211c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 4212c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 4213c9005455SLois Curfman McInnes during the section of code that is being timed. 4214c9005455SLois Curfman McInnes 42151cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESGetConvergenceHistory()` 4216c9005455SLois Curfman McInnes @*/ 4217d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergenceHistory(SNES snes, PetscReal a[], PetscInt its[], PetscInt na, PetscBool reset) 4218d71ae5a4SJacob Faibussowitsch { 42193a40ed3dSBarry Smith PetscFunctionBegin; 42200700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 42214f572ea9SToby Isaac if (a) PetscAssertPointer(a, 2); 42224f572ea9SToby Isaac if (its) PetscAssertPointer(its, 3); 42237a1ec6d4SBarry Smith if (!a) { 4224308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 42259566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(na, &a, na, &its)); 4226071fcb05SBarry Smith snes->conv_hist_alloc = PETSC_TRUE; 4227308dcc3eSBarry Smith } 4228c9005455SLois Curfman McInnes snes->conv_hist = a; 4229758f92a0SBarry Smith snes->conv_hist_its = its; 4230115dd874SBarry Smith snes->conv_hist_max = (size_t)na; 4231a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 4232758f92a0SBarry Smith snes->conv_hist_reset = reset; 42333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4234758f92a0SBarry Smith } 4235758f92a0SBarry Smith 4236d1e78c4fSBarry Smith #if defined(PETSC_HAVE_MATLAB) 4237c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 4238c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 423999e0435eSBarry Smith 4240d71ae5a4SJacob Faibussowitsch PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 4241d71ae5a4SJacob Faibussowitsch { 4242308dcc3eSBarry Smith mxArray *mat; 4243308dcc3eSBarry Smith PetscInt i; 4244308dcc3eSBarry Smith PetscReal *ar; 4245308dcc3eSBarry Smith 4246308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len, 1, mxREAL); 4247308dcc3eSBarry Smith ar = (PetscReal *)mxGetData(mat); 4248f5af7f23SKarl Rupp for (i = 0; i < snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 424911cc89d2SBarry Smith return mat; 4250308dcc3eSBarry Smith } 4251308dcc3eSBarry Smith #endif 4252308dcc3eSBarry Smith 42530c4c9dddSBarry Smith /*@C 4254758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 4255758f92a0SBarry Smith 42563f9fe445SBarry Smith Not Collective 4257758f92a0SBarry Smith 4258758f92a0SBarry Smith Input Parameter: 4259f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 4260758f92a0SBarry Smith 4261758f92a0SBarry Smith Output Parameters: 4262f6dfbefdSBarry Smith + a - array to hold history, usually was set with `SNESSetConvergenceHistory()` 4263758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 4264758f92a0SBarry Smith negative if not converged) for each solve. 426520f4b53cSBarry Smith - na - size of `a` and `its` 4266758f92a0SBarry Smith 4267dc4c0fb0SBarry Smith Level: intermediate 4268dc4c0fb0SBarry Smith 426920f4b53cSBarry Smith Note: 427020f4b53cSBarry Smith This routine is useful, e.g., when running a code for purposes 427120f4b53cSBarry Smith of accurate performance monitoring, when no I/O should be done 427220f4b53cSBarry Smith during the section of code that is being timed. 427320f4b53cSBarry Smith 4274e4094ef1SJacob Faibussowitsch Fortran Notes: 4275758f92a0SBarry Smith The calling sequence for this routine in Fortran is 4276dc4c0fb0SBarry Smith .vb 4277dc4c0fb0SBarry Smith call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 4278dc4c0fb0SBarry Smith .ve 4279758f92a0SBarry Smith 42801cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetConvergenceHistory()` 4281758f92a0SBarry Smith @*/ 4282d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergenceHistory(SNES snes, PetscReal *a[], PetscInt *its[], PetscInt *na) 4283d71ae5a4SJacob Faibussowitsch { 4284758f92a0SBarry Smith PetscFunctionBegin; 42850700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4286758f92a0SBarry Smith if (a) *a = snes->conv_hist; 4287758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 4288115dd874SBarry Smith if (na) *na = (PetscInt)snes->conv_hist_len; 42893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4290c9005455SLois Curfman McInnes } 4291c9005455SLois Curfman McInnes 4292ac226902SBarry Smith /*@C 429376b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 4294eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 42957e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 429676b2cf59SMatthew Knepley 4297c3339decSBarry Smith Logically Collective 429876b2cf59SMatthew Knepley 429976b2cf59SMatthew Knepley Input Parameters: 4300a2b725a8SWilliam Gropp + snes - The nonlinear solver context 4301a2b725a8SWilliam Gropp - func - The function 430276b2cf59SMatthew Knepley 430320f4b53cSBarry Smith Calling sequence of `func`: 430420f4b53cSBarry Smith $ PetscErrorCode func(SNES snes, PetscInt step); 430520f4b53cSBarry Smith + snes - the nonlinear solver context 430620f4b53cSBarry Smith - step - The current step of the iteration 430776b2cf59SMatthew Knepley 4308fe97e370SBarry Smith Level: advanced 4309fe97e370SBarry Smith 43106b7fb656SBarry Smith Note: 4311f6dfbefdSBarry Smith This is NOT what one uses to update the ghost points before a function evaluation, that should be done at the beginning of your function provided 4312f6dfbefdSBarry Smith to `SNESSetFunction()`, or `SNESSetPicard()` 4313fe97e370SBarry Smith This is not used by most users. 431476b2cf59SMatthew Knepley 4315aaa8cc7dSPierre Jolivet There are a variety of function hooks one many set that are called at different stages of the nonlinear solution process, see the functions listed below. 43166b7fb656SBarry Smith 4317e4094ef1SJacob Faibussowitsch .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetJacobian()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRSetPostCheck()`, 4318db781477SPatrick Sanan `SNESMonitorSet()`, `SNESSetDivergenceTest()` 431976b2cf59SMatthew Knepley @*/ 43200b4db180SJacob Faibussowitsch PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES snes, PetscInt step)) 4321d71ae5a4SJacob Faibussowitsch { 432276b2cf59SMatthew Knepley PetscFunctionBegin; 43230700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4324e7788613SBarry Smith snes->ops->update = func; 43253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 432676b2cf59SMatthew Knepley } 432776b2cf59SMatthew Knepley 432891f3e32bSBarry Smith /*@C 4329f6dfbefdSBarry Smith SNESConvergedReasonView - Displays the reason a `SNES` solve converged or diverged to a viewer 43302a359c20SBarry Smith 4331c3339decSBarry Smith Collective 43322a359c20SBarry Smith 4333e4094ef1SJacob Faibussowitsch Input Parameters: 4334f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 43352a359c20SBarry Smith - viewer - the viewer to display the reason 43362a359c20SBarry Smith 43372a359c20SBarry Smith Options Database Keys: 4338ee300463SSatish Balay + -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 4339ee300463SSatish Balay - -snes_converged_reason ::failed - only print reason and number of iterations when diverged 4340eafd5ff0SAlex Lindsay 4341f6dfbefdSBarry Smith Note: 4342f6dfbefdSBarry Smith To change the format of the output call `PetscViewerPushFormat`(viewer,format) before this call. Use `PETSC_VIEWER_DEFAULT` for the default, 4343f6dfbefdSBarry Smith use `PETSC_VIEWER_FAILED` to only display a reason if it fails. 43442a359c20SBarry Smith 43452a359c20SBarry Smith Level: beginner 43462a359c20SBarry Smith 43471cc06b55SBarry Smith .seealso: [](ch_snes), `SNESConvergedReason`, `PetscViewer`, `SNES`, 4348f6dfbefdSBarry Smith `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, 4349f6dfbefdSBarry Smith `SNESConvergedReasonViewFromOptions()`, 4350db781477SPatrick Sanan `PetscViewerPushFormat()`, `PetscViewerPopFormat()` 43512a359c20SBarry Smith @*/ 4352d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonView(SNES snes, PetscViewer viewer) 4353d71ae5a4SJacob Faibussowitsch { 435475cca76cSMatthew G. Knepley PetscViewerFormat format; 43552a359c20SBarry Smith PetscBool isAscii; 43562a359c20SBarry Smith 43572a359c20SBarry Smith PetscFunctionBegin; 435819a666eeSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 43599566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii)); 43602a359c20SBarry Smith if (isAscii) { 43619566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 43629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 436375cca76cSMatthew G. Knepley if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 436475cca76cSMatthew G. Knepley DM dm; 436575cca76cSMatthew G. Knepley Vec u; 436675cca76cSMatthew G. Knepley PetscDS prob; 436775cca76cSMatthew G. Knepley PetscInt Nf, f; 436895cbbfd3SMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 436995cbbfd3SMatthew G. Knepley void **exactCtx; 437075cca76cSMatthew G. Knepley PetscReal error; 437175cca76cSMatthew G. Knepley 43729566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 43739566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &u)); 43749566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 43759566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(prob, &Nf)); 43769566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &exactSol, Nf, &exactCtx)); 43779566063dSJacob Faibussowitsch for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f])); 43789566063dSJacob Faibussowitsch PetscCall(DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error)); 43799566063dSJacob Faibussowitsch PetscCall(PetscFree2(exactSol, exactCtx)); 43809566063dSJacob Faibussowitsch if (error < 1.0e-11) PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n")); 438163a3b9bcSJacob Faibussowitsch else PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", (double)error)); 438275cca76cSMatthew G. Knepley } 4383eafd5ff0SAlex Lindsay if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) { 43842a359c20SBarry Smith if (((PetscObject)snes)->prefix) { 438563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear %s solve converged due to %s iterations %" PetscInt_FMT "\n", ((PetscObject)snes)->prefix, SNESConvergedReasons[snes->reason], snes->iter)); 43862a359c20SBarry Smith } else { 438763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve converged due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter)); 43882a359c20SBarry Smith } 4389eafd5ff0SAlex Lindsay } else if (snes->reason <= 0) { 43902a359c20SBarry Smith if (((PetscObject)snes)->prefix) { 439163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear %s solve did not converge due to %s iterations %" PetscInt_FMT "\n", ((PetscObject)snes)->prefix, SNESConvergedReasons[snes->reason], snes->iter)); 43922a359c20SBarry Smith } else { 439363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve did not converge due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter)); 43942a359c20SBarry Smith } 43952a359c20SBarry Smith } 43969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 43972a359c20SBarry Smith } 43983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 43992a359c20SBarry Smith } 44002a359c20SBarry Smith 4401c4421ceaSFande Kong /*@C 4402c4421ceaSFande Kong SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the 4403aaa8cc7dSPierre Jolivet end of the nonlinear solver to display the convergence reason of the nonlinear solver. 4404c4421ceaSFande Kong 4405c3339decSBarry Smith Logically Collective 4406c4421ceaSFande Kong 4407c4421ceaSFande Kong Input Parameters: 4408f6dfbefdSBarry Smith + snes - the `SNES` context 4409c4421ceaSFande Kong . f - the snes converged reason view function 4410c4421ceaSFande Kong . vctx - [optional] user-defined context for private data for the 4411dc4c0fb0SBarry Smith snes converged reason view routine (use `NULL` if no context is desired) 4412dc4c0fb0SBarry Smith - reasonviewdestroy - [optional] routine that frees reasonview context (may be `NULL`) 4413c4421ceaSFande Kong 4414c4421ceaSFande Kong Options Database Keys: 4415f6dfbefdSBarry Smith + -snes_converged_reason - sets a default `SNESConvergedReasonView()` 4416c4421ceaSFande Kong - -snes_converged_reason_view_cancel - cancels all converged reason viewers that have 4417c4421ceaSFande Kong been hardwired into a code by 4418f6dfbefdSBarry Smith calls to `SNESConvergedReasonViewSet()`, but 4419c4421ceaSFande Kong does not cancel those set via 4420c4421ceaSFande Kong the options database. 4421c4421ceaSFande Kong 4422dc4c0fb0SBarry Smith Level: intermediate 4423dc4c0fb0SBarry Smith 4424f6dfbefdSBarry Smith Note: 4425c4421ceaSFande Kong Several different converged reason view routines may be set by calling 4426f6dfbefdSBarry Smith `SNESConvergedReasonViewSet()` multiple times; all will be called in the 4427c4421ceaSFande Kong order in which they were set. 4428c4421ceaSFande Kong 44291cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESConvergedReason`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()`, `SNESConvergedReasonViewCancel()` 4430c4421ceaSFande Kong @*/ 4431d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewSet(SNES snes, PetscErrorCode (*f)(SNES, void *), void *vctx, PetscErrorCode (*reasonviewdestroy)(void **)) 4432d71ae5a4SJacob Faibussowitsch { 4433c4421ceaSFande Kong PetscInt i; 4434c4421ceaSFande Kong PetscBool identical; 4435c4421ceaSFande Kong 4436c4421ceaSFande Kong PetscFunctionBegin; 4437c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4438c4421ceaSFande Kong for (i = 0; i < snes->numberreasonviews; i++) { 44399566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, vctx, reasonviewdestroy, (PetscErrorCode(*)(void))snes->reasonview[i], snes->reasonviewcontext[i], snes->reasonviewdestroy[i], &identical)); 44403ba16761SJacob Faibussowitsch if (identical) PetscFunctionReturn(PETSC_SUCCESS); 4441c4421ceaSFande Kong } 44425f80ce2aSJacob Faibussowitsch PetscCheck(snes->numberreasonviews < MAXSNESREASONVIEWS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many SNES reasonview set"); 4443c4421ceaSFande Kong snes->reasonview[snes->numberreasonviews] = f; 4444c4421ceaSFande Kong snes->reasonviewdestroy[snes->numberreasonviews] = reasonviewdestroy; 4445c4421ceaSFande Kong snes->reasonviewcontext[snes->numberreasonviews++] = (void *)vctx; 44463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4447c4421ceaSFande Kong } 4448c4421ceaSFande Kong 444991f3e32bSBarry Smith /*@ 4450f6dfbefdSBarry Smith SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a `SNESConvergedReason` is to be viewed. 4451c4421ceaSFande Kong All the user-provided convergedReasonView routines will be involved as well, if they exist. 44522a359c20SBarry Smith 4453c3339decSBarry Smith Collective 44542a359c20SBarry Smith 44552fe279fdSBarry Smith Input Parameter: 4456f6dfbefdSBarry Smith . snes - the `SNES` object 44572a359c20SBarry Smith 4458f6dfbefdSBarry Smith Level: advanced 44592a359c20SBarry Smith 44601cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESConvergedReason`, `SNESConvergedReasonViewSet()`, `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, 4461f6dfbefdSBarry Smith `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()` 44622a359c20SBarry Smith @*/ 4463d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes) 4464d71ae5a4SJacob Faibussowitsch { 44652a359c20SBarry Smith PetscViewer viewer; 44662a359c20SBarry Smith PetscBool flg; 44672a359c20SBarry Smith static PetscBool incall = PETSC_FALSE; 44682a359c20SBarry Smith PetscViewerFormat format; 4469c4421ceaSFande Kong PetscInt i; 44702a359c20SBarry Smith 44712a359c20SBarry Smith PetscFunctionBegin; 44723ba16761SJacob Faibussowitsch if (incall) PetscFunctionReturn(PETSC_SUCCESS); 44732a359c20SBarry Smith incall = PETSC_TRUE; 4474c4421ceaSFande Kong 4475c4421ceaSFande Kong /* All user-provided viewers are called first, if they exist. */ 447648a46eb9SPierre Jolivet for (i = 0; i < snes->numberreasonviews; i++) PetscCall((*snes->reasonview[i])(snes, snes->reasonviewcontext[i])); 4477c4421ceaSFande Kong 4478c4421ceaSFande Kong /* Call PETSc default routine if users ask for it */ 44799566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_converged_reason", &viewer, &format, &flg)); 44802a359c20SBarry Smith if (flg) { 44819566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 44829566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonView(snes, viewer)); 44839566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 44849566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 44852a359c20SBarry Smith } 44862a359c20SBarry Smith incall = PETSC_FALSE; 44873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 44882a359c20SBarry Smith } 44892a359c20SBarry Smith 4490487a658cSBarry Smith /*@ 4491f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 4492f6dfbefdSBarry Smith Call `SNESSolve()` after calling `SNESCreate()` and optional routines of the form `SNESSetXXX()`. 44939b94acceSBarry Smith 4494c3339decSBarry Smith Collective 4495c7afd0dbSLois Curfman McInnes 4496b2002411SLois Curfman McInnes Input Parameters: 4497f6dfbefdSBarry Smith + snes - the `SNES` context 4498dc4c0fb0SBarry Smith . b - the constant part of the equation F(x) = b, or `NULL` to use zero. 449985385478SLisandro Dalcin - x - the solution vector. 45009b94acceSBarry Smith 4501dc4c0fb0SBarry Smith Level: beginner 4502dc4c0fb0SBarry Smith 4503f6dfbefdSBarry Smith Note: 45048ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 4505f6dfbefdSBarry Smith for the nonlinear solve prior to calling `SNESSolve()`. In particular, 45068ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 4507f6dfbefdSBarry Smith this vector to zero by calling `VecSet()`. 45088ddd3da0SLois Curfman McInnes 45091cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESSetFunction()`, `SNESSetJacobian()`, `SNESSetGridSequence()`, `SNESGetSolution()`, 4510db781477SPatrick Sanan `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRGetPreCheck()`, `SNESNewtonTRSetPostCheck()`, `SNESNewtonTRGetPostCheck()`, 4511db781477SPatrick Sanan `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()` 45129b94acceSBarry Smith @*/ 4513d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSolve(SNES snes, Vec b, Vec x) 4514d71ae5a4SJacob Faibussowitsch { 4515ace3abfcSBarry Smith PetscBool flg; 4516efd51863SBarry Smith PetscInt grid; 45170298fd71SBarry Smith Vec xcreated = NULL; 4518caa4e7f2SJed Brown DM dm; 4519052efed2SBarry Smith 45203a40ed3dSBarry Smith PetscFunctionBegin; 45210700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4522a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 4523a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes, 1, x, 3); 45240700a824SBarry Smith if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 452585385478SLisandro Dalcin if (b) PetscCheckSameComm(snes, 1, b, 2); 452685385478SLisandro Dalcin 452734b4d3a8SMatthew G. Knepley /* High level operations using the nonlinear solver */ 452806fc46c8SMatthew G. Knepley { 452906fc46c8SMatthew G. Knepley PetscViewer viewer; 453006fc46c8SMatthew G. Knepley PetscViewerFormat format; 45317c88af5aSMatthew G. Knepley PetscInt num; 453206fc46c8SMatthew G. Knepley PetscBool flg; 453306fc46c8SMatthew G. Knepley static PetscBool incall = PETSC_FALSE; 453406fc46c8SMatthew G. Knepley 453506fc46c8SMatthew G. Knepley if (!incall) { 453634b4d3a8SMatthew G. Knepley /* Estimate the convergence rate of the discretization */ 45379566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg)); 453806fc46c8SMatthew G. Knepley if (flg) { 453906fc46c8SMatthew G. Knepley PetscConvEst conv; 454046079b62SMatthew G. Knepley DM dm; 454146079b62SMatthew G. Knepley PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 454246079b62SMatthew G. Knepley PetscInt Nf; 454306fc46c8SMatthew G. Knepley 454406fc46c8SMatthew G. Knepley incall = PETSC_TRUE; 45459566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 45469566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 45479566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nf, &alpha)); 45489566063dSJacob Faibussowitsch PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject)snes), &conv)); 45499566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetSolver(conv, (PetscObject)snes)); 45509566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetFromOptions(conv)); 45519566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetUp(conv)); 45529566063dSJacob Faibussowitsch PetscCall(PetscConvEstGetConvRate(conv, alpha)); 45539566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 45549566063dSJacob Faibussowitsch PetscCall(PetscConvEstRateView(conv, alpha, viewer)); 45559566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 45569566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 45579566063dSJacob Faibussowitsch PetscCall(PetscConvEstDestroy(&conv)); 45589566063dSJacob Faibussowitsch PetscCall(PetscFree(alpha)); 455906fc46c8SMatthew G. Knepley incall = PETSC_FALSE; 456006fc46c8SMatthew G. Knepley } 456134b4d3a8SMatthew G. Knepley /* Adaptively refine the initial grid */ 4562b2588ea6SMatthew G. Knepley num = 1; 45639566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_initial", &num, &flg)); 456434b4d3a8SMatthew G. Knepley if (flg) { 456534b4d3a8SMatthew G. Knepley DMAdaptor adaptor; 456634b4d3a8SMatthew G. Knepley 456734b4d3a8SMatthew G. Knepley incall = PETSC_TRUE; 45689566063dSJacob Faibussowitsch PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 45699566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSolver(adaptor, snes)); 45709566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 45719566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetFromOptions(adaptor)); 45729566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetUp(adaptor)); 45739566063dSJacob Faibussowitsch PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x)); 45749566063dSJacob Faibussowitsch PetscCall(DMAdaptorDestroy(&adaptor)); 457534b4d3a8SMatthew G. Knepley incall = PETSC_FALSE; 457634b4d3a8SMatthew G. Knepley } 45777c88af5aSMatthew G. Knepley /* Use grid sequencing to adapt */ 45787c88af5aSMatthew G. Knepley num = 0; 45799566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_sequence", &num, NULL)); 45807c88af5aSMatthew G. Knepley if (num) { 45817c88af5aSMatthew G. Knepley DMAdaptor adaptor; 45827c88af5aSMatthew G. Knepley 45837c88af5aSMatthew G. Knepley incall = PETSC_TRUE; 45849566063dSJacob Faibussowitsch PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 45859566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSolver(adaptor, snes)); 45869566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 45879566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetFromOptions(adaptor)); 45889566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetUp(adaptor)); 45899566063dSJacob Faibussowitsch PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x)); 45909566063dSJacob Faibussowitsch PetscCall(DMAdaptorDestroy(&adaptor)); 45917c88af5aSMatthew G. Knepley incall = PETSC_FALSE; 45927c88af5aSMatthew G. Knepley } 459306fc46c8SMatthew G. Knepley } 459406fc46c8SMatthew G. Knepley } 4595ad540459SPierre Jolivet if (!x) x = snes->vec_sol; 4596caa4e7f2SJed Brown if (!x) { 45979566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 45989566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dm, &xcreated)); 4599a69afd8bSBarry Smith x = xcreated; 4600a69afd8bSBarry Smith } 46019566063dSJacob Faibussowitsch PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view_pre")); 4602f05ece33SBarry Smith 46039566063dSJacob Faibussowitsch for (grid = 0; grid < snes->gridsequence; grid++) PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4604efd51863SBarry Smith for (grid = 0; grid < snes->gridsequence + 1; grid++) { 460585385478SLisandro Dalcin /* set solution vector */ 46069566063dSJacob Faibussowitsch if (!grid) PetscCall(PetscObjectReference((PetscObject)x)); 46079566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 460885385478SLisandro Dalcin snes->vec_sol = x; 46099566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 4610caa4e7f2SJed Brown 4611caa4e7f2SJed Brown /* set affine vector if provided */ 46129566063dSJacob Faibussowitsch if (b) PetscCall(PetscObjectReference((PetscObject)b)); 46139566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_rhs)); 461485385478SLisandro Dalcin snes->vec_rhs = b; 461585385478SLisandro Dalcin 46165f80ce2aSJacob Faibussowitsch if (snes->vec_rhs) PetscCheck(snes->vec_func != snes->vec_rhs, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Right hand side vector cannot be function vector"); 46175f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_func != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be function vector"); 46185f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_rhs != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be right hand side vector"); 4619aa624791SPierre Jolivet if (!snes->vec_sol_update /* && snes->vec_sol */) PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_sol_update)); 46209566063dSJacob Faibussowitsch PetscCall(DMShellSetGlobalVector(dm, snes->vec_sol)); 46219566063dSJacob Faibussowitsch PetscCall(SNESSetUp(snes)); 46223f149594SLisandro Dalcin 46237eee914bSBarry Smith if (!grid) { 462425e27a38SBarry Smith if (snes->ops->computeinitialguess) PetscCallBack("SNES callback initial guess", (*snes->ops->computeinitialguess)(snes, snes->vec_sol, snes->initialguessP)); 4625dd568438SSatish Balay } 4626d25893d9SBarry Smith 4627abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 46289371c9d4SSatish Balay if (snes->counters_reset) { 46299371c9d4SSatish Balay snes->nfuncs = 0; 46309371c9d4SSatish Balay snes->linear_its = 0; 46319371c9d4SSatish Balay snes->numFailures = 0; 46329371c9d4SSatish Balay } 4633d5e45103SBarry Smith 46342d157150SStefano Zampini snes->reason = SNES_CONVERGED_ITERATING; 46359566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_Solve, snes, 0, 0, 0)); 4636dbbe0bcdSBarry Smith PetscUseTypeMethod(snes, solve); 46379566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_Solve, snes, 0, 0, 0)); 46382d157150SStefano Zampini PetscCheck(snes->reason, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Internal error, solver %s returned without setting converged reason", ((PetscObject)snes)->type_name); 4639422a814eSBarry Smith snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 46403f149594SLisandro Dalcin 464137ec4e1aSPeter Brune if (snes->lagjac_persist) snes->jac_iter += snes->iter; 464237ec4e1aSPeter Brune if (snes->lagpre_persist) snes->pre_iter += snes->iter; 464337ec4e1aSPeter Brune 46449566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_test_local_min", NULL, NULL, &flg)); 46459566063dSJacob Faibussowitsch if (flg && !PetscPreLoadingOn) PetscCall(SNESTestLocalMin(snes)); 4646c4421ceaSFande Kong /* Call converged reason views. This may involve user-provided viewers as well */ 46479566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonViewFromOptions(snes)); 46485968eb51SBarry Smith 46495f80ce2aSJacob Faibussowitsch if (snes->errorifnotconverged) PetscCheck(snes->reason >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_NOT_CONVERGED, "SNESSolve has not converged"); 46509c8e83a9SBarry Smith if (snes->reason < 0) break; 4651efd51863SBarry Smith if (grid < snes->gridsequence) { 4652efd51863SBarry Smith DM fine; 4653efd51863SBarry Smith Vec xnew; 4654efd51863SBarry Smith Mat interp; 4655efd51863SBarry Smith 46569566063dSJacob Faibussowitsch PetscCall(DMRefine(snes->dm, PetscObjectComm((PetscObject)snes), &fine)); 46575f80ce2aSJacob Faibussowitsch PetscCheck(fine, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_INCOMP, "DMRefine() did not perform any refinement, cannot continue grid sequencing"); 46589566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(snes->dm, fine, &interp, NULL)); 46599566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(fine, &xnew)); 46609566063dSJacob Faibussowitsch PetscCall(MatInterpolate(interp, x, xnew)); 46619566063dSJacob Faibussowitsch PetscCall(DMInterpolate(snes->dm, interp, fine)); 46629566063dSJacob Faibussowitsch PetscCall(MatDestroy(&interp)); 4663efd51863SBarry Smith x = xnew; 4664efd51863SBarry Smith 46659566063dSJacob Faibussowitsch PetscCall(SNESReset(snes)); 46669566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes, fine)); 46679566063dSJacob Faibussowitsch PetscCall(SNESResetFromOptions(snes)); 46689566063dSJacob Faibussowitsch PetscCall(DMDestroy(&fine)); 46699566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4670efd51863SBarry Smith } 4671efd51863SBarry Smith } 46729566063dSJacob Faibussowitsch PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view")); 46739566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(snes->vec_sol, (PetscObject)snes, "-snes_view_solution")); 46749566063dSJacob Faibussowitsch PetscCall(DMMonitor(snes->dm)); 46759566063dSJacob Faibussowitsch PetscCall(SNESMonitorPauseFinal_Internal(snes)); 46763f7e2da0SPeter Brune 46779566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xcreated)); 46789566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsBlock((PetscObject)snes)); 46793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 46809b94acceSBarry Smith } 46819b94acceSBarry Smith 46829b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 46839b94acceSBarry Smith 468482bf6240SBarry Smith /*@C 46854b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 46869b94acceSBarry Smith 4687c3339decSBarry Smith Collective 4688fee21e36SBarry Smith 4689c7afd0dbSLois Curfman McInnes Input Parameters: 4690f6dfbefdSBarry Smith + snes - the `SNES` context 4691454a90a3SBarry Smith - type - a known method 4692c7afd0dbSLois Curfman McInnes 4693c7afd0dbSLois Curfman McInnes Options Database Key: 4694454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 469504d7464bSBarry Smith of available methods (for instance, newtonls or newtontr) 4696ae12b187SLois Curfman McInnes 4697dc4c0fb0SBarry Smith Level: intermediate 4698dc4c0fb0SBarry Smith 46999b94acceSBarry Smith Notes: 4700e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 4701f6dfbefdSBarry Smith + `SNESNEWTONLS` - Newton's method with line search 4702c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 47034a221d59SStefano Zampini - `SNESNEWTONTR` - Newton's method with trust region 4704c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 47059b94acceSBarry Smith 4706f6dfbefdSBarry Smith Normally, it is best to use the `SNESSetFromOptions()` command and then 4707f6dfbefdSBarry Smith set the `SNES` solver type from the options database rather than by using 4708ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 4709ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 4710f6dfbefdSBarry Smith The `SNESSetType()` routine is provided for those situations where it 4711ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 4712ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 4713ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 4714ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 4715b0a32e0cSBarry Smith appropriate method. 471636851e7fSLois Curfman McInnes 4717e4094ef1SJacob Faibussowitsch Developer Notes: 4718f6dfbefdSBarry Smith `SNESRegister()` adds a constructor for a new `SNESType` to `SNESList`, `SNESSetType()` locates 4719f6dfbefdSBarry Smith the constructor in that list and calls it to create the specific object. 47208f6c3df8SBarry Smith 47211cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESType`, `SNESCreate()`, `SNESDestroy()`, `SNESGetType()`, `SNESSetFromOptions()` 47229b94acceSBarry Smith @*/ 4723d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetType(SNES snes, SNESType type) 4724d71ae5a4SJacob Faibussowitsch { 4725ace3abfcSBarry Smith PetscBool match; 47265f80ce2aSJacob Faibussowitsch PetscErrorCode (*r)(SNES); 47273a40ed3dSBarry Smith 47283a40ed3dSBarry Smith PetscFunctionBegin; 47290700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 47304f572ea9SToby Isaac PetscAssertPointer(type, 2); 473182bf6240SBarry Smith 47329566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, type, &match)); 47333ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 473492ff6ae8SBarry Smith 47359566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(SNESList, type, &r)); 47366adde796SStefano Zampini PetscCheck(r, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested SNES type %s", type); 473775396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 4738dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, destroy); 473975396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 47409e5d0892SLisandro Dalcin snes->ops->setup = NULL; 47419e5d0892SLisandro Dalcin snes->ops->solve = NULL; 47429e5d0892SLisandro Dalcin snes->ops->view = NULL; 47439e5d0892SLisandro Dalcin snes->ops->setfromoptions = NULL; 47449e5d0892SLisandro Dalcin snes->ops->destroy = NULL; 47457fe760d5SStefano Zampini 47467fe760d5SStefano Zampini /* It may happen the user has customized the line search before calling SNESSetType */ 47479566063dSJacob Faibussowitsch if (((PetscObject)snes)->type_name) PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 47487fe760d5SStefano Zampini 474975396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 475075396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 4751f5af7f23SKarl Rupp 47529566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)snes, type)); 47539566063dSJacob Faibussowitsch PetscCall((*r)(snes)); 47543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 47559b94acceSBarry Smith } 47569b94acceSBarry Smith 47579b94acceSBarry Smith /*@C 4758f6dfbefdSBarry Smith SNESGetType - Gets the `SNES` method type and name (as a string). 47599b94acceSBarry Smith 4760c7afd0dbSLois Curfman McInnes Not Collective 4761c7afd0dbSLois Curfman McInnes 47629b94acceSBarry Smith Input Parameter: 47634b0e389bSBarry Smith . snes - nonlinear solver context 47649b94acceSBarry Smith 47659b94acceSBarry Smith Output Parameter: 4766f6dfbefdSBarry Smith . type - `SNES` method (a character string) 47679b94acceSBarry Smith 476836851e7fSLois Curfman McInnes Level: intermediate 476936851e7fSLois Curfman McInnes 47701cc06b55SBarry Smith .seealso: [](ch_snes), `SNESSetType()`, `SNESType`, `SNESSetFromOptions()`, `SNES` 47719b94acceSBarry Smith @*/ 4772d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetType(SNES snes, SNESType *type) 4773d71ae5a4SJacob Faibussowitsch { 47743a40ed3dSBarry Smith PetscFunctionBegin; 47750700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 47764f572ea9SToby Isaac PetscAssertPointer(type, 2); 47777adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 47783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 47799b94acceSBarry Smith } 47809b94acceSBarry Smith 47813cd8a7caSMatthew G. Knepley /*@ 4782f6dfbefdSBarry Smith SNESSetSolution - Sets the solution vector for use by the `SNES` routines. 47833cd8a7caSMatthew G. Knepley 4784c3339decSBarry Smith Logically Collective 47853cd8a7caSMatthew G. Knepley 47863cd8a7caSMatthew G. Knepley Input Parameters: 4787f6dfbefdSBarry Smith + snes - the `SNES` context obtained from `SNESCreate()` 47883cd8a7caSMatthew G. Knepley - u - the solution vector 47893cd8a7caSMatthew G. Knepley 47903cd8a7caSMatthew G. Knepley Level: beginner 47913cd8a7caSMatthew G. Knepley 47921cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESGetSolution()`, `Vec` 47933cd8a7caSMatthew G. Knepley @*/ 4794d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetSolution(SNES snes, Vec u) 4795d71ae5a4SJacob Faibussowitsch { 47963cd8a7caSMatthew G. Knepley DM dm; 47973cd8a7caSMatthew G. Knepley 47983cd8a7caSMatthew G. Knepley PetscFunctionBegin; 47993cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48003cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 48019566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)u)); 48029566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 48033cd8a7caSMatthew G. Knepley 48043cd8a7caSMatthew G. Knepley snes->vec_sol = u; 48053cd8a7caSMatthew G. Knepley 48069566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 48079566063dSJacob Faibussowitsch PetscCall(DMShellSetGlobalVector(dm, u)); 48083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48093cd8a7caSMatthew G. Knepley } 48103cd8a7caSMatthew G. Knepley 481152baeb72SSatish Balay /*@ 48129b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 4813f6dfbefdSBarry Smith stored. This is the fine grid solution when using `SNESSetGridSequence()`. 48149b94acceSBarry Smith 4815f6dfbefdSBarry Smith Not Collective, but x is parallel if snes is parallel 4816c7afd0dbSLois Curfman McInnes 48179b94acceSBarry Smith Input Parameter: 4818f6dfbefdSBarry Smith . snes - the `SNES` context 48199b94acceSBarry Smith 48209b94acceSBarry Smith Output Parameter: 48219b94acceSBarry Smith . x - the solution 48229b94acceSBarry Smith 482370e92668SMatthew Knepley Level: intermediate 482436851e7fSLois Curfman McInnes 48251cc06b55SBarry Smith .seealso: [](ch_snes), `SNESSetSolution()`, `SNESSolve()`, `SNES`, `SNESGetSolutionUpdate()`, `SNESGetFunction()` 48269b94acceSBarry Smith @*/ 4827d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolution(SNES snes, Vec *x) 4828d71ae5a4SJacob Faibussowitsch { 48293a40ed3dSBarry Smith PetscFunctionBegin; 48300700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48314f572ea9SToby Isaac PetscAssertPointer(x, 2); 483285385478SLisandro Dalcin *x = snes->vec_sol; 48333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 483470e92668SMatthew Knepley } 483570e92668SMatthew Knepley 483652baeb72SSatish Balay /*@ 48379b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 48389b94acceSBarry Smith stored. 48399b94acceSBarry Smith 4840f6dfbefdSBarry Smith Not Collective, but x is parallel if snes is parallel 4841c7afd0dbSLois Curfman McInnes 48429b94acceSBarry Smith Input Parameter: 4843f6dfbefdSBarry Smith . snes - the `SNES` context 48449b94acceSBarry Smith 48459b94acceSBarry Smith Output Parameter: 48469b94acceSBarry Smith . x - the solution update 48479b94acceSBarry Smith 484836851e7fSLois Curfman McInnes Level: advanced 484936851e7fSLois Curfman McInnes 48501cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESGetSolution()`, `SNESGetFunction()` 48519b94acceSBarry Smith @*/ 4852d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolutionUpdate(SNES snes, Vec *x) 4853d71ae5a4SJacob Faibussowitsch { 48543a40ed3dSBarry Smith PetscFunctionBegin; 48550700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48564f572ea9SToby Isaac PetscAssertPointer(x, 2); 485785385478SLisandro Dalcin *x = snes->vec_sol_update; 48583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48599b94acceSBarry Smith } 48609b94acceSBarry Smith 48619b94acceSBarry Smith /*@C 4862f6dfbefdSBarry Smith SNESGetFunction - Returns the function that defines the nonlinear system set with `SNESSetFunction()` 48639b94acceSBarry Smith 4864f6dfbefdSBarry Smith Not Collective, but r is parallel if snes is parallel. Collective if r is requested, but has not been created yet. 4865c7afd0dbSLois Curfman McInnes 48669b94acceSBarry Smith Input Parameter: 4867f6dfbefdSBarry Smith . snes - the `SNES` context 48689b94acceSBarry Smith 4869d8d19677SJose E. Roman Output Parameters: 4870dc4c0fb0SBarry Smith + r - the vector that is used to store residuals (or `NULL` if you don't want it) 487120f4b53cSBarry Smith . f - the function (or `NULL` if you don't want it); for calling sequence see `SNESFunction` 4872dc4c0fb0SBarry Smith - ctx - the function context (or `NULL` if you don't want it) 48739b94acceSBarry Smith 487436851e7fSLois Curfman McInnes Level: advanced 487536851e7fSLois Curfman McInnes 4876f6dfbefdSBarry Smith Note: 4877dc4c0fb0SBarry Smith The vector `r` DOES NOT, in general, contain the current value of the `SNES` nonlinear function 487804edfde5SBarry Smith 4879e4094ef1SJacob Faibussowitsch .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetFunction()`, `SNESGetSolution()`, `SNESFunction` 48809b94acceSBarry Smith @*/ 4881d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunction(SNES snes, Vec *r, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) 4882d71ae5a4SJacob Faibussowitsch { 48836cab3a1bSJed Brown DM dm; 4884a63bb30eSJed Brown 48853a40ed3dSBarry Smith PetscFunctionBegin; 48860700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4887a63bb30eSJed Brown if (r) { 4888a63bb30eSJed Brown if (!snes->vec_func) { 4889a63bb30eSJed Brown if (snes->vec_rhs) { 48909566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_rhs, &snes->vec_func)); 4891a63bb30eSJed Brown } else if (snes->vec_sol) { 48929566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_func)); 4893a63bb30eSJed Brown } else if (snes->dm) { 48949566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(snes->dm, &snes->vec_func)); 4895a63bb30eSJed Brown } 4896a63bb30eSJed Brown } 4897a63bb30eSJed Brown *r = snes->vec_func; 4898a63bb30eSJed Brown } 48999566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 49009566063dSJacob Faibussowitsch PetscCall(DMSNESGetFunction(dm, f, ctx)); 49013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 49029b94acceSBarry Smith } 49039b94acceSBarry Smith 4904c79ef259SPeter Brune /*@C 490537fdd005SBarry Smith SNESGetNGS - Returns the function and context set with `SNESSetNGS()` 4906c79ef259SPeter Brune 4907c79ef259SPeter Brune Input Parameter: 4908f6dfbefdSBarry Smith . snes - the `SNES` context 4909c79ef259SPeter Brune 4910d8d19677SJose E. Roman Output Parameters: 491137fdd005SBarry Smith + f - the function (or `NULL`) see `SNESSetNGS()` for details 4912dc4c0fb0SBarry Smith - ctx - the function context (or `NULL`) 4913c79ef259SPeter Brune 4914c79ef259SPeter Brune Level: advanced 4915c79ef259SPeter Brune 49161cc06b55SBarry Smith .seealso: [](ch_snes), `SNESSetNGS()`, `SNESGetFunction()` 4917c79ef259SPeter Brune @*/ 4918d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNGS(SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) 4919d71ae5a4SJacob Faibussowitsch { 49206cab3a1bSJed Brown DM dm; 49216cab3a1bSJed Brown 4922646217ecSPeter Brune PetscFunctionBegin; 4923646217ecSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49249566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 49259566063dSJacob Faibussowitsch PetscCall(DMSNESGetNGS(dm, f, ctx)); 49263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4927646217ecSPeter Brune } 4928646217ecSPeter Brune 49293c7409f5SSatish Balay /*@C 49303c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 4931f6dfbefdSBarry Smith `SNES` options in the database. 49323c7409f5SSatish Balay 4933c3339decSBarry Smith Logically Collective 4934fee21e36SBarry Smith 4935d8d19677SJose E. Roman Input Parameters: 4936f6dfbefdSBarry Smith + snes - the `SNES` context 4937c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4938c7afd0dbSLois Curfman McInnes 4939dc4c0fb0SBarry Smith Level: advanced 4940dc4c0fb0SBarry Smith 4941f6dfbefdSBarry Smith Note: 4942a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4943c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4944d850072dSLois Curfman McInnes 49451cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetFromOptions()`, `SNESAppendOptionsPrefix()` 49463c7409f5SSatish Balay @*/ 4947d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetOptionsPrefix(SNES snes, const char prefix[]) 4948d71ae5a4SJacob Faibussowitsch { 49493a40ed3dSBarry Smith PetscFunctionBegin; 49500700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49519566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes, prefix)); 49529566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 495335f5d045SPeter Brune if (snes->linesearch) { 49549566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 49559566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch, prefix)); 495635f5d045SPeter Brune } 49579566063dSJacob Faibussowitsch PetscCall(KSPSetOptionsPrefix(snes->ksp, prefix)); 49583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 49593c7409f5SSatish Balay } 49603c7409f5SSatish Balay 49613c7409f5SSatish Balay /*@C 4962f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 4963f6dfbefdSBarry Smith `SNES` options in the database. 49643c7409f5SSatish Balay 4965c3339decSBarry Smith Logically Collective 4966fee21e36SBarry Smith 4967c7afd0dbSLois Curfman McInnes Input Parameters: 4968f6dfbefdSBarry Smith + snes - the `SNES` context 4969c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4970c7afd0dbSLois Curfman McInnes 4971dc4c0fb0SBarry Smith Level: advanced 4972dc4c0fb0SBarry Smith 4973f6dfbefdSBarry Smith Note: 4974a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4975c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4976d850072dSLois Curfman McInnes 49771cc06b55SBarry Smith .seealso: [](ch_snes), `SNESGetOptionsPrefix()`, `SNESSetOptionsPrefix()` 49783c7409f5SSatish Balay @*/ 4979d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESAppendOptionsPrefix(SNES snes, const char prefix[]) 4980d71ae5a4SJacob Faibussowitsch { 49813a40ed3dSBarry Smith PetscFunctionBegin; 49820700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49839566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes, prefix)); 49849566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 498535f5d045SPeter Brune if (snes->linesearch) { 49869566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 49879566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch, prefix)); 498835f5d045SPeter Brune } 49899566063dSJacob Faibussowitsch PetscCall(KSPAppendOptionsPrefix(snes->ksp, prefix)); 49903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 49913c7409f5SSatish Balay } 49923c7409f5SSatish Balay 49939ab63eb5SSatish Balay /*@C 4994f6dfbefdSBarry Smith SNESGetOptionsPrefix - Gets the prefix used for searching for all 4995f6dfbefdSBarry Smith `SNES` options in the database. 49963c7409f5SSatish Balay 4997c7afd0dbSLois Curfman McInnes Not Collective 4998c7afd0dbSLois Curfman McInnes 49993c7409f5SSatish Balay Input Parameter: 5000f6dfbefdSBarry Smith . snes - the `SNES` context 50013c7409f5SSatish Balay 50023c7409f5SSatish Balay Output Parameter: 50033c7409f5SSatish Balay . prefix - pointer to the prefix string used 50043c7409f5SSatish Balay 500536851e7fSLois Curfman McInnes Level: advanced 500636851e7fSLois Curfman McInnes 5007e4094ef1SJacob Faibussowitsch Fortran Notes: 5008dc4c0fb0SBarry Smith The user should pass in a string 'prefix' of 5009dc4c0fb0SBarry Smith sufficient length to hold the prefix. 5010dc4c0fb0SBarry Smith 50111cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetOptionsPrefix()`, `SNESAppendOptionsPrefix()` 50123c7409f5SSatish Balay @*/ 5013d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetOptionsPrefix(SNES snes, const char *prefix[]) 5014d71ae5a4SJacob Faibussowitsch { 50153a40ed3dSBarry Smith PetscFunctionBegin; 50160700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 50179566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)snes, prefix)); 50183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 50193c7409f5SSatish Balay } 50203c7409f5SSatish Balay 50213cea93caSBarry Smith /*@C 50221c84c290SBarry Smith SNESRegister - Adds a method to the nonlinear solver package. 50231c84c290SBarry Smith 502420f4b53cSBarry Smith Not Collective 50251c84c290SBarry Smith 50261c84c290SBarry Smith Input Parameters: 502720f4b53cSBarry Smith + sname - name of a new user-defined solver 502820f4b53cSBarry Smith - function - routine to create method context 50291c84c290SBarry Smith 5030dc4c0fb0SBarry Smith Level: advanced 5031dc4c0fb0SBarry Smith 5032f6dfbefdSBarry Smith Note: 5033f6dfbefdSBarry Smith `SNESRegister()` may be called multiple times to add several user-defined solvers. 50341c84c290SBarry Smith 5035e4094ef1SJacob Faibussowitsch Example Usage: 50361c84c290SBarry Smith .vb 5037bdf89e91SBarry Smith SNESRegister("my_solver", MySolverCreate); 50381c84c290SBarry Smith .ve 50391c84c290SBarry Smith 50401c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 50411c84c290SBarry Smith $ SNESSetType(snes, "my_solver") 50421c84c290SBarry Smith or at runtime via the option 50431c84c290SBarry Smith $ -snes_type my_solver 50441c84c290SBarry Smith 50451cc06b55SBarry Smith .seealso: [](ch_snes), `SNESRegisterAll()`, `SNESRegisterDestroy()` 50463cea93caSBarry Smith @*/ 5047d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESRegister(const char sname[], PetscErrorCode (*function)(SNES)) 5048d71ae5a4SJacob Faibussowitsch { 5049b2002411SLois Curfman McInnes PetscFunctionBegin; 50509566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 50519566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&SNESList, sname, function)); 50523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5053b2002411SLois Curfman McInnes } 5054da9b6338SBarry Smith 5055d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESTestLocalMin(SNES snes) 5056d71ae5a4SJacob Faibussowitsch { 505777431f27SBarry Smith PetscInt N, i, j; 5058da9b6338SBarry Smith Vec u, uh, fh; 5059da9b6338SBarry Smith PetscScalar value; 5060da9b6338SBarry Smith PetscReal norm; 5061da9b6338SBarry Smith 5062da9b6338SBarry Smith PetscFunctionBegin; 50639566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &u)); 50649566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &uh)); 50659566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &fh)); 5066da9b6338SBarry Smith 5067da9b6338SBarry Smith /* currently only works for sequential */ 50689566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Testing FormFunction() for local min\n")); 50699566063dSJacob Faibussowitsch PetscCall(VecGetSize(u, &N)); 5070da9b6338SBarry Smith for (i = 0; i < N; i++) { 50719566063dSJacob Faibussowitsch PetscCall(VecCopy(u, uh)); 507263a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "i = %" PetscInt_FMT "\n", i)); 5073da9b6338SBarry Smith for (j = -10; j < 11; j++) { 50748b49ba18SBarry Smith value = PetscSign(j) * PetscExpReal(PetscAbs(j) - 10.0); 50759566063dSJacob Faibussowitsch PetscCall(VecSetValue(uh, i, value, ADD_VALUES)); 50769566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, uh, fh)); 50779566063dSJacob Faibussowitsch PetscCall(VecNorm(fh, NORM_2, &norm)); 507863a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), " j norm %" PetscInt_FMT " %18.16e\n", j, (double)norm)); 5079da9b6338SBarry Smith value = -value; 50809566063dSJacob Faibussowitsch PetscCall(VecSetValue(uh, i, value, ADD_VALUES)); 5081da9b6338SBarry Smith } 5082da9b6338SBarry Smith } 50839566063dSJacob Faibussowitsch PetscCall(VecDestroy(&uh)); 50849566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fh)); 50853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5086da9b6338SBarry Smith } 508771f87433Sdalcinl 508871f87433Sdalcinl /*@ 5089f6dfbefdSBarry Smith SNESKSPSetUseEW - Sets `SNES` to the use Eisenstat-Walker method for 509071f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 509171f87433Sdalcinl Newton method. 509271f87433Sdalcinl 5093c3339decSBarry Smith Logically Collective 509471f87433Sdalcinl 509571f87433Sdalcinl Input Parameters: 5096f6dfbefdSBarry Smith + snes - `SNES` context 5097f6dfbefdSBarry Smith - flag - `PETSC_TRUE` or `PETSC_FALSE` 509871f87433Sdalcinl 5099f6dfbefdSBarry Smith Options Database Keys: 510064ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 510164ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 510264ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 510364ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 510464ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 510564ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 510664ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 510764ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 510864ba62caSBarry Smith 5109dc4c0fb0SBarry Smith Level: advanced 5110dc4c0fb0SBarry Smith 5111f6dfbefdSBarry Smith Note: 5112f6dfbefdSBarry Smith The default is to use a constant relative tolerance for 511371f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 511471f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 511571f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 511671f87433Sdalcinl solver. 511771f87433Sdalcinl 5118e4094ef1SJacob Faibussowitsch References: 5119f6dfbefdSBarry Smith . - * S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an inexact Newton method", SISC 17 (1), pp.16-32, 1996. 512071f87433Sdalcinl 51211cc06b55SBarry Smith .seealso: [](ch_snes), `KSP`, `SNES`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 512271f87433Sdalcinl @*/ 5123d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPSetUseEW(SNES snes, PetscBool flag) 5124d71ae5a4SJacob Faibussowitsch { 512571f87433Sdalcinl PetscFunctionBegin; 51260700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5127acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes, flag, 2); 512871f87433Sdalcinl snes->ksp_ewconv = flag; 51293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 513071f87433Sdalcinl } 513171f87433Sdalcinl 513271f87433Sdalcinl /*@ 5133f6dfbefdSBarry Smith SNESKSPGetUseEW - Gets if `SNES` is using Eisenstat-Walker method 513471f87433Sdalcinl for computing relative tolerance for linear solvers within an 513571f87433Sdalcinl inexact Newton method. 513671f87433Sdalcinl 513771f87433Sdalcinl Not Collective 513871f87433Sdalcinl 513971f87433Sdalcinl Input Parameter: 5140f6dfbefdSBarry Smith . snes - `SNES` context 514171f87433Sdalcinl 514271f87433Sdalcinl Output Parameter: 5143f6dfbefdSBarry Smith . flag - `PETSC_TRUE` or `PETSC_FALSE` 514471f87433Sdalcinl 514571f87433Sdalcinl Level: advanced 514671f87433Sdalcinl 51471cc06b55SBarry Smith .seealso: [](ch_snes), `SNESKSPSetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 514871f87433Sdalcinl @*/ 5149d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 5150d71ae5a4SJacob Faibussowitsch { 515171f87433Sdalcinl PetscFunctionBegin; 51520700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 51534f572ea9SToby Isaac PetscAssertPointer(flag, 2); 515471f87433Sdalcinl *flag = snes->ksp_ewconv; 51553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 515671f87433Sdalcinl } 515771f87433Sdalcinl 515871f87433Sdalcinl /*@ 5159fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 516071f87433Sdalcinl convergence criteria for the linear solvers within an inexact 516171f87433Sdalcinl Newton method. 516271f87433Sdalcinl 5163c3339decSBarry Smith Logically Collective 516471f87433Sdalcinl 516571f87433Sdalcinl Input Parameters: 5166f6dfbefdSBarry Smith + snes - `SNES` context 51670f0abf79SStefano Zampini . version - version 1, 2 (default is 2), 3 or 4 516871f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 516971f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 517071f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 517171f87433Sdalcinl (0 <= gamma2 <= 1) 517271f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 517371f87433Sdalcinl . alpha2 - power for safeguard 517471f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 517571f87433Sdalcinl 5176dc4c0fb0SBarry Smith Level: advanced 5177dc4c0fb0SBarry Smith 5178f6dfbefdSBarry Smith Notes: 517971f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 518071f87433Sdalcinl 5181f6dfbefdSBarry Smith Use `PETSC_DEFAULT` to retain the default for any of the parameters. 518271f87433Sdalcinl 51831cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()` 518471f87433Sdalcinl @*/ 5185d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPSetParametersEW(SNES snes, PetscInt version, PetscReal rtol_0, PetscReal rtol_max, PetscReal gamma, PetscReal alpha, PetscReal alpha2, PetscReal threshold) 5186d71ae5a4SJacob Faibussowitsch { 5187fa9f3622SBarry Smith SNESKSPEW *kctx; 51885fd66863SKarl Rupp 518971f87433Sdalcinl PetscFunctionBegin; 51900700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5191fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 51925f80ce2aSJacob Faibussowitsch PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing"); 5193c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, version, 2); 5194c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol_0, 3); 5195c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol_max, 4); 5196c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, gamma, 5); 5197c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, alpha, 6); 5198c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, alpha2, 7); 5199c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, threshold, 8); 520071f87433Sdalcinl 520171f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 520213bcc0bdSJacob Faibussowitsch if (rtol_0 != (PetscReal)PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 520313bcc0bdSJacob Faibussowitsch if (rtol_max != (PetscReal)PETSC_DEFAULT) kctx->rtol_max = rtol_max; 520413bcc0bdSJacob Faibussowitsch if (gamma != (PetscReal)PETSC_DEFAULT) kctx->gamma = gamma; 520513bcc0bdSJacob Faibussowitsch if (alpha != (PetscReal)PETSC_DEFAULT) kctx->alpha = alpha; 520613bcc0bdSJacob Faibussowitsch if (alpha2 != (PetscReal)PETSC_DEFAULT) kctx->alpha2 = alpha2; 520713bcc0bdSJacob Faibussowitsch if (threshold != (PetscReal)PETSC_DEFAULT) kctx->threshold = threshold; 520871f87433Sdalcinl 52090f0abf79SStefano Zampini PetscCheck(kctx->version >= 1 && kctx->version <= 4, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Only versions 1 to 4 are supported: %" PetscInt_FMT, kctx->version); 52100b121fc5SBarry Smith PetscCheck(kctx->rtol_0 >= 0.0 && kctx->rtol_0 < 1.0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "0.0 <= rtol_0 < 1.0: %g", (double)kctx->rtol_0); 52110b121fc5SBarry Smith PetscCheck(kctx->rtol_max >= 0.0 && kctx->rtol_max < 1.0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "0.0 <= rtol_max (%g) < 1.0", (double)kctx->rtol_max); 52120b121fc5SBarry Smith PetscCheck(kctx->gamma >= 0.0 && kctx->gamma <= 1.0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "0.0 <= gamma (%g) <= 1.0", (double)kctx->gamma); 52130b121fc5SBarry Smith PetscCheck(kctx->alpha > 1.0 && kctx->alpha <= 2.0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "1.0 < alpha (%g) <= 2.0", (double)kctx->alpha); 52140b121fc5SBarry Smith PetscCheck(kctx->threshold > 0.0 && kctx->threshold < 1.0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "0.0 < threshold (%g) < 1.0", (double)kctx->threshold); 52153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 521671f87433Sdalcinl } 521771f87433Sdalcinl 521871f87433Sdalcinl /*@ 5219fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 522071f87433Sdalcinl convergence criteria for the linear solvers within an inexact 522171f87433Sdalcinl Newton method. 522271f87433Sdalcinl 522371f87433Sdalcinl Not Collective 522471f87433Sdalcinl 522597bb3fdcSJose E. Roman Input Parameter: 5226f6dfbefdSBarry Smith . snes - `SNES` context 522771f87433Sdalcinl 522871f87433Sdalcinl Output Parameters: 52290f0abf79SStefano Zampini + version - version 1, 2 (default is 2), 3 or 4 523071f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 523171f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 5232bf388a1fSBarry Smith . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 523371f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 523471f87433Sdalcinl . alpha2 - power for safeguard 523571f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 523671f87433Sdalcinl 523771f87433Sdalcinl Level: advanced 523871f87433Sdalcinl 52391cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPSetParametersEW()` 524071f87433Sdalcinl @*/ 5241d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPGetParametersEW(SNES snes, PetscInt *version, PetscReal *rtol_0, PetscReal *rtol_max, PetscReal *gamma, PetscReal *alpha, PetscReal *alpha2, PetscReal *threshold) 5242d71ae5a4SJacob Faibussowitsch { 5243fa9f3622SBarry Smith SNESKSPEW *kctx; 52445fd66863SKarl Rupp 524571f87433Sdalcinl PetscFunctionBegin; 52460700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5247fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 52485f80ce2aSJacob Faibussowitsch PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing"); 524971f87433Sdalcinl if (version) *version = kctx->version; 525071f87433Sdalcinl if (rtol_0) *rtol_0 = kctx->rtol_0; 525171f87433Sdalcinl if (rtol_max) *rtol_max = kctx->rtol_max; 525271f87433Sdalcinl if (gamma) *gamma = kctx->gamma; 525371f87433Sdalcinl if (alpha) *alpha = kctx->alpha; 525471f87433Sdalcinl if (alpha2) *alpha2 = kctx->alpha2; 525571f87433Sdalcinl if (threshold) *threshold = kctx->threshold; 52563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 525771f87433Sdalcinl } 525871f87433Sdalcinl 5259d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 5260d71ae5a4SJacob Faibussowitsch { 5261fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx; 526271f87433Sdalcinl PetscReal rtol = PETSC_DEFAULT, stol; 526371f87433Sdalcinl 526471f87433Sdalcinl PetscFunctionBegin; 52653ba16761SJacob Faibussowitsch if (!snes->ksp_ewconv) PetscFunctionReturn(PETSC_SUCCESS); 526630058271SDmitry Karpeev if (!snes->iter) { 526730058271SDmitry Karpeev rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 52689566063dSJacob Faibussowitsch PetscCall(VecNorm(snes->vec_func, NORM_2, &kctx->norm_first)); 52690f0abf79SStefano Zampini } else { 52700fdf79fbSJacob Faibussowitsch PetscCheck(kctx->version >= 1 && kctx->version <= 4, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Only versions 1-4 are supported: %" PetscInt_FMT, kctx->version); 527171f87433Sdalcinl if (kctx->version == 1) { 52720f0abf79SStefano Zampini rtol = PetscAbsReal(snes->norm - kctx->lresid_last) / kctx->norm_last; 527385ec1a3cSBarry Smith stol = PetscPowReal(kctx->rtol_last, kctx->alpha2); 527471f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol, stol); 527571f87433Sdalcinl } else if (kctx->version == 2) { 527685ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha); 527785ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha); 527871f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol, stol); 527971f87433Sdalcinl } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 528085ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha); 528171f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 528285ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha); 528371f87433Sdalcinl stol = PetscMax(rtol, stol); 528471f87433Sdalcinl rtol = PetscMin(kctx->rtol_0, stol); 528571f87433Sdalcinl /* safeguard: avoid oversolving */ 528630058271SDmitry Karpeev stol = kctx->gamma * (kctx->norm_first * snes->rtol) / snes->norm; 528771f87433Sdalcinl stol = PetscMax(rtol, stol); 528871f87433Sdalcinl rtol = PetscMin(kctx->rtol_0, stol); 52890fdf79fbSJacob Faibussowitsch } else /* if (kctx->version == 4) */ { 52900fdf79fbSJacob Faibussowitsch /* H.-B. An et al. Journal of Computational and Applied Mathematics 200 (2007) 47-60 */ 52910f0abf79SStefano Zampini PetscReal ared = PetscAbsReal(kctx->norm_last - snes->norm); 52920f0abf79SStefano Zampini PetscReal pred = PetscAbsReal(kctx->norm_last - kctx->lresid_last); 52930f0abf79SStefano Zampini PetscReal rk = ared / pred; 52940f0abf79SStefano Zampini if (rk < kctx->v4_p1) rtol = 1. - 2. * kctx->v4_p1; 52950f0abf79SStefano Zampini else if (rk < kctx->v4_p2) rtol = kctx->rtol_last; 52960f0abf79SStefano Zampini else if (rk < kctx->v4_p3) rtol = kctx->v4_m1 * kctx->rtol_last; 52970f0abf79SStefano Zampini else rtol = kctx->v4_m2 * kctx->rtol_last; 52980f0abf79SStefano Zampini 5299a4598233SStefano Zampini if (kctx->rtol_last_2 > kctx->v4_m3 && kctx->rtol_last > kctx->v4_m3 && kctx->rk_last_2 < kctx->v4_p1 && kctx->rk_last < kctx->v4_p1) rtol = kctx->v4_m4 * kctx->rtol_last; 53000f0abf79SStefano Zampini kctx->rtol_last_2 = kctx->rtol_last; 53010f0abf79SStefano Zampini kctx->rk_last_2 = kctx->rk_last; 53020f0abf79SStefano Zampini kctx->rk_last = rk; 53030fdf79fbSJacob Faibussowitsch } 53040f0abf79SStefano Zampini } 53050f0abf79SStefano Zampini /* safeguard: avoid rtol greater than rtol_max */ 530671f87433Sdalcinl rtol = PetscMin(rtol, kctx->rtol_max); 53079566063dSJacob Faibussowitsch PetscCall(KSPSetTolerances(ksp, rtol, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT)); 530863a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g\n", snes->iter, kctx->version, (double)rtol)); 53093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 531071f87433Sdalcinl } 531171f87433Sdalcinl 5312d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 5313d71ae5a4SJacob Faibussowitsch { 5314fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx; 531571f87433Sdalcinl PCSide pcside; 531671f87433Sdalcinl Vec lres; 531771f87433Sdalcinl 531871f87433Sdalcinl PetscFunctionBegin; 53193ba16761SJacob Faibussowitsch if (!snes->ksp_ewconv) PetscFunctionReturn(PETSC_SUCCESS); 53209566063dSJacob Faibussowitsch PetscCall(KSPGetTolerances(ksp, &kctx->rtol_last, NULL, NULL, NULL)); 532171dbe336SPeter Brune kctx->norm_last = snes->norm; 53220f0abf79SStefano Zampini if (kctx->version == 1 || kctx->version == 4) { 53234f00ce20SMatthew G. Knepley PC pc; 53240f0abf79SStefano Zampini PetscBool getRes; 53254f00ce20SMatthew G. Knepley 53269566063dSJacob Faibussowitsch PetscCall(KSPGetPC(ksp, &pc)); 53270f0abf79SStefano Zampini PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &getRes)); 53280f0abf79SStefano Zampini if (!getRes) { 53290f0abf79SStefano Zampini KSPNormType normtype; 53300f0abf79SStefano Zampini 53310f0abf79SStefano Zampini PetscCall(KSPGetNormType(ksp, &normtype)); 53320f0abf79SStefano Zampini getRes = (PetscBool)(normtype == KSP_NORM_UNPRECONDITIONED); 53330f0abf79SStefano Zampini } 53349566063dSJacob Faibussowitsch PetscCall(KSPGetPCSide(ksp, &pcside)); 53350f0abf79SStefano Zampini if (pcside == PC_RIGHT || getRes) { /* KSP residual is true linear residual */ 53369566063dSJacob Faibussowitsch PetscCall(KSPGetResidualNorm(ksp, &kctx->lresid_last)); 533771f87433Sdalcinl } else { 533871f87433Sdalcinl /* KSP residual is preconditioned residual */ 533971f87433Sdalcinl /* compute true linear residual norm */ 53400f0abf79SStefano Zampini Mat J; 53410f0abf79SStefano Zampini PetscCall(KSPGetOperators(ksp, &J, NULL)); 53429566063dSJacob Faibussowitsch PetscCall(VecDuplicate(b, &lres)); 53430f0abf79SStefano Zampini PetscCall(MatMult(J, x, lres)); 53449566063dSJacob Faibussowitsch PetscCall(VecAYPX(lres, -1.0, b)); 53459566063dSJacob Faibussowitsch PetscCall(VecNorm(lres, NORM_2, &kctx->lresid_last)); 53469566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lres)); 534771f87433Sdalcinl } 534871f87433Sdalcinl } 53493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 535071f87433Sdalcinl } 535171f87433Sdalcinl 5352d4211eb9SBarry Smith /*@ 5353f6dfbefdSBarry Smith SNESGetKSP - Returns the `KSP` context for a `SNES` solver. 5354d4211eb9SBarry Smith 5355f6dfbefdSBarry Smith Not Collective, but if snes is parallel, then ksp is parallel 5356d4211eb9SBarry Smith 5357d4211eb9SBarry Smith Input Parameter: 5358f6dfbefdSBarry Smith . snes - the `SNES` context 5359d4211eb9SBarry Smith 5360d4211eb9SBarry Smith Output Parameter: 5361f6dfbefdSBarry Smith . ksp - the `KSP` context 5362d4211eb9SBarry Smith 5363dc4c0fb0SBarry Smith Level: beginner 5364dc4c0fb0SBarry Smith 5365d4211eb9SBarry Smith Notes: 5366f6dfbefdSBarry Smith The user can then directly manipulate the `KSP` context to set various 5367d4211eb9SBarry Smith options, etc. Likewise, the user can then extract and manipulate the 5368f6dfbefdSBarry Smith `PC` contexts as well. 5369f6dfbefdSBarry Smith 5370f6dfbefdSBarry Smith Some `SNESType`s do not use a `KSP` but a `KSP` is still returned by this function 5371d4211eb9SBarry Smith 53721cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `KSP`, `PC`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()` 5373d4211eb9SBarry Smith @*/ 5374d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetKSP(SNES snes, KSP *ksp) 5375d71ae5a4SJacob Faibussowitsch { 537671f87433Sdalcinl PetscFunctionBegin; 5377d4211eb9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 53784f572ea9SToby Isaac PetscAssertPointer(ksp, 2); 5379d4211eb9SBarry Smith 5380d4211eb9SBarry Smith if (!snes->ksp) { 53819566063dSJacob Faibussowitsch PetscCall(KSPCreate(PetscObjectComm((PetscObject)snes), &snes->ksp)); 53829566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->ksp, (PetscObject)snes, 1)); 5383d4211eb9SBarry Smith 53849566063dSJacob Faibussowitsch PetscCall(KSPSetPreSolve(snes->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPreSolve_SNESEW, snes)); 53859566063dSJacob Faibussowitsch PetscCall(KSPSetPostSolve(snes->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPostSolve_SNESEW, snes)); 5386a5c2985bSBarry Smith 53879566063dSJacob Faibussowitsch PetscCall(KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes)); 53889566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptions((PetscObject)snes->ksp, ((PetscObject)snes)->options)); 5389d4211eb9SBarry Smith } 5390d4211eb9SBarry Smith *ksp = snes->ksp; 53913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 539271f87433Sdalcinl } 53936c699258SBarry Smith 5394af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 53956c699258SBarry Smith /*@ 5396f6dfbefdSBarry Smith SNESSetDM - Sets the `DM` that may be used by some nonlinear solvers or their underlying preconditioners 53976c699258SBarry Smith 5398c3339decSBarry Smith Logically Collective 53996c699258SBarry Smith 54006c699258SBarry Smith Input Parameters: 54012a808120SBarry Smith + snes - the nonlinear solver context 5402dc4c0fb0SBarry Smith - dm - the dm, cannot be `NULL` 5403dc4c0fb0SBarry Smith 5404dc4c0fb0SBarry Smith Level: intermediate 54056c699258SBarry Smith 5406f6dfbefdSBarry Smith Note: 5407f6dfbefdSBarry Smith A `DM` can only be used for solving one problem at a time because information about the problem is stored on the `DM`, 5408f6dfbefdSBarry Smith even when not using interfaces like `DMSNESSetFunction()`. Use `DMClone()` to get a distinct `DM` when solving different 5409e03a659cSJed Brown problems using the same function space. 5410e03a659cSJed Brown 54111cc06b55SBarry Smith .seealso: [](ch_snes), `DM`, `SNESGetDM()`, `KSPSetDM()`, `KSPGetDM()` 54126c699258SBarry Smith @*/ 5413d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetDM(SNES snes, DM dm) 5414d71ae5a4SJacob Faibussowitsch { 5415345fed2cSBarry Smith KSP ksp; 5416942e3340SBarry Smith DMSNES sdm; 54176c699258SBarry Smith 54186c699258SBarry Smith PetscFunctionBegin; 54190700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 54202a808120SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 54219566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)dm)); 5422942e3340SBarry Smith if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 542351f4b3c7SToby Isaac if (snes->dm->dmsnes && !dm->dmsnes) { 54249566063dSJacob Faibussowitsch PetscCall(DMCopyDMSNES(snes->dm, dm)); 54259566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &sdm)); 5426f5af7f23SKarl Rupp if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 54276cab3a1bSJed Brown } 54289566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookRemove(snes->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, snes)); 54299566063dSJacob Faibussowitsch PetscCall(DMDestroy(&snes->dm)); 54306cab3a1bSJed Brown } 54316c699258SBarry Smith snes->dm = dm; 5432116d1032SJed Brown snes->dmAuto = PETSC_FALSE; 5433f5af7f23SKarl Rupp 54349566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 54359566063dSJacob Faibussowitsch PetscCall(KSPSetDM(ksp, dm)); 54369566063dSJacob Faibussowitsch PetscCall(KSPSetDMActive(ksp, PETSC_FALSE)); 5437efd4aadfSBarry Smith if (snes->npc) { 54389566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes->npc, snes->dm)); 54399566063dSJacob Faibussowitsch PetscCall(SNESSetNPCSide(snes, snes->npcside)); 54402c155ee1SBarry Smith } 54413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 54426c699258SBarry Smith } 54436c699258SBarry Smith 54446c699258SBarry Smith /*@ 5445f6dfbefdSBarry Smith SNESGetDM - Gets the `DM` that may be used by some preconditioners 54466c699258SBarry Smith 5447f6dfbefdSBarry Smith Not Collective but dm obtained is parallel on snes 54486c699258SBarry Smith 54496c699258SBarry Smith Input Parameter: 54506c699258SBarry Smith . snes - the preconditioner context 54516c699258SBarry Smith 54526c699258SBarry Smith Output Parameter: 54536c699258SBarry Smith . dm - the dm 54546c699258SBarry Smith 54556c699258SBarry Smith Level: intermediate 54566c699258SBarry Smith 54571cc06b55SBarry Smith .seealso: [](ch_snes), `DM`, `SNESSetDM()`, `KSPSetDM()`, `KSPGetDM()` 54586c699258SBarry Smith @*/ 5459d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetDM(SNES snes, DM *dm) 5460d71ae5a4SJacob Faibussowitsch { 54616c699258SBarry Smith PetscFunctionBegin; 54620700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 54636cab3a1bSJed Brown if (!snes->dm) { 54649566063dSJacob Faibussowitsch PetscCall(DMShellCreate(PetscObjectComm((PetscObject)snes), &snes->dm)); 5465116d1032SJed Brown snes->dmAuto = PETSC_TRUE; 54666cab3a1bSJed Brown } 54676c699258SBarry Smith *dm = snes->dm; 54683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 54696c699258SBarry Smith } 54700807856dSBarry Smith 547131823bd8SMatthew G Knepley /*@ 5472be95d8f1SBarry Smith SNESSetNPC - Sets the nonlinear preconditioner to be used. 547331823bd8SMatthew G Knepley 5474c3339decSBarry Smith Collective 547531823bd8SMatthew G Knepley 547631823bd8SMatthew G Knepley Input Parameters: 5477f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 5478f6dfbefdSBarry Smith - npc - the preconditioner object 547931823bd8SMatthew G Knepley 5480dc4c0fb0SBarry Smith Level: developer 5481dc4c0fb0SBarry Smith 548231823bd8SMatthew G Knepley Notes: 5483f6dfbefdSBarry Smith Use `SNESGetNPC()` to retrieve the preconditioner context (for example, 548431823bd8SMatthew G Knepley to configure it using the API). 548531823bd8SMatthew G Knepley 5486f6dfbefdSBarry Smith Only some `SNESType` can use a nonlinear preconditioner 5487f6dfbefdSBarry Smith 54881cc06b55SBarry Smith .seealso: [](ch_snes), `SNESNGS`, `SNESFAS`, `SNESGetNPC()`, `SNESHasNPC()` 548931823bd8SMatthew G Knepley @*/ 5490d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNPC(SNES snes, SNES npc) 5491d71ae5a4SJacob Faibussowitsch { 549231823bd8SMatthew G Knepley PetscFunctionBegin; 549331823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5494f6dfbefdSBarry Smith PetscValidHeaderSpecific(npc, SNES_CLASSID, 2); 5495f6dfbefdSBarry Smith PetscCheckSameComm(snes, 1, npc, 2); 5496f6dfbefdSBarry Smith PetscCall(PetscObjectReference((PetscObject)npc)); 54979566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&snes->npc)); 5498f6dfbefdSBarry Smith snes->npc = npc; 54993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 550031823bd8SMatthew G Knepley } 550131823bd8SMatthew G Knepley 550231823bd8SMatthew G Knepley /*@ 5503f6dfbefdSBarry Smith SNESGetNPC - Gets a nonlinear preconditioning solver SNES` to be used to precondition the original nonlinear solver. 550431823bd8SMatthew G Knepley 5505f6dfbefdSBarry Smith Not Collective; but any changes to the obtained the npc object must be applied collectively 550631823bd8SMatthew G Knepley 550731823bd8SMatthew G Knepley Input Parameter: 5508f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 550931823bd8SMatthew G Knepley 551031823bd8SMatthew G Knepley Output Parameter: 5511e4094ef1SJacob Faibussowitsch . pc - preconditioner context 551231823bd8SMatthew G Knepley 5513f6dfbefdSBarry Smith Options Database Key: 5514f6dfbefdSBarry Smith . -npc_snes_type <type> - set the type of the `SNES` to use as the nonlinear preconditioner 5515b5badacbSBarry Smith 5516dc4c0fb0SBarry Smith Level: developer 5517dc4c0fb0SBarry Smith 551895452b02SPatrick Sanan Notes: 5519f6dfbefdSBarry Smith If a `SNES` was previously set with `SNESSetNPC()` then that value is returned, otherwise a new `SNES` object is created. 5520be95d8f1SBarry Smith 5521f6dfbefdSBarry Smith The (preconditioner) `SNES` returned automatically inherits the same nonlinear function and Jacobian supplied to the original 5522f6dfbefdSBarry Smith `SNES` 5523951fe5abSBarry Smith 55241cc06b55SBarry Smith .seealso: [](ch_snes), `SNESSetNPC()`, `SNESHasNPC()`, `SNES`, `SNESCreate()` 552531823bd8SMatthew G Knepley @*/ 5526d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) 5527d71ae5a4SJacob Faibussowitsch { 5528a64e098fSPeter Brune const char *optionsprefix; 552931823bd8SMatthew G Knepley 553031823bd8SMatthew G Knepley PetscFunctionBegin; 553131823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 55324f572ea9SToby Isaac PetscAssertPointer(pc, 2); 5533efd4aadfSBarry Smith if (!snes->npc) { 5534ec785e5bSStefano Zampini void *ctx; 5535ec785e5bSStefano Zampini 55369566063dSJacob Faibussowitsch PetscCall(SNESCreate(PetscObjectComm((PetscObject)snes), &snes->npc)); 55379566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->npc, (PetscObject)snes, 1)); 55389566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 55399566063dSJacob Faibussowitsch PetscCall(SNESSetOptionsPrefix(snes->npc, optionsprefix)); 55409566063dSJacob Faibussowitsch PetscCall(SNESAppendOptionsPrefix(snes->npc, "npc_")); 5541ec785e5bSStefano Zampini PetscCall(SNESGetApplicationContext(snes, &ctx)); 5542ec785e5bSStefano Zampini PetscCall(SNESSetApplicationContext(snes->npc, ctx)); 55439566063dSJacob Faibussowitsch PetscCall(SNESSetCountersReset(snes->npc, PETSC_FALSE)); 554431823bd8SMatthew G Knepley } 5545efd4aadfSBarry Smith *pc = snes->npc; 55463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 554731823bd8SMatthew G Knepley } 554831823bd8SMatthew G Knepley 55493ad1a0b9SPatrick Farrell /*@ 55503ad1a0b9SPatrick Farrell SNESHasNPC - Returns whether a nonlinear preconditioner exists 55513ad1a0b9SPatrick Farrell 55523ad1a0b9SPatrick Farrell Not Collective 55533ad1a0b9SPatrick Farrell 55543ad1a0b9SPatrick Farrell Input Parameter: 5555f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 55563ad1a0b9SPatrick Farrell 55573ad1a0b9SPatrick Farrell Output Parameter: 5558f6dfbefdSBarry Smith . has_npc - whether the `SNES` has an NPC or not 55593ad1a0b9SPatrick Farrell 55603ad1a0b9SPatrick Farrell Level: developer 55613ad1a0b9SPatrick Farrell 55621cc06b55SBarry Smith .seealso: [](ch_snes), `SNESSetNPC()`, `SNESGetNPC()` 55633ad1a0b9SPatrick Farrell @*/ 5564d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 5565d71ae5a4SJacob Faibussowitsch { 55663ad1a0b9SPatrick Farrell PetscFunctionBegin; 55673ad1a0b9SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5568efd4aadfSBarry Smith *has_npc = (PetscBool)(snes->npc ? PETSC_TRUE : PETSC_FALSE); 55693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 55703ad1a0b9SPatrick Farrell } 55713ad1a0b9SPatrick Farrell 5572c40d0f55SPeter Brune /*@ 5573be95d8f1SBarry Smith SNESSetNPCSide - Sets the preconditioning side. 5574c40d0f55SPeter Brune 5575c3339decSBarry Smith Logically Collective 5576c40d0f55SPeter Brune 5577c40d0f55SPeter Brune Input Parameter: 5578f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 5579c40d0f55SPeter Brune 5580c40d0f55SPeter Brune Output Parameter: 5581c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5582c40d0f55SPeter Brune .vb 55832d547940SBarry Smith PC_LEFT - left preconditioning 55842d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5585c40d0f55SPeter Brune .ve 5586c40d0f55SPeter Brune 5587f6dfbefdSBarry Smith Options Database Key: 558867b8a455SSatish Balay . -snes_npc_side <right,left> - nonlinear preconditioner side 5589c40d0f55SPeter Brune 5590dc4c0fb0SBarry Smith Level: intermediate 5591dc4c0fb0SBarry Smith 5592f6dfbefdSBarry Smith Note: 5593f6dfbefdSBarry Smith `SNESNRICHARDSON` and `SNESNCG` only support left preconditioning. 55942d547940SBarry Smith 55951cc06b55SBarry Smith .seealso: [](ch_snes), `SNESType`, `SNESGetNPCSide()`, `KSPSetPCSide()` 5596c40d0f55SPeter Brune @*/ 5597d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNPCSide(SNES snes, PCSide side) 5598d71ae5a4SJacob Faibussowitsch { 5599c40d0f55SPeter Brune PetscFunctionBegin; 5600c40d0f55SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5601c40d0f55SPeter Brune PetscValidLogicalCollectiveEnum(snes, side, 2); 5602b552625fSStefano Zampini if (side == PC_SIDE_DEFAULT) side = PC_RIGHT; 560354c59aa7SJacob Faibussowitsch PetscCheck((side == PC_LEFT) || (side == PC_RIGHT), PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONG, "Only PC_LEFT and PC_RIGHT are supported"); 5604efd4aadfSBarry Smith snes->npcside = side; 56053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5606c40d0f55SPeter Brune } 5607c40d0f55SPeter Brune 5608c40d0f55SPeter Brune /*@ 5609be95d8f1SBarry Smith SNESGetNPCSide - Gets the preconditioning side. 5610c40d0f55SPeter Brune 5611c40d0f55SPeter Brune Not Collective 5612c40d0f55SPeter Brune 5613c40d0f55SPeter Brune Input Parameter: 5614f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 5615c40d0f55SPeter Brune 5616c40d0f55SPeter Brune Output Parameter: 5617c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5618c40d0f55SPeter Brune .vb 5619f6dfbefdSBarry Smith `PC_LEFT` - left preconditioning 5620f6dfbefdSBarry Smith `PC_RIGHT` - right preconditioning (default for most nonlinear solvers) 5621c40d0f55SPeter Brune .ve 5622c40d0f55SPeter Brune 5623c40d0f55SPeter Brune Level: intermediate 5624c40d0f55SPeter Brune 56251cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSetNPCSide()`, `KSPGetPCSide()` 5626c40d0f55SPeter Brune @*/ 5627d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNPCSide(SNES snes, PCSide *side) 5628d71ae5a4SJacob Faibussowitsch { 5629c40d0f55SPeter Brune PetscFunctionBegin; 5630c40d0f55SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 56314f572ea9SToby Isaac PetscAssertPointer(side, 2); 5632efd4aadfSBarry Smith *side = snes->npcside; 56333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5634c40d0f55SPeter Brune } 5635c40d0f55SPeter Brune 56369e764e56SPeter Brune /*@ 5637f6dfbefdSBarry Smith SNESSetLineSearch - Sets the linesearch on the `SNES` instance. 56389e764e56SPeter Brune 5639c3339decSBarry Smith Collective 56409e764e56SPeter Brune 56419e764e56SPeter Brune Input Parameters: 5642f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 56439e764e56SPeter Brune - linesearch - the linesearch object 56449e764e56SPeter Brune 5645dc4c0fb0SBarry Smith Level: developer 5646dc4c0fb0SBarry Smith 5647f6dfbefdSBarry Smith Note: 5648f6dfbefdSBarry Smith Use `SNESGetLineSearch()` to retrieve the preconditioner context (for example, 56499e764e56SPeter Brune to configure it using the API). 56509e764e56SPeter Brune 56511cc06b55SBarry Smith .seealso: [](ch_snes), `SNESGetLineSearch()` 56529e764e56SPeter Brune @*/ 5653d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 5654d71ae5a4SJacob Faibussowitsch { 56559e764e56SPeter Brune PetscFunctionBegin; 56569e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5657f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 56589e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 56599566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)linesearch)); 56609566063dSJacob Faibussowitsch PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 5661f5af7f23SKarl Rupp 56629e764e56SPeter Brune snes->linesearch = linesearch; 5663f5af7f23SKarl Rupp 56643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 56659e764e56SPeter Brune } 56669e764e56SPeter Brune 5667a34ceb2aSJed Brown /*@ 5668dc4c0fb0SBarry Smith SNESGetLineSearch - Returns the line search context set with `SNESSetLineSearch()` 5669f6dfbefdSBarry Smith or creates a default line search instance associated with the `SNES` and returns it. 56709e764e56SPeter Brune 56719e764e56SPeter Brune Not Collective 56729e764e56SPeter Brune 56739e764e56SPeter Brune Input Parameter: 5674f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 56759e764e56SPeter Brune 56769e764e56SPeter Brune Output Parameter: 56779e764e56SPeter Brune . linesearch - linesearch context 56789e764e56SPeter Brune 5679162e0bf5SPeter Brune Level: beginner 56809e764e56SPeter Brune 56811cc06b55SBarry Smith .seealso: [](ch_snes), `SNESLineSearch`, `SNESSetLineSearch()`, `SNESLineSearchCreate()` 56829e764e56SPeter Brune @*/ 5683d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 5684d71ae5a4SJacob Faibussowitsch { 56859e764e56SPeter Brune const char *optionsprefix; 56869e764e56SPeter Brune 56879e764e56SPeter Brune PetscFunctionBegin; 56889e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 56894f572ea9SToby Isaac PetscAssertPointer(linesearch, 2); 56909e764e56SPeter Brune if (!snes->linesearch) { 56919566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 56929566063dSJacob Faibussowitsch PetscCall(SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch)); 56939566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetSNES(snes->linesearch, snes)); 56949566063dSJacob Faibussowitsch PetscCall(SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix)); 56959566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->linesearch, (PetscObject)snes, 1)); 56969e764e56SPeter Brune } 56979e764e56SPeter Brune *linesearch = snes->linesearch; 56983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 56999e764e56SPeter Brune } 5700