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; 13e3ed9ee7SBarry Smith PetscLogEvent SNES_Solve, SNES_Setup, SNES_FunctionEval, SNES_JacobianEval, SNES_NGSEval, SNES_NGSFuncEval, SNES_NPCSolve, SNES_ObjectiveEval; 14a09944afSBarry Smith 15e113a28aSBarry Smith /*@ 16f6dfbefdSBarry Smith SNESSetErrorIfNotConverged - Causes `SNESSolve()` to generate an error if the solver has not converged. 17e113a28aSBarry Smith 18*c3339decSBarry 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 24e113a28aSBarry Smith Options database keys: 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 33f6dfbefdSBarry Smith .seealso: `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; 41e113a28aSBarry Smith PetscFunctionReturn(0); 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 57f6dfbefdSBarry Smith .seealso: `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); 63534a8f05SLisandro Dalcin PetscValidBoolPointer(flag, 2); 64e113a28aSBarry Smith *flag = snes->errorifnotconverged; 65e113a28aSBarry Smith PetscFunctionReturn(0); 66e113a28aSBarry Smith } 67e113a28aSBarry Smith 684fc747eaSLawrence Mitchell /*@ 69f6dfbefdSBarry Smith SNESSetAlwaysComputesFinalResidual - tells the `SNES` to always compute the residual at the final solution 704fc747eaSLawrence Mitchell 71*c3339decSBarry 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 83f6dfbefdSBarry Smith .seealso: `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; 904fc747eaSLawrence Mitchell PetscFunctionReturn(0); 914fc747eaSLawrence Mitchell } 924fc747eaSLawrence Mitchell 934fc747eaSLawrence Mitchell /*@ 94f6dfbefdSBarry Smith SNESGetAlwaysComputesFinalResidual - checks if the `SNES` always computes the residual at the final solution 954fc747eaSLawrence Mitchell 96*c3339decSBarry 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 106f6dfbefdSBarry Smith .seealso: `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; 1134fc747eaSLawrence Mitchell PetscFunctionReturn(0); 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 120*c3339decSBarry Smith Logically Collective 1214936397dSBarry Smith 1224936397dSBarry Smith Input Parameters: 123f6dfbefdSBarry Smith . snes - the `SNES` context 1244936397dSBarry Smith 12528529972SSatish Balay Level: advanced 1264936397dSBarry Smith 127f0b84518SBarry Smith Note: 128f0b84518SBarry Smith You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or 129f0b84518SBarry Smith `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 130f0b84518SBarry Smith 131f0b84518SBarry Smith .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction`, `SNESSetJacobianDomainError()`, `SNESVISetVariableBounds()`, 132f0b84518SBarry Smith `SNESVISetComputeVariableBounds()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 1334936397dSBarry Smith @*/ 134d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunctionDomainError(SNES snes) 135d71ae5a4SJacob Faibussowitsch { 1364936397dSBarry Smith PetscFunctionBegin; 1370700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1385f80ce2aSJacob Faibussowitsch PetscCheck(!snes->errorifnotconverged, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "User code indicates input vector is not in the function domain"); 1394936397dSBarry Smith snes->domainerror = PETSC_TRUE; 1404936397dSBarry Smith PetscFunctionReturn(0); 1414936397dSBarry Smith } 1424936397dSBarry Smith 1436a388c36SPeter Brune /*@ 144f6dfbefdSBarry Smith SNESSetJacobianDomainError - tells `SNES` that the function you provided to `SNESSetJacobian()` at the proposed step. For example there is a negative element transformation. 14507b62357SFande Kong 146*c3339decSBarry Smith Logically Collective 14707b62357SFande Kong 14807b62357SFande Kong Input Parameters: 149f6dfbefdSBarry Smith . snes - the `SNES` context 15007b62357SFande Kong 15107b62357SFande Kong Level: advanced 15207b62357SFande Kong 153f0b84518SBarry Smith Note: 154f0b84518SBarry Smith You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or 155f0b84518SBarry Smith `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 156f0b84518SBarry Smith 157f0b84518SBarry Smith .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESVISetVariableBounds()`, 158f0b84518SBarry Smith `SNESVISetComputeVariableBounds()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 15907b62357SFande Kong @*/ 160d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetJacobianDomainError(SNES snes) 161d71ae5a4SJacob Faibussowitsch { 16207b62357SFande Kong PetscFunctionBegin; 16307b62357SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1645f80ce2aSJacob Faibussowitsch PetscCheck(!snes->errorifnotconverged, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "User code indicates computeJacobian does not make sense"); 16507b62357SFande Kong snes->jacobiandomainerror = PETSC_TRUE; 16607b62357SFande Kong PetscFunctionReturn(0); 16707b62357SFande Kong } 16807b62357SFande Kong 16907b62357SFande Kong /*@ 170f6dfbefdSBarry Smith SNESSetCheckJacobianDomainError - tells `SNESSolve()` whether to check if the user called `SNESSetJacobianDomainError()` Jacobian domain error after 171f6dfbefdSBarry Smith each Jacobian evaluation. By default, we check Jacobian domain error in the debug mode, and do not check it in the optimized mode. 172b351a90bSFande Kong 173*c3339decSBarry Smith Logically Collective 174b351a90bSFande Kong 175b351a90bSFande Kong Input Parameters: 176a2b725a8SWilliam Gropp + snes - the SNES context 177f6dfbefdSBarry Smith - flg - indicates if or not to check Jacobian domain error after each Jacobian evaluation 178b351a90bSFande Kong 179b351a90bSFande Kong Level: advanced 180b351a90bSFande Kong 181f6dfbefdSBarry Smith Note: 182f6dfbefdSBarry Smith Checks require one extra parallel synchronization for each Jacobian evaluation 183f6dfbefdSBarry Smith 184db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESGetCheckJacobianDomainError()` 185b351a90bSFande Kong @*/ 186d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetCheckJacobianDomainError(SNES snes, PetscBool flg) 187d71ae5a4SJacob Faibussowitsch { 188b351a90bSFande Kong PetscFunctionBegin; 189b351a90bSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 190b351a90bSFande Kong snes->checkjacdomainerror = flg; 191b351a90bSFande Kong PetscFunctionReturn(0); 192b351a90bSFande Kong } 193b351a90bSFande Kong 194b351a90bSFande Kong /*@ 1958383d7d7SFande Kong SNESGetCheckJacobianDomainError - Get an indicator whether or not we are checking Jacobian domain errors after each Jacobian evaluation. 1968383d7d7SFande Kong 197*c3339decSBarry Smith Logically Collective 1988383d7d7SFande Kong 1998383d7d7SFande Kong Input Parameters: 200f6dfbefdSBarry Smith . snes - the `SNES` context 2018383d7d7SFande Kong 2028383d7d7SFande Kong Output Parameters: 203f6dfbefdSBarry Smith . flg - `PETSC_FALSE` indicates that we don't check Jacobian domain errors after each Jacobian evaluation 2048383d7d7SFande Kong 2058383d7d7SFande Kong Level: advanced 2068383d7d7SFande Kong 207db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESSetCheckJacobianDomainError()` 2088383d7d7SFande Kong @*/ 209d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetCheckJacobianDomainError(SNES snes, PetscBool *flg) 210d71ae5a4SJacob Faibussowitsch { 2118383d7d7SFande Kong PetscFunctionBegin; 2128383d7d7SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 213534a8f05SLisandro Dalcin PetscValidBoolPointer(flg, 2); 2148383d7d7SFande Kong *flg = snes->checkjacdomainerror; 2158383d7d7SFande Kong PetscFunctionReturn(0); 2168383d7d7SFande Kong } 2178383d7d7SFande Kong 2188383d7d7SFande Kong /*@ 219f6dfbefdSBarry Smith SNESGetFunctionDomainError - Gets the status of the domain error after a call to `SNESComputeFunction()`; 2206a388c36SPeter Brune 221f6dfbefdSBarry Smith Logically Collective 2226a388c36SPeter Brune 2236a388c36SPeter Brune Input Parameters: 224f6dfbefdSBarry Smith . snes - the `SNES` context 2256a388c36SPeter Brune 2266a388c36SPeter Brune Output Parameters: 227f6dfbefdSBarry Smith . domainerror - Set to `PETSC_TRUE` if there's a domain error; `PETSC_FALSE` otherwise. 2286a388c36SPeter Brune 229f6dfbefdSBarry Smith Level: developer 2306a388c36SPeter Brune 231db781477SPatrick Sanan .seealso: `SNESSetFunctionDomainError()`, `SNESComputeFunction()` 2326a388c36SPeter Brune @*/ 233d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 234d71ae5a4SJacob Faibussowitsch { 2356a388c36SPeter Brune PetscFunctionBegin; 2366a388c36SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 237534a8f05SLisandro Dalcin PetscValidBoolPointer(domainerror, 2); 2386a388c36SPeter Brune *domainerror = snes->domainerror; 2396a388c36SPeter Brune PetscFunctionReturn(0); 2406a388c36SPeter Brune } 2416a388c36SPeter Brune 24207b62357SFande Kong /*@ 243f6dfbefdSBarry Smith SNESGetJacobianDomainError - Gets the status of the Jacobian domain error after a call to `SNESComputeJacobian()`; 24407b62357SFande Kong 245*c3339decSBarry Smith Logically Collective 24607b62357SFande Kong 24707b62357SFande Kong Input Parameters: 248f6dfbefdSBarry Smith . snes - the `SNES` context 24907b62357SFande Kong 25007b62357SFande Kong Output Parameters: 251f6dfbefdSBarry Smith . domainerror - Set to `PETSC_TRUE` if there's a Jacobian domain error; `PETSC_FALSE` otherwise. 25207b62357SFande Kong 25307b62357SFande Kong Level: advanced 25407b62357SFande Kong 255c2e3fba1SPatrick Sanan .seealso: `SNESSetFunctionDomainError()`, `SNESComputeFunction()`, `SNESGetFunctionDomainError()` 25607b62357SFande Kong @*/ 257d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetJacobianDomainError(SNES snes, PetscBool *domainerror) 258d71ae5a4SJacob Faibussowitsch { 25907b62357SFande Kong PetscFunctionBegin; 26007b62357SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 261534a8f05SLisandro Dalcin PetscValidBoolPointer(domainerror, 2); 26207b62357SFande Kong *domainerror = snes->jacobiandomainerror; 26307b62357SFande Kong PetscFunctionReturn(0); 26407b62357SFande Kong } 26507b62357SFande Kong 26655849f57SBarry Smith /*@C 267f6dfbefdSBarry Smith SNESLoad - Loads a `SNES` that has been stored in `PETSCVIEWERBINARY` with `SNESView()`. 26855849f57SBarry Smith 269*c3339decSBarry Smith Collective 27055849f57SBarry Smith 27155849f57SBarry Smith Input Parameters: 272f6dfbefdSBarry Smith + newdm - the newly loaded `SNES`, this needs to have been created with `SNESCreate()` or 273f6dfbefdSBarry Smith some related function before a call to `SNESLoad()`. 274f6dfbefdSBarry Smith - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` 27555849f57SBarry Smith 27655849f57SBarry Smith Level: intermediate 27755849f57SBarry Smith 278f6dfbefdSBarry Smith Note: 279f6dfbefdSBarry Smith The type is determined by the data in the file, any type set into the `SNES` before this call is ignored. 28055849f57SBarry Smith 281f6dfbefdSBarry Smith .seealso: `SNESCreate()`, `SNESType`, `PetscViewerBinaryOpen()`, `SNESView()`, `MatLoad()`, `VecLoad()` 28255849f57SBarry Smith @*/ 283d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLoad(SNES snes, PetscViewer viewer) 284d71ae5a4SJacob Faibussowitsch { 28555849f57SBarry Smith PetscBool isbinary; 286060da220SMatthew G. Knepley PetscInt classid; 28755849f57SBarry Smith char type[256]; 28855849f57SBarry Smith KSP ksp; 2892d53ad75SBarry Smith DM dm; 2902d53ad75SBarry Smith DMSNES dmsnes; 29155849f57SBarry Smith 29255849f57SBarry Smith PetscFunctionBegin; 2932d53ad75SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 29455849f57SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2959566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 2965f80ce2aSJacob Faibussowitsch PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 29755849f57SBarry Smith 2989566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, &classid, 1, NULL, PETSC_INT)); 2995f80ce2aSJacob Faibussowitsch PetscCheck(classid == SNES_FILE_CLASSID, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONG, "Not SNES next in file"); 3009566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, type, 256, NULL, PETSC_CHAR)); 3019566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, type)); 302dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, load, viewer); 3039566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 3049566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &dmsnes)); 3059566063dSJacob Faibussowitsch PetscCall(DMSNESLoad(dmsnes, viewer)); 3069566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 3079566063dSJacob Faibussowitsch PetscCall(KSPLoad(ksp, viewer)); 30855849f57SBarry Smith PetscFunctionReturn(0); 30955849f57SBarry Smith } 3106a388c36SPeter Brune 3119804daf3SBarry Smith #include <petscdraw.h> 312e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 313e04113cfSBarry Smith #include <petscviewersaws.h> 314bfb97211SBarry Smith #endif 3158404b7f3SBarry Smith 316fe2efc57SMark /*@C 317f6dfbefdSBarry Smith SNESViewFromOptions - View a `SNES` based on the options database 318fe2efc57SMark 319*c3339decSBarry Smith Collective 320fe2efc57SMark 321fe2efc57SMark Input Parameters: 322f6dfbefdSBarry Smith + A - the `SNES` context 323736c3998SJose E. Roman . obj - Optional object 324736c3998SJose E. Roman - name - command line option 325fe2efc57SMark 326fe2efc57SMark Level: intermediate 327f6dfbefdSBarry Smith 328db781477SPatrick Sanan .seealso: `SNES`, `SNESView`, `PetscObjectViewFromOptions()`, `SNESCreate()` 329fe2efc57SMark @*/ 330d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESViewFromOptions(SNES A, PetscObject obj, const char name[]) 331d71ae5a4SJacob Faibussowitsch { 332fe2efc57SMark PetscFunctionBegin; 333fe2efc57SMark PetscValidHeaderSpecific(A, SNES_CLASSID, 1); 3349566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 335fe2efc57SMark PetscFunctionReturn(0); 336fe2efc57SMark } 337fe2efc57SMark 338789d8953SBarry Smith PETSC_EXTERN PetscErrorCode SNESComputeJacobian_DMDA(SNES, Vec, Mat, Mat, void *); 339789d8953SBarry Smith 3407e2c5f70SBarry Smith /*@C 341f6dfbefdSBarry Smith SNESView - Prints the `SNES` data structure. 3429b94acceSBarry Smith 343*c3339decSBarry Smith Collective 344fee21e36SBarry Smith 345c7afd0dbSLois Curfman McInnes Input Parameters: 346f6dfbefdSBarry Smith + snes - the `SNES` context 347f6dfbefdSBarry Smith - viewer - the `PetscViewer` 348c7afd0dbSLois Curfman McInnes 3499b94acceSBarry Smith Options Database Key: 350f6dfbefdSBarry Smith . -snes_view - Calls `SNESView()` at end of `SNESSolve()` 3519b94acceSBarry Smith 3529b94acceSBarry Smith Notes: 3539b94acceSBarry Smith The available visualization contexts include 354f6dfbefdSBarry Smith + `PETSC_VIEWER_STDOUT_SELF` - standard output (default) 355f6dfbefdSBarry Smith - `PETSC_VIEWER_STDOUT_WORLD` - synchronized standard 356c8a8ba5cSLois Curfman McInnes output where only the first processor opens 357c8a8ba5cSLois Curfman McInnes the file. All other processors send their 358c8a8ba5cSLois Curfman McInnes data to the first processor to print. 3599b94acceSBarry Smith 360052bf0daSPierre Jolivet The available formats include 361f6dfbefdSBarry Smith + `PETSC_VIEWER_DEFAULT` - standard output (default) 362f6dfbefdSBarry Smith - `PETSC_VIEWER_ASCII_INFO_DETAIL` - more verbose output for `SNESNASM` 363052bf0daSPierre Jolivet 3643e081fefSLois Curfman McInnes The user can open an alternative visualization context with 365f6dfbefdSBarry Smith `PetscViewerASCIIOpen()` - output to a specified file. 3669b94acceSBarry Smith 367f6dfbefdSBarry Smith In the debugger you can do "call `SNESView`(snes,0)" to display the `SNES` solver. (The same holds for any PETSc object viewer). 368595c91d4SBarry Smith 36936851e7fSLois Curfman McInnes Level: beginner 37036851e7fSLois Curfman McInnes 371f6dfbefdSBarry Smith .seealso: `SNES`, `SNESLoad()`, `SNESCreate()`, `PetscViewerASCIIOpen()` 3729b94acceSBarry Smith @*/ 373d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESView(SNES snes, PetscViewer viewer) 374d71ae5a4SJacob Faibussowitsch { 375fa9f3622SBarry Smith SNESKSPEW *kctx; 37694b7f48cSBarry Smith KSP ksp; 3777f1410a3SPeter Brune SNESLineSearch linesearch; 37872a02f06SBarry Smith PetscBool iascii, isstring, isbinary, isdraw; 3792d53ad75SBarry Smith DMSNES dmsnes; 380e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 381536b137fSBarry Smith PetscBool issaws; 382bfb97211SBarry Smith #endif 3839b94acceSBarry Smith 3843a40ed3dSBarry Smith PetscFunctionBegin; 3850700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 38648a46eb9SPierre Jolivet if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &viewer)); 3870700a824SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 388c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, viewer, 2); 38974679c65SBarry Smith 3909566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 3919566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring)); 3929566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 3939566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 394e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 3959566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws)); 396bfb97211SBarry Smith #endif 39732077d6dSBarry Smith if (iascii) { 398dc0571f2SMatthew G. Knepley SNESNormSchedule normschedule; 3998404b7f3SBarry Smith DM dm; 4008404b7f3SBarry Smith PetscErrorCode (*cJ)(SNES, Vec, Mat, Mat, void *); 4018404b7f3SBarry Smith void *ctx; 402789d8953SBarry Smith const char *pre = ""; 403dc0571f2SMatthew G. Knepley 4049566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)snes, viewer)); 40548a46eb9SPierre Jolivet if (!snes->setupcalled) PetscCall(PetscViewerASCIIPrintf(viewer, " SNES has not been set up so information may be incomplete\n")); 406e7788613SBarry Smith if (snes->ops->view) { 4079566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 408dbbe0bcdSBarry Smith PetscUseTypeMethod(snes, view, viewer); 4099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 4100ef38995SBarry Smith } 41163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " maximum iterations=%" PetscInt_FMT ", maximum function evaluations=%" PetscInt_FMT "\n", snes->max_its, snes->max_funcs)); 4129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " tolerances: relative=%g, absolute=%g, solution=%g\n", (double)snes->rtol, (double)snes->abstol, (double)snes->stol)); 41348a46eb9SPierre Jolivet if (snes->usesksp) PetscCall(PetscViewerASCIIPrintf(viewer, " total number of linear solver iterations=%" PetscInt_FMT "\n", snes->linear_its)); 41463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " total number of function evaluations=%" PetscInt_FMT "\n", snes->nfuncs)); 4159566063dSJacob Faibussowitsch PetscCall(SNESGetNormSchedule(snes, &normschedule)); 4169566063dSJacob Faibussowitsch if (normschedule > 0) PetscCall(PetscViewerASCIIPrintf(viewer, " norm schedule %s\n", SNESNormSchedules[normschedule])); 41748a46eb9SPierre Jolivet if (snes->gridsequence) PetscCall(PetscViewerASCIIPrintf(viewer, " total number of grid sequence refinements=%" PetscInt_FMT "\n", snes->gridsequence)); 4189b94acceSBarry Smith if (snes->ksp_ewconv) { 419fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 4209b94acceSBarry Smith if (kctx) { 42163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Eisenstat-Walker computation of KSP relative tolerance (version %" PetscInt_FMT ")\n", kctx->version)); 4229566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " rtol_0=%g, rtol_max=%g, threshold=%g\n", (double)kctx->rtol_0, (double)kctx->rtol_max, (double)kctx->threshold)); 4239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " gamma=%g, alpha=%g, alpha2=%g\n", (double)kctx->gamma, (double)kctx->alpha, (double)kctx->alpha2)); 4249b94acceSBarry Smith } 4259b94acceSBarry Smith } 426eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 4279566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Preconditioned is never rebuilt\n")); 428eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 42963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Preconditioned is rebuilt every %" PetscInt_FMT " new Jacobians\n", snes->lagpreconditioner)); 430eb1f6c34SBarry Smith } 431eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 4329566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is never rebuilt\n")); 433eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 43463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is rebuilt every %" PetscInt_FMT " SNES iterations\n", snes->lagjacobian)); 435eb1f6c34SBarry Smith } 4369566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 4379566063dSJacob Faibussowitsch PetscCall(DMSNESGetJacobian(dm, &cJ, &ctx)); 438789d8953SBarry Smith if (snes->mf_operator) { 4399566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is applied matrix-free with differencing\n")); 440789d8953SBarry Smith pre = "Preconditioning "; 441789d8953SBarry Smith } 4428404b7f3SBarry Smith if (cJ == SNESComputeJacobianDefault) { 4439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using finite differences one column at a time\n", pre)); 4448404b7f3SBarry Smith } else if (cJ == SNESComputeJacobianDefaultColor) { 4459566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using finite differences with coloring\n", pre)); 446789d8953SBarry Smith /* it slightly breaks data encapsulation for access the DMDA information directly */ 447789d8953SBarry Smith } else if (cJ == SNESComputeJacobian_DMDA) { 448789d8953SBarry Smith MatFDColoring fdcoloring; 4499566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)dm, "DMDASNES_FDCOLORING", (PetscObject *)&fdcoloring)); 450789d8953SBarry Smith if (fdcoloring) { 4519566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using colored finite differences on a DMDA\n", pre)); 452789d8953SBarry Smith } else { 4539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using a DMDA local Jacobian\n", pre)); 454789d8953SBarry Smith } 455789d8953SBarry Smith } else if (snes->mf) { 4569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is applied matrix-free with differencing, no explicit Jacobian\n")); 4578404b7f3SBarry Smith } 4580f5bd95cSBarry Smith } else if (isstring) { 459317d6ea6SBarry Smith const char *type; 4609566063dSJacob Faibussowitsch PetscCall(SNESGetType(snes, &type)); 4619566063dSJacob Faibussowitsch PetscCall(PetscViewerStringSPrintf(viewer, " SNESType: %-7.7s", type)); 462dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, view, viewer); 46355849f57SBarry Smith } else if (isbinary) { 46455849f57SBarry Smith PetscInt classid = SNES_FILE_CLASSID; 46555849f57SBarry Smith MPI_Comm comm; 46655849f57SBarry Smith PetscMPIInt rank; 46755849f57SBarry Smith char type[256]; 46855849f57SBarry Smith 4699566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)snes, &comm)); 4709566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 471dd400576SPatrick Sanan if (rank == 0) { 4729566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(viewer, &classid, 1, PETSC_INT)); 4739566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(type, ((PetscObject)snes)->type_name, sizeof(type))); 4749566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(viewer, type, sizeof(type), PETSC_CHAR)); 47555849f57SBarry Smith } 476dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, view, viewer); 47772a02f06SBarry Smith } else if (isdraw) { 47872a02f06SBarry Smith PetscDraw draw; 47972a02f06SBarry Smith char str[36]; 48089fd9fafSBarry Smith PetscReal x, y, bottom, h; 48172a02f06SBarry Smith 4829566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 4839566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCurrentPoint(draw, &x, &y)); 4849566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(str, "SNES: ", sizeof(str))); 4859566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(str, ((PetscObject)snes)->type_name, sizeof(str))); 4869566063dSJacob Faibussowitsch PetscCall(PetscDrawStringBoxed(draw, x, y, PETSC_DRAW_BLUE, PETSC_DRAW_BLACK, str, NULL, &h)); 48789fd9fafSBarry Smith bottom = y - h; 4889566063dSJacob Faibussowitsch PetscCall(PetscDrawPushCurrentPoint(draw, x, bottom)); 489dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, view, viewer); 490e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 491536b137fSBarry Smith } else if (issaws) { 492d45a07a7SBarry Smith PetscMPIInt rank; 4932657e9d9SBarry Smith const char *name; 494d45a07a7SBarry Smith 4959566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)snes, &name)); 4969566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 497dd400576SPatrick Sanan if (!((PetscObject)snes)->amsmem && rank == 0) { 498d45a07a7SBarry Smith char dir[1024]; 499d45a07a7SBarry Smith 5009566063dSJacob Faibussowitsch PetscCall(PetscObjectViewSAWs((PetscObject)snes, viewer)); 5019566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/its", name)); 502792fecdfSBarry Smith PetscCallSAWs(SAWs_Register, (dir, &snes->iter, 1, SAWs_READ, SAWs_INT)); 50348a46eb9SPierre Jolivet if (!snes->conv_hist) PetscCall(SNESSetConvergenceHistory(snes, NULL, NULL, PETSC_DECIDE, PETSC_TRUE)); 5049566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/conv_hist", name)); 505792fecdfSBarry Smith PetscCallSAWs(SAWs_Register, (dir, snes->conv_hist, 10, SAWs_READ, SAWs_DOUBLE)); 506f05ece33SBarry Smith } 507bfb97211SBarry Smith #endif 50872a02f06SBarry Smith } 50972a02f06SBarry Smith if (snes->linesearch) { 5109566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 5119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5129566063dSJacob Faibussowitsch PetscCall(SNESLineSearchView(linesearch, viewer)); 5139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 51419bcc07fSBarry Smith } 515efd4aadfSBarry Smith if (snes->npc && snes->usesnpc) { 5169566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5179566063dSJacob Faibussowitsch PetscCall(SNESView(snes->npc, viewer)); 5189566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5194a0c5b0cSMatthew G Knepley } 5209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5219566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &dmsnes)); 5229566063dSJacob Faibussowitsch PetscCall(DMSNESView(dmsnes, viewer)); 5239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5242c155ee1SBarry Smith if (snes->usesksp) { 5259566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 5269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5279566063dSJacob Faibussowitsch PetscCall(KSPView(ksp, viewer)); 5289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5292c155ee1SBarry Smith } 53072a02f06SBarry Smith if (isdraw) { 53172a02f06SBarry Smith PetscDraw draw; 5329566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 5339566063dSJacob Faibussowitsch PetscCall(PetscDrawPopCurrentPoint(draw)); 5347f1410a3SPeter Brune } 5353a40ed3dSBarry Smith PetscFunctionReturn(0); 5369b94acceSBarry Smith } 5379b94acceSBarry Smith 53876b2cf59SMatthew Knepley /* 53976b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 54076b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 54176b2cf59SMatthew Knepley */ 54276b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 543a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 5446849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 54576b2cf59SMatthew Knepley 546ac226902SBarry Smith /*@C 547f6dfbefdSBarry Smith SNESAddOptionsChecker - Adds an additional function to check for `SNES` options. 54876b2cf59SMatthew Knepley 54976b2cf59SMatthew Knepley Not Collective 55076b2cf59SMatthew Knepley 55176b2cf59SMatthew Knepley Input Parameter: 55276b2cf59SMatthew Knepley . snescheck - function that checks for options 55376b2cf59SMatthew Knepley 55476b2cf59SMatthew Knepley Level: developer 55576b2cf59SMatthew Knepley 556f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFromOptions()` 55776b2cf59SMatthew Knepley @*/ 558d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 559d71ae5a4SJacob Faibussowitsch { 56076b2cf59SMatthew Knepley PetscFunctionBegin; 56163a3b9bcSJacob Faibussowitsch PetscCheck(numberofsetfromoptions < MAXSETFROMOPTIONS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %d allowed", MAXSETFROMOPTIONS); 56276b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 56376b2cf59SMatthew Knepley PetscFunctionReturn(0); 56476b2cf59SMatthew Knepley } 56576b2cf59SMatthew Knepley 566d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 567d71ae5a4SJacob Faibussowitsch { 568aa3661deSLisandro Dalcin Mat J; 569895c21f2SBarry Smith MatNullSpace nullsp; 570aa3661deSLisandro Dalcin 571aa3661deSLisandro Dalcin PetscFunctionBegin; 5720700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 573aa3661deSLisandro Dalcin 57498613b67SLisandro Dalcin if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 57598613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 5769566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A ? A : B, NULL, &snes->vec_func)); 57798613b67SLisandro Dalcin } 57898613b67SLisandro Dalcin 579aa3661deSLisandro Dalcin if (version == 1) { 5809566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes, &J)); 5819566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix)); 5829566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 5831e2ae407SBarry Smith /* TODO: the version 2 code should be merged into the MatCreateSNESMF() and MatCreateMFFD() infrastructure and then removed */ 584aa3661deSLisandro Dalcin } else if (version == 2) { 5855f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_func, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "SNESSetFunction() must be called first"); 586570b7f6dSBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16) 587f6dfbefdSBarry Smith PetscCall(MatCreateSNESMFMore(snes, snes->vec_func, &J)); 588aa3661deSLisandro Dalcin #else 5892479783cSJose E. Roman SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "matrix-free operator routines (version 2)"); 590aa3661deSLisandro Dalcin #endif 5912479783cSJose E. Roman } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator routines, only version 1 and 2"); 592aa3661deSLisandro Dalcin 593895c21f2SBarry Smith /* attach any user provided null space that was on Amat to the newly created matrix free matrix */ 594895c21f2SBarry Smith if (snes->jacobian) { 5959566063dSJacob Faibussowitsch PetscCall(MatGetNullSpace(snes->jacobian, &nullsp)); 5961baa6e33SBarry Smith if (nullsp) PetscCall(MatSetNullSpace(J, nullsp)); 597895c21f2SBarry Smith } 598895c21f2SBarry Smith 59963a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default matrix-free operator routines (version %" PetscInt_FMT ")\n", version)); 600d3462f78SMatthew Knepley if (hasOperator) { 601aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 602aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 6039566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, NULL, NULL, NULL)); 604aa3661deSLisandro Dalcin } else { 605aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 6063232da50SPeter Brune provided preconditioner Jacobian with the default matrix free version. */ 607b552625fSStefano Zampini if (snes->npcside == PC_LEFT && snes->npc) { 6089566063dSJacob Faibussowitsch if (!snes->jacobian) PetscCall(SNESSetJacobian(snes, J, NULL, NULL, NULL)); 609172a4300SPeter Brune } else { 610789d8953SBarry Smith KSP ksp; 611789d8953SBarry Smith PC pc; 612789d8953SBarry Smith PetscBool match; 613789d8953SBarry Smith 6149566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, J, MatMFFDComputeJacobian, NULL)); 615aa3661deSLisandro Dalcin /* Force no preconditioner */ 6169566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 6179566063dSJacob Faibussowitsch PetscCall(KSPGetPC(ksp, &pc)); 6182698c518SLisandro Dalcin PetscCall(PetscObjectTypeCompareAny((PetscObject)pc, &match, PCSHELL, PCH2OPUS, "")); 619aa3661deSLisandro Dalcin if (!match) { 6209566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n")); 6219566063dSJacob Faibussowitsch PetscCall(PCSetType(pc, PCNONE)); 622aa3661deSLisandro Dalcin } 623aa3661deSLisandro Dalcin } 624789d8953SBarry Smith } 6259566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 626aa3661deSLisandro Dalcin PetscFunctionReturn(0); 627aa3661deSLisandro Dalcin } 628aa3661deSLisandro Dalcin 629d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine, Mat Restrict, Vec Rscale, Mat Inject, DM dmcoarse, void *ctx) 630d71ae5a4SJacob Faibussowitsch { 631dfe15315SJed Brown SNES snes = (SNES)ctx; 6320298fd71SBarry Smith Vec Xfine, Xfine_named = NULL, Xcoarse; 633dfe15315SJed Brown 634dfe15315SJed Brown PetscFunctionBegin; 63516ebb321SJed Brown if (PetscLogPrintInfo) { 63616ebb321SJed Brown PetscInt finelevel, coarselevel, fineclevel, coarseclevel; 6379566063dSJacob Faibussowitsch PetscCall(DMGetRefineLevel(dmfine, &finelevel)); 6389566063dSJacob Faibussowitsch PetscCall(DMGetCoarsenLevel(dmfine, &fineclevel)); 6399566063dSJacob Faibussowitsch PetscCall(DMGetRefineLevel(dmcoarse, &coarselevel)); 6409566063dSJacob Faibussowitsch PetscCall(DMGetCoarsenLevel(dmcoarse, &coarseclevel)); 64163a3b9bcSJacob 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)); 64216ebb321SJed Brown } 643dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 644dfe15315SJed Brown else { 6459566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dmfine, "SNESVecSol", &Xfine_named)); 646dfe15315SJed Brown Xfine = Xfine_named; 647dfe15315SJed Brown } 6489566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dmcoarse, "SNESVecSol", &Xcoarse)); 649907f5c5aSLawrence Mitchell if (Inject) { 6509566063dSJacob Faibussowitsch PetscCall(MatRestrict(Inject, Xfine, Xcoarse)); 651907f5c5aSLawrence Mitchell } else { 6529566063dSJacob Faibussowitsch PetscCall(MatRestrict(Restrict, Xfine, Xcoarse)); 6539566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(Xcoarse, Xcoarse, Rscale)); 654907f5c5aSLawrence Mitchell } 6559566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedGlobalVector(dmcoarse, "SNESVecSol", &Xcoarse)); 6569566063dSJacob Faibussowitsch if (Xfine_named) PetscCall(DMRestoreNamedGlobalVector(dmfine, "SNESVecSol", &Xfine_named)); 657dfe15315SJed Brown PetscFunctionReturn(0); 658dfe15315SJed Brown } 659dfe15315SJed Brown 660d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm, DM dmc, void *ctx) 661d71ae5a4SJacob Faibussowitsch { 66216ebb321SJed Brown PetscFunctionBegin; 6639566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(dmc, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, ctx)); 66416ebb321SJed Brown PetscFunctionReturn(0); 66516ebb321SJed Brown } 66616ebb321SJed Brown 667a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 668a6950cb2SJed Brown * safely call SNESGetDM() in their residual evaluation routine. */ 669d71ae5a4SJacob Faibussowitsch static PetscErrorCode KSPComputeOperators_SNES(KSP ksp, Mat A, Mat B, void *ctx) 670d71ae5a4SJacob Faibussowitsch { 671caa4e7f2SJed Brown SNES snes = (SNES)ctx; 6720298fd71SBarry Smith Vec X, Xnamed = NULL; 673dfe15315SJed Brown DM dmsave; 6744e269d77SPeter Brune void *ctxsave; 67525ce1634SJed Brown PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *) = NULL; 676caa4e7f2SJed Brown 677caa4e7f2SJed Brown PetscFunctionBegin; 678dfe15315SJed Brown dmsave = snes->dm; 6799566063dSJacob Faibussowitsch PetscCall(KSPGetDM(ksp, &snes->dm)); 680dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 6819371c9d4SSatish Balay else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ PetscCall(DMGetNamedGlobalVector(snes->dm, "SNESVecSol", &Xnamed)); 682dfe15315SJed Brown X = Xnamed; 6839566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, NULL, NULL, &jac, &ctxsave)); 6844e269d77SPeter Brune /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */ 68548a46eb9SPierre Jolivet if (jac == SNESComputeJacobianDefaultColor) PetscCall(SNESSetJacobian(snes, NULL, NULL, SNESComputeJacobianDefaultColor, NULL)); 6864e269d77SPeter Brune } 6874dde8bb0SMatthew G. Knepley /* Make sure KSP DM has the Jacobian computation routine */ 6884dde8bb0SMatthew G. Knepley { 6894dde8bb0SMatthew G. Knepley DMSNES sdm; 6904e269d77SPeter Brune 6919566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &sdm)); 69248a46eb9SPierre Jolivet if (!sdm->ops->computejacobian) PetscCall(DMCopyDMSNES(dmsave, snes->dm)); 6934dde8bb0SMatthew G. Knepley } 6942b93b426SMatthew G. Knepley /* Compute the operators */ 6959566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobian(snes, X, A, B)); 6962b93b426SMatthew G. Knepley /* Put the previous context back */ 69748a46eb9SPierre Jolivet if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) PetscCall(SNESSetJacobian(snes, NULL, NULL, jac, ctxsave)); 6984e269d77SPeter Brune 6999566063dSJacob Faibussowitsch if (Xnamed) PetscCall(DMRestoreNamedGlobalVector(snes->dm, "SNESVecSol", &Xnamed)); 700dfe15315SJed Brown snes->dm = dmsave; 701caa4e7f2SJed Brown PetscFunctionReturn(0); 702caa4e7f2SJed Brown } 703caa4e7f2SJed Brown 7046cab3a1bSJed Brown /*@ 705f6dfbefdSBarry Smith SNESSetUpMatrices - ensures that matrices are available for `SNES`, this is called by `SNESSetUp_XXX()` 7066cab3a1bSJed Brown 7076cab3a1bSJed Brown Collective 7086cab3a1bSJed Brown 7094165533cSJose E. Roman Input Parameter: 7106cab3a1bSJed Brown . snes - snes to configure 7116cab3a1bSJed Brown 7126cab3a1bSJed Brown Level: developer 7136cab3a1bSJed Brown 714f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetUp()` 7156cab3a1bSJed Brown @*/ 716d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUpMatrices(SNES snes) 717d71ae5a4SJacob Faibussowitsch { 7186cab3a1bSJed Brown DM dm; 719942e3340SBarry Smith DMSNES sdm; 7206cab3a1bSJed Brown 7216cab3a1bSJed Brown PetscFunctionBegin; 7229566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 7239566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 72458b371f3SBarry Smith if (!snes->jacobian && snes->mf) { 7256cab3a1bSJed Brown Mat J; 7266cab3a1bSJed Brown void *functx; 7279566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes, &J)); 7289566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix)); 7299566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 7309566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 7319566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, J, NULL, NULL)); 7329566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 733caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 7346cab3a1bSJed Brown Mat J, B; 7359566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes, &J)); 7369566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix)); 7379566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 7389566063dSJacob Faibussowitsch PetscCall(DMCreateMatrix(snes->dm, &B)); 73906f20277SJed Brown /* sdm->computejacobian was already set to reach here */ 7409566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, B, NULL, NULL)); 7419566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 7429566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 743caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 7441ba9b98eSMatthew G. Knepley PetscDS prob; 7456cab3a1bSJed Brown Mat J, B; 7461ba9b98eSMatthew G. Knepley PetscBool hasPrec = PETSC_FALSE; 7471ba9b98eSMatthew G. Knepley 7486cab3a1bSJed Brown J = snes->jacobian; 7499566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 7509566063dSJacob Faibussowitsch if (prob) PetscCall(PetscDSHasJacobianPreconditioner(prob, &hasPrec)); 7519566063dSJacob Faibussowitsch if (J) PetscCall(PetscObjectReference((PetscObject)J)); 7529566063dSJacob Faibussowitsch else if (hasPrec) PetscCall(DMCreateMatrix(snes->dm, &J)); 7539566063dSJacob Faibussowitsch PetscCall(DMCreateMatrix(snes->dm, &B)); 7549566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J ? J : B, B, NULL, NULL)); 7559566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 7569566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 7576cab3a1bSJed Brown } 758caa4e7f2SJed Brown { 759caa4e7f2SJed Brown KSP ksp; 7609566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 7619566063dSJacob Faibussowitsch PetscCall(KSPSetComputeOperators(ksp, KSPComputeOperators_SNES, snes)); 7629566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(snes->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, snes)); 763caa4e7f2SJed Brown } 7646cab3a1bSJed Brown PetscFunctionReturn(0); 7656cab3a1bSJed Brown } 7666cab3a1bSJed Brown 767d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESMonitorPauseFinal_Internal(SNES snes) 768d71ae5a4SJacob Faibussowitsch { 7695e7c47f3SMatthew G. Knepley PetscInt i; 7705e7c47f3SMatthew G. Knepley 7715e7c47f3SMatthew G. Knepley PetscFunctionBegin; 7725e7c47f3SMatthew G. Knepley if (!snes->pauseFinal) PetscFunctionReturn(0); 7735e7c47f3SMatthew G. Knepley for (i = 0; i < snes->numbermonitors; ++i) { 7745e7c47f3SMatthew G. Knepley PetscViewerAndFormat *vf = (PetscViewerAndFormat *)snes->monitorcontext[i]; 7755e7c47f3SMatthew G. Knepley PetscDraw draw; 7765e7c47f3SMatthew G. Knepley PetscReal lpause; 7775e7c47f3SMatthew G. Knepley 7785e7c47f3SMatthew G. Knepley if (!vf) continue; 7795e7c47f3SMatthew G. Knepley if (vf->lg) { 7805e7c47f3SMatthew G. Knepley if (!PetscCheckPointer(vf->lg, PETSC_OBJECT)) continue; 7815e7c47f3SMatthew G. Knepley if (((PetscObject)vf->lg)->classid != PETSC_DRAWLG_CLASSID) continue; 7829566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(vf->lg, &draw)); 7839566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPause(draw, &lpause)); 7849566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, -1.0)); 7859566063dSJacob Faibussowitsch PetscCall(PetscDrawPause(draw)); 7869566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, lpause)); 7875e7c47f3SMatthew G. Knepley } else { 7885e7c47f3SMatthew G. Knepley PetscBool isdraw; 7895e7c47f3SMatthew G. Knepley 7905e7c47f3SMatthew G. Knepley if (!PetscCheckPointer(vf->viewer, PETSC_OBJECT)) continue; 7915e7c47f3SMatthew G. Knepley if (((PetscObject)vf->viewer)->classid != PETSC_VIEWER_CLASSID) continue; 7929566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer, PETSCVIEWERDRAW, &isdraw)); 7935e7c47f3SMatthew G. Knepley if (!isdraw) continue; 7949566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(vf->viewer, 0, &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 } 8005e7c47f3SMatthew G. Knepley } 8015e7c47f3SMatthew G. Knepley PetscFunctionReturn(0); 8025e7c47f3SMatthew G. Knepley } 8035e7c47f3SMatthew G. Knepley 804fde5950dSBarry Smith /*@C 805fde5950dSBarry Smith SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 806fde5950dSBarry Smith 807*c3339decSBarry Smith Collective 808fde5950dSBarry Smith 809fde5950dSBarry Smith Input Parameters: 810fde5950dSBarry Smith + snes - SNES object you wish to monitor 811fde5950dSBarry Smith . name - the monitor type one is seeking 812fde5950dSBarry Smith . help - message indicating what monitoring is done 813fde5950dSBarry Smith . manual - manual page for the monitor 814fde5950dSBarry Smith . monitor - the monitor function 815f6dfbefdSBarry 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 816fde5950dSBarry Smith 817f6dfbefdSBarry Smith Options Database Key: 818f6dfbefdSBarry Smith . -name - trigger the use of this monitor in `SNESSetFromOptions()` 819f6dfbefdSBarry Smith 820f6dfbefdSBarry Smith Level: advanced 821fde5950dSBarry Smith 822db781477SPatrick Sanan .seealso: `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 823db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 824db781477SPatrick Sanan `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, 825db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 826c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 827db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 828db781477SPatrick Sanan `PetscOptionsFList()`, `PetscOptionsEList()` 829fde5950dSBarry Smith @*/ 830d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSetFromOptions(SNES snes, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(SNES, PetscInt, PetscReal, PetscViewerAndFormat *), PetscErrorCode (*monitorsetup)(SNES, PetscViewerAndFormat *)) 831d71ae5a4SJacob Faibussowitsch { 832fde5950dSBarry Smith PetscViewer viewer; 833fde5950dSBarry Smith PetscViewerFormat format; 834fde5950dSBarry Smith PetscBool flg; 835fde5950dSBarry Smith 836fde5950dSBarry Smith PetscFunctionBegin; 8379566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, name, &viewer, &format, &flg)); 838fde5950dSBarry Smith if (flg) { 839d43b4f6eSBarry Smith PetscViewerAndFormat *vf; 8409566063dSJacob Faibussowitsch PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf)); 8419566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)viewer)); 8421baa6e33SBarry Smith if (monitorsetup) PetscCall((*monitorsetup)(snes, vf)); 8439566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, (PetscErrorCode(*)(SNES, PetscInt, PetscReal, void *))monitor, vf, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy)); 844fde5950dSBarry Smith } 845fde5950dSBarry Smith PetscFunctionReturn(0); 846fde5950dSBarry Smith } 847fde5950dSBarry Smith 848d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESEWSetFromOptions_Private(SNESKSPEW *kctx, MPI_Comm comm, const char *prefix) 849d71ae5a4SJacob Faibussowitsch { 8500f0abf79SStefano Zampini PetscFunctionBegin; 8510f0abf79SStefano Zampini PetscOptionsBegin(comm, prefix, "Eisenstat and Walker type forcing options", "KSP"); 8520f0abf79SStefano Zampini PetscCall(PetscOptionsInt("-ksp_ew_version", "Version 1, 2 or 3", NULL, kctx->version, &kctx->version, NULL)); 8530f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_rtol0", "0 <= rtol0 < 1", NULL, kctx->rtol_0, &kctx->rtol_0, NULL)); 8540f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_rtolmax", "0 <= rtolmax < 1", NULL, kctx->rtol_max, &kctx->rtol_max, NULL)); 8550f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_gamma", "0 <= gamma <= 1", NULL, kctx->gamma, &kctx->gamma, NULL)); 8560f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_alpha", "1 < alpha <= 2", NULL, kctx->alpha, &kctx->alpha, NULL)); 8570f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_alpha2", "alpha2", NULL, kctx->alpha2, &kctx->alpha2, NULL)); 8580f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_threshold", "0 < threshold < 1", NULL, kctx->threshold, &kctx->threshold, NULL)); 8590f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p1", "p1", NULL, kctx->v4_p1, &kctx->v4_p1, NULL)); 8600f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p2", "p2", NULL, kctx->v4_p2, &kctx->v4_p2, NULL)); 8610f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p3", "p3", NULL, kctx->v4_p3, &kctx->v4_p3, NULL)); 8620f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m1", "Scaling when rk-1 in [p2,p3)", NULL, kctx->v4_m1, &kctx->v4_m1, NULL)); 8630f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m2", "Scaling when rk-1 in [p3,+infty)", NULL, kctx->v4_m2, &kctx->v4_m2, NULL)); 8640f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m3", "Threshold for successive rtol (0.1 in Eq.7)", NULL, kctx->v4_m3, &kctx->v4_m3, NULL)); 8650f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m4", "Adaptation scaling (0.5 in Eq.7)", NULL, kctx->v4_m4, &kctx->v4_m4, NULL)); 8660f0abf79SStefano Zampini PetscOptionsEnd(); 8670f0abf79SStefano Zampini PetscFunctionReturn(0); 8680f0abf79SStefano Zampini } 8690f0abf79SStefano Zampini 8709b94acceSBarry Smith /*@ 871f6dfbefdSBarry Smith SNESSetFromOptions - Sets various `SNES` and `KSP` parameters from user options. 8729b94acceSBarry Smith 873*c3339decSBarry Smith Collective 874c7afd0dbSLois Curfman McInnes 8759b94acceSBarry Smith Input Parameter: 876f6dfbefdSBarry Smith . snes - the `SNES` context 8779b94acceSBarry Smith 87836851e7fSLois Curfman McInnes Options Database Keys: 879f6dfbefdSBarry Smith + -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, `SNESType` for complete list 88082738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 88182738288SBarry Smith of the change in the solution between steps 88270441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 883b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 884e4d06f11SPatrick Farrell . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 885be5caee7SBarry Smith . -snes_force_iteration <force> - force SNESSolve() to take at least one iteration 886b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 887b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 8884839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 889ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 890a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 8913d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - retains the -snes_lag_preconditioner information across multiple SNESSolve() 892e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 8933d5a8a6aSBarry Smith . -snes_lag_jacobian_persists <true,false> - retains the -snes_lag_jacobian information across multiple SNESSolve() 894b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 895f362779dSJed Brown . -snes_convergence_test - <default,skip,correct_pressure> convergence test in nonlinear solver. 896f6dfbefdSBarry Smith default `SNESConvergedDefault()`. skip `SNESConvergedSkip()` means continue iterating until max_it or some other criterion is reached, saving expense 897f6dfbefdSBarry Smith of convergence test. correct_pressure S`NESConvergedCorrectPressure()` has special handling of a pressure null space. 898fde5950dSBarry Smith . -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout 899fde5950dSBarry Smith . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 900fde5950dSBarry Smith . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 901fde5950dSBarry Smith . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 9024619e776SBarry Smith . -snes_monitor_lg_residualnorm - plots residual norm at each iteration 903459f5d12SBarry Smith . -snes_monitor_lg_range - plots residual norm at each iteration 9045e7c47f3SMatthew G. Knepley . -snes_monitor_pause_final - Pauses all monitor drawing after the solver ends 905e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 906e2e60de9SPeter Brune . -snes_fd_color - use finite differences with coloring to compute Jacobian 9075968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 908b5badacbSBarry Smith . -snes_converged_reason - print the reason for convergence/divergence after each solve 909e62ac41dSBarry Smith . -npc_snes_type <type> - the SNES type to use as a nonlinear preconditioner 910e62ac41dSBarry 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. 911e62ac41dSBarry 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. 91282738288SBarry Smith 913f6dfbefdSBarry Smith Options Database Keys for Eisenstat-Walker method: 914fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 9154b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 91636851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 91736851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 91836851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 91936851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 92036851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 92136851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 92282738288SBarry Smith 92311ca99fdSLois Curfman McInnes Notes: 924ec5066bdSBarry Smith To see all options, run your program with the -help option or consult the users manual 925ec5066bdSBarry Smith 926f6dfbefdSBarry Smith `SNES` supports three approaches for computing (approximate) Jacobians: user provided via `SNESSetJacobian()`, matrix free, and computing explicitly with 927f6dfbefdSBarry Smith finite differences and coloring using `MatFDColoring`. It is also possible to use automatic differentiation and the `MatFDColoring` object. 92883e2fdc7SBarry Smith 92936851e7fSLois Curfman McInnes Level: beginner 93036851e7fSLois Curfman McInnes 931f6dfbefdSBarry Smith .seealso: `SNESType`, `SNESSetOptionsPrefix()`, `SNESResetFromOptions()`, `SNES`, `SNESCreate()` 9329b94acceSBarry Smith @*/ 933d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFromOptions(SNES snes) 934d71ae5a4SJacob Faibussowitsch { 9358afaa268SBarry Smith PetscBool flg, pcset, persist, set; 936d8f46077SPeter Brune PetscInt i, indx, lag, grids; 93704d7464bSBarry Smith const char *deft = SNESNEWTONLS; 938649ef022SMatthew Knepley const char *convtests[] = {"default", "skip", "correct_pressure"}; 93985385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 9400f0abf79SStefano Zampini char type[256], monfilename[PETSC_MAX_PATH_LEN], ewprefix[256]; 941c40d0f55SPeter Brune PCSide pcside; 942a64e098fSPeter Brune const char *optionsprefix; 9439b94acceSBarry Smith 9443a40ed3dSBarry Smith PetscFunctionBegin; 9450700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 9469566063dSJacob Faibussowitsch PetscCall(SNESRegisterAll()); 947d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)snes); 948639ff905SBarry Smith if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name; 9499566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-snes_type", "Nonlinear solver method", "SNESSetType", SNESList, deft, type, 256, &flg)); 950d64ed03dSBarry Smith if (flg) { 9519566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, type)); 9527adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 9539566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, deft)); 954d64ed03dSBarry Smith } 9559566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_stol", "Stop if step length less than", "SNESSetTolerances", snes->stol, &snes->stol, NULL)); 9569566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_atol", "Stop if function norm less than", "SNESSetTolerances", snes->abstol, &snes->abstol, NULL)); 957186905e3SBarry Smith 9589566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_rtol", "Stop if decrease in function norm less than", "SNESSetTolerances", snes->rtol, &snes->rtol, NULL)); 9599566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_divergence_tolerance", "Stop if residual norm increases by this factor", "SNESSetDivergenceTolerance", snes->divtol, &snes->divtol, NULL)); 9609566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_it", "Maximum iterations", "SNESSetTolerances", snes->max_its, &snes->max_its, NULL)); 9619566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_funcs", "Maximum function evaluations", "SNESSetTolerances", snes->max_funcs, &snes->max_funcs, NULL)); 9629566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_fail", "Maximum nonlinear step failures", "SNESSetMaxNonlinearStepFailures", snes->maxFailures, &snes->maxFailures, NULL)); 9639566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_linear_solve_fail", "Maximum failures in linear solves allowed", "SNESSetMaxLinearSolveFailures", snes->maxLinearSolveFailures, &snes->maxLinearSolveFailures, NULL)); 9649566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_error_if_not_converged", "Generate error if solver does not converge", "SNESSetErrorIfNotConverged", snes->errorifnotconverged, &snes->errorifnotconverged, NULL)); 9659566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_force_iteration", "Force SNESSolve() to take at least one iteration", "SNESSetForceIteration", snes->forceiteration, &snes->forceiteration, NULL)); 9669566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_check_jacobian_domain_error", "Check Jacobian domain error after Jacobian evaluation", "SNESCheckJacobianDomainError", snes->checkjacdomainerror, &snes->checkjacdomainerror, NULL)); 96785385478SLisandro Dalcin 9689566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_lag_preconditioner", "How often to rebuild preconditioner", "SNESSetLagPreconditioner", snes->lagpreconditioner, &lag, &flg)); 969a8054027SBarry Smith if (flg) { 9705f80ce2aSJacob 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"); 9719566063dSJacob Faibussowitsch PetscCall(SNESSetLagPreconditioner(snes, lag)); 972a8054027SBarry Smith } 9739566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_lag_preconditioner_persists", "Preconditioner lagging through multiple SNES solves", "SNESSetLagPreconditionerPersists", snes->lagjac_persist, &persist, &flg)); 9741baa6e33SBarry Smith if (flg) PetscCall(SNESSetLagPreconditionerPersists(snes, persist)); 9759566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_lag_jacobian", "How often to rebuild Jacobian", "SNESSetLagJacobian", snes->lagjacobian, &lag, &flg)); 976e35cf81dSBarry Smith if (flg) { 9775f80ce2aSJacob 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"); 9789566063dSJacob Faibussowitsch PetscCall(SNESSetLagJacobian(snes, lag)); 979e35cf81dSBarry Smith } 9809566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_lag_jacobian_persists", "Jacobian lagging through multiple SNES solves", "SNESSetLagJacobianPersists", snes->lagjac_persist, &persist, &flg)); 9811baa6e33SBarry Smith if (flg) PetscCall(SNESSetLagJacobianPersists(snes, persist)); 98237ec4e1aSPeter Brune 9839566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_grid_sequence", "Use grid sequencing to generate initial guess", "SNESSetGridSequence", snes->gridsequence, &grids, &flg)); 9841baa6e33SBarry Smith if (flg) PetscCall(SNESSetGridSequence(snes, grids)); 985a8054027SBarry Smith 9869566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_convergence_test", "Convergence test", "SNESSetConvergenceTest", convtests, sizeof(convtests) / sizeof(char *), "default", &indx, &flg)); 98785385478SLisandro Dalcin if (flg) { 98885385478SLisandro Dalcin switch (indx) { 989d71ae5a4SJacob Faibussowitsch case 0: 990d71ae5a4SJacob Faibussowitsch PetscCall(SNESSetConvergenceTest(snes, SNESConvergedDefault, NULL, NULL)); 991d71ae5a4SJacob Faibussowitsch break; 992d71ae5a4SJacob Faibussowitsch case 1: 993d71ae5a4SJacob Faibussowitsch PetscCall(SNESSetConvergenceTest(snes, SNESConvergedSkip, NULL, NULL)); 994d71ae5a4SJacob Faibussowitsch break; 995d71ae5a4SJacob Faibussowitsch case 2: 996d71ae5a4SJacob Faibussowitsch PetscCall(SNESSetConvergenceTest(snes, SNESConvergedCorrectPressure, NULL, NULL)); 997d71ae5a4SJacob Faibussowitsch break; 99885385478SLisandro Dalcin } 99985385478SLisandro Dalcin } 100085385478SLisandro Dalcin 10019566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_norm_schedule", "SNES Norm schedule", "SNESSetNormSchedule", SNESNormSchedules, 5, "function", &indx, &flg)); 10029566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetNormSchedule(snes, (SNESNormSchedule)indx)); 1003fdacfa88SPeter Brune 10049566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_function_type", "SNES Norm schedule", "SNESSetFunctionType", SNESFunctionTypes, 2, "unpreconditioned", &indx, &flg)); 10059566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetFunctionType(snes, (SNESFunctionType)indx)); 1006186905e3SBarry Smith 100785385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 100885385478SLisandro Dalcin 10099566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_ksp_ew", "Use Eisentat-Walker linear system convergence test", "SNESKSPSetUseEW", snes->ksp_ewconv, &snes->ksp_ewconv, NULL)); 1010186905e3SBarry Smith 10110f0abf79SStefano Zampini PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 10120f0abf79SStefano Zampini PetscCall(PetscSNPrintf(ewprefix, sizeof(ewprefix), "%s%s", optionsprefix ? optionsprefix : "", "snes_")); 10130f0abf79SStefano Zampini PetscCall(SNESEWSetFromOptions_Private(kctx, PetscObjectComm((PetscObject)snes), ewprefix)); 10140f0abf79SStefano Zampini 10159566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_ksp_ew_version", "Version 1, 2 or 3", "SNESKSPSetParametersEW", kctx->version, &kctx->version, NULL)); 10169566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_rtol0", "0 <= rtol0 < 1", "SNESKSPSetParametersEW", kctx->rtol_0, &kctx->rtol_0, NULL)); 10179566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_rtolmax", "0 <= rtolmax < 1", "SNESKSPSetParametersEW", kctx->rtol_max, &kctx->rtol_max, NULL)); 10189566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_gamma", "0 <= gamma <= 1", "SNESKSPSetParametersEW", kctx->gamma, &kctx->gamma, NULL)); 10199566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha", "1 < alpha <= 2", "SNESKSPSetParametersEW", kctx->alpha, &kctx->alpha, NULL)); 10209566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha2", "alpha2", "SNESKSPSetParametersEW", kctx->alpha2, &kctx->alpha2, NULL)); 10219566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_threshold", "0 < threshold < 1", "SNESKSPSetParametersEW", kctx->threshold, &kctx->threshold, NULL)); 1022186905e3SBarry Smith 102390d69ab7SBarry Smith flg = PETSC_FALSE; 10249566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_cancel", "Remove all monitors", "SNESMonitorCancel", flg, &flg, &set)); 10259566063dSJacob Faibussowitsch if (set && flg) PetscCall(SNESMonitorCancel(snes)); 1026eabae89aSBarry Smith 10279566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor", "Monitor norm of function", "SNESMonitorDefault", SNESMonitorDefault, SNESMonitorDefaultSetUp)); 10289566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_short", "Monitor norm of function with fewer digits", "SNESMonitorDefaultShort", SNESMonitorDefaultShort, NULL)); 10299566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_range", "Monitor range of elements of function", "SNESMonitorRange", SNESMonitorRange, NULL)); 1030eabae89aSBarry Smith 10319566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_ratio", "Monitor ratios of the norm of function for consecutive steps", "SNESMonitorRatio", SNESMonitorRatio, SNESMonitorRatioSetUp)); 10329566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_field", "Monitor norm of function (split into fields)", "SNESMonitorDefaultField", SNESMonitorDefaultField, NULL)); 10339566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_solution", "View solution at each iteration", "SNESMonitorSolution", SNESMonitorSolution, NULL)); 10349566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_solution_update", "View correction at each iteration", "SNESMonitorSolutionUpdate", SNESMonitorSolutionUpdate, NULL)); 10359566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_residual", "View residual at each iteration", "SNESMonitorResidual", SNESMonitorResidual, NULL)); 10369566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_jacupdate_spectrum", "Print the change in the spectrum of the Jacobian", "SNESMonitorJacUpdateSpectrum", SNESMonitorJacUpdateSpectrum, NULL)); 10379566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_fields", "Monitor norm of function per field", "SNESMonitorSet", SNESMonitorFields, NULL)); 10389566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_pause_final", "Pauses all draw monitors at the final iterate", "SNESMonitorPauseFinal_Internal", PETSC_FALSE, &snes->pauseFinal, NULL)); 10392db13446SMatthew G. Knepley 10409566063dSJacob Faibussowitsch PetscCall(PetscOptionsString("-snes_monitor_python", "Use Python function", "SNESMonitorSet", NULL, monfilename, sizeof(monfilename), &flg)); 10419566063dSJacob Faibussowitsch if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)snes, monfilename)); 10425180491cSLisandro Dalcin 104390d69ab7SBarry Smith flg = PETSC_FALSE; 10449566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_lg_range", "Plot function range at each iteration", "SNESMonitorLGRange", flg, &flg, NULL)); 1045459f5d12SBarry Smith if (flg) { 1046459f5d12SBarry Smith PetscViewer ctx; 1047e24b481bSBarry Smith 10489566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &ctx)); 10499566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, SNESMonitorLGRange, ctx, (PetscErrorCode(*)(void **))PetscViewerDestroy)); 1050459f5d12SBarry Smith } 10512e7541e6SPeter Brune 105290d69ab7SBarry Smith flg = PETSC_FALSE; 10539566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_converged_reason_view_cancel", "Remove all converged reason viewers", "SNESConvergedReasonViewCancel", flg, &flg, &set)); 10549566063dSJacob Faibussowitsch if (set && flg) PetscCall(SNESConvergedReasonViewCancel(snes)); 1055c4421ceaSFande Kong 1056c4421ceaSFande Kong flg = PETSC_FALSE; 10579566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd", "Use finite differences (slow) to compute Jacobian", "SNESComputeJacobianDefault", flg, &flg, NULL)); 10584b27c08aSLois Curfman McInnes if (flg) { 10596cab3a1bSJed Brown void *functx; 1060b1f624c7SBarry Smith DM dm; 10619566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 1062800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetJacobianContext_Internal(dm)); 10639566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 10649566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, snes->jacobian, snes->jacobian_pre, SNESComputeJacobianDefault, functx)); 10659566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default finite difference Jacobian matrix\n")); 10669b94acceSBarry Smith } 1067639f9d9dSBarry Smith 106844848bc4SPeter Brune flg = PETSC_FALSE; 10699566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd_function", "Use finite differences (slow) to compute function from user objective", "SNESObjectiveComputeFunctionDefaultFD", flg, &flg, NULL)); 10701baa6e33SBarry Smith if (flg) PetscCall(SNESSetFunction(snes, NULL, SNESObjectiveComputeFunctionDefaultFD, NULL)); 107197584545SPeter Brune 107297584545SPeter Brune flg = PETSC_FALSE; 10739566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd_color", "Use finite differences with coloring to compute Jacobian", "SNESComputeJacobianDefaultColor", flg, &flg, NULL)); 107444848bc4SPeter Brune if (flg) { 1075c52e227fSPeter Brune DM dm; 10769566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 1077800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetJacobianContext_Internal(dm)); 10789566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, snes->jacobian, snes->jacobian_pre, SNESComputeJacobianDefaultColor, NULL)); 10799566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default finite difference coloring Jacobian matrix\n")); 108044848bc4SPeter Brune } 108144848bc4SPeter Brune 1082aa3661deSLisandro Dalcin flg = PETSC_FALSE; 10839566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_mf_operator", "Use a Matrix-Free Jacobian with user-provided preconditioner matrix", "SNESSetUseMatrixFree", PETSC_FALSE, &snes->mf_operator, &flg)); 1084d8f46077SPeter Brune if (flg && snes->mf_operator) { 1085a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 1086d8f46077SPeter Brune snes->mf = PETSC_TRUE; 1087a8248277SBarry Smith } 1088aa3661deSLisandro Dalcin flg = PETSC_FALSE; 10899566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_mf", "Use a Matrix-Free Jacobian with no preconditioner matrix", "SNESSetUseMatrixFree", PETSC_FALSE, &snes->mf, &flg)); 1090d8f46077SPeter Brune if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 10919566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_mf_version", "Matrix-Free routines version 1 or 2", "None", snes->mf_version, &snes->mf_version, NULL)); 1092d28543b3SPeter Brune 1093c40d0f55SPeter Brune flg = PETSC_FALSE; 10949566063dSJacob Faibussowitsch PetscCall(SNESGetNPCSide(snes, &pcside)); 10959566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-snes_npc_side", "SNES nonlinear preconditioner side", "SNESSetNPCSide", PCSides, (PetscEnum)pcside, (PetscEnum *)&pcside, &flg)); 10969566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetNPCSide(snes, pcside)); 1097c40d0f55SPeter Brune 1098e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 10998a70d858SHong Zhang /* 11008a70d858SHong Zhang Publish convergence information using SAWs 11018a70d858SHong Zhang */ 11028a70d858SHong Zhang flg = PETSC_FALSE; 11039566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_saws", "Publish SNES progress using SAWs", "SNESMonitorSet", flg, &flg, NULL)); 11048a70d858SHong Zhang if (flg) { 11058a70d858SHong Zhang void *ctx; 11069566063dSJacob Faibussowitsch PetscCall(SNESMonitorSAWsCreate(snes, &ctx)); 11079566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, SNESMonitorSAWs, ctx, SNESMonitorSAWsDestroy)); 11088a70d858SHong Zhang } 11098a70d858SHong Zhang #endif 11108a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS) 1111b90c6cbeSBarry Smith { 1112b90c6cbeSBarry Smith PetscBool set; 1113b90c6cbeSBarry Smith flg = PETSC_FALSE; 11149566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_saws_block", "Block for SAWs at end of SNESSolve", "PetscObjectSAWsBlock", ((PetscObject)snes)->amspublishblock, &flg, &set)); 11151baa6e33SBarry Smith if (set) PetscCall(PetscObjectSAWsSetBlock((PetscObject)snes, flg)); 1116b90c6cbeSBarry Smith } 1117b90c6cbeSBarry Smith #endif 1118b90c6cbeSBarry Smith 111948a46eb9SPierre Jolivet for (i = 0; i < numberofsetfromoptions; i++) PetscCall((*othersetfromoptions[i])(snes)); 112076b2cf59SMatthew Knepley 1121dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, setfromoptions, PetscOptionsObject); 11225d973c19SBarry Smith 11235d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 1124dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)snes, PetscOptionsObject)); 1125d0609cedSBarry Smith PetscOptionsEnd(); 11264bbc92c1SBarry Smith 1127d8d34be6SBarry Smith if (snes->linesearch) { 11289566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 11299566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFromOptions(snes->linesearch)); 1130d8d34be6SBarry Smith } 11319e764e56SPeter Brune 11326aa5e7e9SBarry Smith if (snes->usesksp) { 11339566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 11349566063dSJacob Faibussowitsch PetscCall(KSPSetOperators(snes->ksp, snes->jacobian, snes->jacobian_pre)); 11359566063dSJacob Faibussowitsch PetscCall(KSPSetFromOptions(snes->ksp)); 11366aa5e7e9SBarry Smith } 11376991f827SBarry Smith 1138b5badacbSBarry Smith /* if user has set the SNES NPC type via options database, create it. */ 11399566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 11409566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasName(((PetscObject)snes)->options, optionsprefix, "-npc_snes_type", &pcset)); 114148a46eb9SPierre Jolivet if (pcset && (!snes->npc)) PetscCall(SNESGetNPC(snes, &snes->npc)); 11421baa6e33SBarry Smith if (snes->npc) PetscCall(SNESSetFromOptions(snes->npc)); 1143b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled++; 1144b3cd9a81SMatthew G. Knepley PetscFunctionReturn(0); 1145b3cd9a81SMatthew G. Knepley } 1146b3cd9a81SMatthew G. Knepley 1147b3cd9a81SMatthew G. Knepley /*@ 1148f6dfbefdSBarry Smith SNESResetFromOptions - Sets various `SNES` and `KSP` parameters from user options ONLY if the `SNESSetFromOptions()` was previously set from options 1149b3cd9a81SMatthew G. Knepley 1150*c3339decSBarry Smith Collective 1151b3cd9a81SMatthew G. Knepley 1152b3cd9a81SMatthew G. Knepley Input Parameter: 1153f6dfbefdSBarry Smith . snes - the `SNES` context 1154b3cd9a81SMatthew G. Knepley 1155b3cd9a81SMatthew G. Knepley Level: beginner 1156b3cd9a81SMatthew G. Knepley 1157f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFromOptions()`, `SNESSetOptionsPrefix()` 1158b3cd9a81SMatthew G. Knepley @*/ 1159d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESResetFromOptions(SNES snes) 1160d71ae5a4SJacob Faibussowitsch { 1161b3cd9a81SMatthew G. Knepley PetscFunctionBegin; 11629566063dSJacob Faibussowitsch if (snes->setfromoptionscalled) PetscCall(SNESSetFromOptions(snes)); 11633a40ed3dSBarry Smith PetscFunctionReturn(0); 11649b94acceSBarry Smith } 11659b94acceSBarry Smith 1166bb9467b5SJed Brown /*@C 1167d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 1168d25893d9SBarry Smith the nonlinear solvers. 1169d25893d9SBarry Smith 1170*c3339decSBarry Smith Logically Collective 1171d25893d9SBarry Smith 1172d25893d9SBarry Smith Input Parameters: 1173f6dfbefdSBarry Smith + snes - the `SNES` context 1174d25893d9SBarry Smith . compute - function to compute the context 1175d25893d9SBarry Smith - destroy - function to destroy the context 1176d25893d9SBarry Smith 1177d25893d9SBarry Smith Level: intermediate 1178d25893d9SBarry Smith 1179f6dfbefdSBarry Smith Note: 1180f6dfbefdSBarry Smith This routine is useful if you are performing grid sequencing or using `SNESFAS` and need the appropriate context generated for each level. 1181f6dfbefdSBarry Smith 1182f6dfbefdSBarry Smith Use `SNESSetApplicationContext()` to see the context immediately 1183f6dfbefdSBarry Smith 1184f6dfbefdSBarry Smith Fortran Note: 1185bb9467b5SJed Brown This function is currently not available from Fortran. 1186bb9467b5SJed Brown 1187f6dfbefdSBarry Smith .seealso: `SNESGetApplicationContext()`, `SNESSetComputeApplicationContext()`, `SNESSetApplicationContext()` 1188d25893d9SBarry Smith @*/ 1189d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetComputeApplicationContext(SNES snes, PetscErrorCode (*compute)(SNES, void **), PetscErrorCode (*destroy)(void **)) 1190d71ae5a4SJacob Faibussowitsch { 1191d25893d9SBarry Smith PetscFunctionBegin; 1192d25893d9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1193d25893d9SBarry Smith snes->ops->usercompute = compute; 1194d25893d9SBarry Smith snes->ops->userdestroy = destroy; 1195d25893d9SBarry Smith PetscFunctionReturn(0); 1196d25893d9SBarry Smith } 1197a847f771SSatish Balay 1198b07ff414SBarry Smith /*@ 1199f6dfbefdSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for the nonlinear solvers. 12009b94acceSBarry Smith 1201*c3339decSBarry Smith Logically Collective 1202fee21e36SBarry Smith 1203c7afd0dbSLois Curfman McInnes Input Parameters: 1204f6dfbefdSBarry Smith + snes - the `SNES` context 1205c7afd0dbSLois Curfman McInnes - usrP - optional user context 1206c7afd0dbSLois Curfman McInnes 120736851e7fSLois Curfman McInnes Level: intermediate 120836851e7fSLois Curfman McInnes 1209f6dfbefdSBarry Smith Notes: 1210f6dfbefdSBarry Smith Users can provide a context when constructing the `SNES` options and then access it inside their function, Jacobian, or other evaluation function 1211f6dfbefdSBarry Smith with `SNESGetApplicationContext()` 1212f6dfbefdSBarry Smith 1213f6dfbefdSBarry Smith To provide a function that computes the context for you use `SNESSetComputeApplicationContext()` 1214f6dfbefdSBarry Smith 1215f6dfbefdSBarry Smith Fortran Note: 121695452b02SPatrick Sanan To use this from Fortran you must write a Fortran interface definition for this 1217daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1218daf670e6SBarry Smith 1219f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetComputeApplicationContext()`, `SNESGetApplicationContext()` 12209b94acceSBarry Smith @*/ 1221d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetApplicationContext(SNES snes, void *usrP) 1222d71ae5a4SJacob Faibussowitsch { 1223b07ff414SBarry Smith KSP ksp; 12241b2093e4SBarry Smith 12253a40ed3dSBarry Smith PetscFunctionBegin; 12260700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 12279566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 12289566063dSJacob Faibussowitsch PetscCall(KSPSetApplicationContext(ksp, usrP)); 12299b94acceSBarry Smith snes->user = usrP; 12303a40ed3dSBarry Smith PetscFunctionReturn(0); 12319b94acceSBarry Smith } 123274679c65SBarry Smith 1233b07ff414SBarry Smith /*@ 12349b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 1235f6dfbefdSBarry Smith nonlinear solvers set with `SNESGetApplicationContext()` or with `SNESSetComputeApplicationContext()` 12369b94acceSBarry Smith 1237c7afd0dbSLois Curfman McInnes Not Collective 1238c7afd0dbSLois Curfman McInnes 12399b94acceSBarry Smith Input Parameter: 1240f6dfbefdSBarry Smith . snes - `SNES` context 12419b94acceSBarry Smith 12429b94acceSBarry Smith Output Parameter: 12439b94acceSBarry Smith . usrP - user context 12449b94acceSBarry Smith 1245f6dfbefdSBarry Smith Fortran Note: 124695452b02SPatrick Sanan To use this from Fortran you must write a Fortran interface definition for this 1247daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1248daf670e6SBarry Smith 124936851e7fSLois Curfman McInnes Level: intermediate 125036851e7fSLois Curfman McInnes 1251db781477SPatrick Sanan .seealso: `SNESSetApplicationContext()` 12529b94acceSBarry Smith @*/ 1253d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetApplicationContext(SNES snes, void *usrP) 1254d71ae5a4SJacob Faibussowitsch { 12553a40ed3dSBarry Smith PetscFunctionBegin; 12560700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1257e71120c6SJed Brown *(void **)usrP = snes->user; 12583a40ed3dSBarry Smith PetscFunctionReturn(0); 12599b94acceSBarry Smith } 126074679c65SBarry Smith 12619b94acceSBarry Smith /*@ 1262f6dfbefdSBarry Smith SNESSetUseMatrixFree - indicates that `SNES` should use matrix free finite difference matrix vector products to apply the Jacobian. 12633565c898SBarry Smith 1264f6dfbefdSBarry Smith Logically Collective on snes, the values must be the same on all MPI ranks 12653565c898SBarry Smith 12663565c898SBarry Smith Input Parameters: 1267f6dfbefdSBarry Smith + snes - `SNES` context 1268f6dfbefdSBarry Smith . mf_operator - use matrix-free only for the Amat used by `SNESSetJacobian()`, this means the user provided Pmat will continue to be used 1269f6dfbefdSBarry 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 1270f6dfbefdSBarry Smith this option no matrix element based preconditioners can be used in the linear solve since the matrix won't be explicitly available 12713565c898SBarry Smith 1272f6dfbefdSBarry Smith Options Database Keys: 1273f6dfbefdSBarry Smith + -snes_mf_operator - use matrix free only for the mat operator 1274f6dfbefdSBarry Smith . -snes_mf - use matrix-free for both the mat and pmat operator 1275ec5066bdSBarry Smith . -snes_fd_color - compute the Jacobian via coloring and finite differences. 1276ec5066bdSBarry Smith - -snes_fd - compute the Jacobian via finite differences (slow) 12773565c898SBarry Smith 12783565c898SBarry Smith Level: intermediate 12793565c898SBarry Smith 1280f6dfbefdSBarry Smith Note: 1281f6dfbefdSBarry Smith SNES supports three approaches for computing (approximate) Jacobians: user provided via `SNESSetJacobian()`, matrix-free, and computing explicitly with 1282f6dfbefdSBarry Smith finite differences and coloring using `MatFDColoring`. It is also possible to use automatic differentiation and the `MatFDColoring` object. 1283ec5066bdSBarry Smith 1284f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetUseMatrixFree()`, `MatCreateSNESMF()`, `SNESComputeJacobianDefaultColor()` 12853565c898SBarry Smith @*/ 1286d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUseMatrixFree(SNES snes, PetscBool mf_operator, PetscBool mf) 1287d71ae5a4SJacob Faibussowitsch { 12883565c898SBarry Smith PetscFunctionBegin; 12893565c898SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 129088b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes, mf_operator, 2); 129188b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes, mf, 3); 12924ddffce6SLisandro Dalcin snes->mf = mf_operator ? PETSC_TRUE : mf; 12933565c898SBarry Smith snes->mf_operator = mf_operator; 12943565c898SBarry Smith PetscFunctionReturn(0); 12953565c898SBarry Smith } 12963565c898SBarry Smith 12973565c898SBarry Smith /*@ 1298f6dfbefdSBarry Smith SNESGetUseMatrixFree - indicates if the SNES uses matrix-free finite difference matrix vector products to apply the Jacobian. 12993565c898SBarry Smith 1300f6dfbefdSBarry Smith Not Collective, but the resulting flags will be the same on all MPI ranks 13013565c898SBarry Smith 13023565c898SBarry Smith Input Parameter: 1303f6dfbefdSBarry Smith . snes - `SNES` context 13043565c898SBarry Smith 13053565c898SBarry Smith Output Parameters: 1306f6dfbefdSBarry Smith + mf_operator - use matrix-free only for the Amat used by `SNESSetJacobian()`, this means the user provided Pmat will continue to be used 1307f6dfbefdSBarry 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 13083565c898SBarry Smith 13093565c898SBarry Smith Level: intermediate 13103565c898SBarry Smith 1311f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetUseMatrixFree()`, `MatCreateSNESMF()` 13123565c898SBarry Smith @*/ 1313d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetUseMatrixFree(SNES snes, PetscBool *mf_operator, PetscBool *mf) 1314d71ae5a4SJacob Faibussowitsch { 13153565c898SBarry Smith PetscFunctionBegin; 13163565c898SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13173565c898SBarry Smith if (mf) *mf = snes->mf; 13183565c898SBarry Smith if (mf_operator) *mf_operator = snes->mf_operator; 13193565c898SBarry Smith PetscFunctionReturn(0); 13203565c898SBarry Smith } 13213565c898SBarry Smith 13223565c898SBarry Smith /*@ 1323c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 1324c8228a4eSBarry Smith at this time. 13259b94acceSBarry Smith 1326c7afd0dbSLois Curfman McInnes Not Collective 1327c7afd0dbSLois Curfman McInnes 13289b94acceSBarry Smith Input Parameter: 1329f6dfbefdSBarry Smith . snes - `SNES` context 13309b94acceSBarry Smith 13319b94acceSBarry Smith Output Parameter: 13329b94acceSBarry Smith . iter - iteration number 13339b94acceSBarry Smith 1334c8228a4eSBarry Smith Notes: 1335c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 1336c8228a4eSBarry Smith 1337c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 1338f6dfbefdSBarry Smith Jacobian at each `SNES` iteration). For example, the code 133908405cd6SLois Curfman McInnes .vb 134008405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 134108405cd6SLois Curfman McInnes if (!(it % 2)) { 134208405cd6SLois Curfman McInnes [compute Jacobian here] 134308405cd6SLois Curfman McInnes } 134408405cd6SLois Curfman McInnes .ve 1345f6dfbefdSBarry Smith can be used in your function that computes the Jacobian to cause the Jacobian to be 1346f6dfbefdSBarry Smith recomputed every second `SNES` iteration. See also `SNESSetLagJacobian()` 1347c8228a4eSBarry Smith 1348f6dfbefdSBarry Smith After the `SNES` solve is complete this will return the number of nonlinear iterations used. 1349c04deec6SBarry Smith 135036851e7fSLois Curfman McInnes Level: intermediate 135136851e7fSLois Curfman McInnes 1352f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESSetLagJacobian()`, `SNESGetLinearSolveIterations()` 13539b94acceSBarry Smith @*/ 1354d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetIterationNumber(SNES snes, PetscInt *iter) 1355d71ae5a4SJacob Faibussowitsch { 13563a40ed3dSBarry Smith PetscFunctionBegin; 13570700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13584482741eSBarry Smith PetscValidIntPointer(iter, 2); 13599b94acceSBarry Smith *iter = snes->iter; 13603a40ed3dSBarry Smith PetscFunctionReturn(0); 13619b94acceSBarry Smith } 136274679c65SBarry Smith 1363360c497dSPeter Brune /*@ 1364360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 1365360c497dSPeter Brune 1366360c497dSPeter Brune Not Collective 1367360c497dSPeter Brune 1368d8d19677SJose E. Roman Input Parameters: 1369f6dfbefdSBarry Smith + snes - `SNES` context 1370a2b725a8SWilliam Gropp - iter - iteration number 1371360c497dSPeter Brune 1372360c497dSPeter Brune Level: developer 1373360c497dSPeter Brune 1374db781477SPatrick Sanan .seealso: `SNESGetLinearSolveIterations()` 1375360c497dSPeter Brune @*/ 1376d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetIterationNumber(SNES snes, PetscInt iter) 1377d71ae5a4SJacob Faibussowitsch { 1378360c497dSPeter Brune PetscFunctionBegin; 1379360c497dSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13809566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsTakeAccess((PetscObject)snes)); 1381360c497dSPeter Brune snes->iter = iter; 13829566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsGrantAccess((PetscObject)snes)); 1383360c497dSPeter Brune PetscFunctionReturn(0); 1384360c497dSPeter Brune } 1385360c497dSPeter Brune 13869b94acceSBarry Smith /*@ 1387b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 13889b94acceSBarry Smith attempted by the nonlinear solver. 13899b94acceSBarry Smith 1390c7afd0dbSLois Curfman McInnes Not Collective 1391c7afd0dbSLois Curfman McInnes 13929b94acceSBarry Smith Input Parameter: 1393f6dfbefdSBarry Smith . snes - `SNES` context 13949b94acceSBarry Smith 13959b94acceSBarry Smith Output Parameter: 13969b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 13979b94acceSBarry Smith 1398f6dfbefdSBarry Smith Note: 1399f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()`. 1400c96a6f78SLois Curfman McInnes 140136851e7fSLois Curfman McInnes Level: intermediate 140236851e7fSLois Curfman McInnes 1403f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1404db781477SPatrick Sanan `SNESSetMaxNonlinearStepFailures()`, `SNESGetMaxNonlinearStepFailures()` 14059b94acceSBarry Smith @*/ 1406d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNonlinearStepFailures(SNES snes, PetscInt *nfails) 1407d71ae5a4SJacob Faibussowitsch { 14083a40ed3dSBarry Smith PetscFunctionBegin; 14090700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14104482741eSBarry Smith PetscValidIntPointer(nfails, 2); 141150ffb88aSMatthew Knepley *nfails = snes->numFailures; 141250ffb88aSMatthew Knepley PetscFunctionReturn(0); 141350ffb88aSMatthew Knepley } 141450ffb88aSMatthew Knepley 141550ffb88aSMatthew Knepley /*@ 1416b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 1417f6dfbefdSBarry Smith attempted by the nonlinear solver before it gives up and generates an error 141850ffb88aSMatthew Knepley 141950ffb88aSMatthew Knepley Not Collective 142050ffb88aSMatthew Knepley 142150ffb88aSMatthew Knepley Input Parameters: 1422f6dfbefdSBarry Smith + snes - `SNES` context 142350ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 142450ffb88aSMatthew Knepley 142550ffb88aSMatthew Knepley Level: intermediate 142650ffb88aSMatthew Knepley 1427f6dfbefdSBarry Smith .seealso: `SNESSetErrorIfNotConverged()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1428db781477SPatrick Sanan `SNESGetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 142950ffb88aSMatthew Knepley @*/ 1430d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 1431d71ae5a4SJacob Faibussowitsch { 143250ffb88aSMatthew Knepley PetscFunctionBegin; 14330700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 143450ffb88aSMatthew Knepley snes->maxFailures = maxFails; 143550ffb88aSMatthew Knepley PetscFunctionReturn(0); 143650ffb88aSMatthew Knepley } 143750ffb88aSMatthew Knepley 143850ffb88aSMatthew Knepley /*@ 1439b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 1440f6dfbefdSBarry Smith attempted by the nonlinear solver before it gives up and generates an error 144150ffb88aSMatthew Knepley 144250ffb88aSMatthew Knepley Not Collective 144350ffb88aSMatthew Knepley 144450ffb88aSMatthew Knepley Input Parameter: 144550ffb88aSMatthew Knepley . snes - SNES context 144650ffb88aSMatthew Knepley 144750ffb88aSMatthew Knepley Output Parameter: 144850ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 144950ffb88aSMatthew Knepley 145050ffb88aSMatthew Knepley Level: intermediate 145150ffb88aSMatthew Knepley 1452f6dfbefdSBarry Smith .seealso: `SNESSetErrorIfNotConverged()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1453db781477SPatrick Sanan `SNESSetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 145450ffb88aSMatthew Knepley @*/ 1455d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 1456d71ae5a4SJacob Faibussowitsch { 145750ffb88aSMatthew Knepley PetscFunctionBegin; 14580700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14594482741eSBarry Smith PetscValidIntPointer(maxFails, 2); 146050ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 14613a40ed3dSBarry Smith PetscFunctionReturn(0); 14629b94acceSBarry Smith } 1463a847f771SSatish Balay 14642541af92SBarry Smith /*@ 14652541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 1466f6dfbefdSBarry Smith done by the `SNES` object 14672541af92SBarry Smith 14682541af92SBarry Smith Not Collective 14692541af92SBarry Smith 14702541af92SBarry Smith Input Parameter: 1471f6dfbefdSBarry Smith . snes - `SNES` context 14722541af92SBarry Smith 14732541af92SBarry Smith Output Parameter: 14742541af92SBarry Smith . nfuncs - number of evaluations 14752541af92SBarry Smith 14762541af92SBarry Smith Level: intermediate 14772541af92SBarry Smith 1478f6dfbefdSBarry Smith Note: 1479f6dfbefdSBarry Smith Reset every time `SNESSolve()` is called unless `SNESSetCountersReset()` is used. 1480971e163fSPeter Brune 1481f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, `SNESSetCountersReset()` 14822541af92SBarry Smith @*/ 1483d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 1484d71ae5a4SJacob Faibussowitsch { 14852541af92SBarry Smith PetscFunctionBegin; 14860700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14872541af92SBarry Smith PetscValidIntPointer(nfuncs, 2); 14882541af92SBarry Smith *nfuncs = snes->nfuncs; 14892541af92SBarry Smith PetscFunctionReturn(0); 14902541af92SBarry Smith } 14912541af92SBarry Smith 14923d4c4710SBarry Smith /*@ 14933d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 14943d4c4710SBarry Smith linear solvers. 14953d4c4710SBarry Smith 14963d4c4710SBarry Smith Not Collective 14973d4c4710SBarry Smith 14983d4c4710SBarry Smith Input Parameter: 1499f6dfbefdSBarry Smith . snes - `SNES` context 15003d4c4710SBarry Smith 15013d4c4710SBarry Smith Output Parameter: 15023d4c4710SBarry Smith . nfails - number of failed solves 15033d4c4710SBarry Smith 1504f6dfbefdSBarry Smith Options Database Key: 15059d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 15069d85da0cSMatthew G. Knepley 1507f6dfbefdSBarry Smith Level: intermediate 1508f6dfbefdSBarry Smith 1509f6dfbefdSBarry Smith Note: 1510f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()`. 15113d4c4710SBarry Smith 1512db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()` 15133d4c4710SBarry Smith @*/ 1514d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLinearSolveFailures(SNES snes, PetscInt *nfails) 1515d71ae5a4SJacob Faibussowitsch { 15163d4c4710SBarry Smith PetscFunctionBegin; 15170700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 15183d4c4710SBarry Smith PetscValidIntPointer(nfails, 2); 15193d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 15203d4c4710SBarry Smith PetscFunctionReturn(0); 15213d4c4710SBarry Smith } 15223d4c4710SBarry Smith 15233d4c4710SBarry Smith /*@ 15243d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 1525f6dfbefdSBarry Smith allowed before `SNES` returns with a diverged reason of `SNES_DIVERGED_LINEAR_SOLVE` 15263d4c4710SBarry Smith 1527*c3339decSBarry Smith Logically Collective 15283d4c4710SBarry Smith 15293d4c4710SBarry Smith Input Parameters: 1530f6dfbefdSBarry Smith + snes - `SNES` context 15313d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 15323d4c4710SBarry Smith 15333d4c4710SBarry Smith Level: intermediate 15343d4c4710SBarry Smith 1535f6dfbefdSBarry Smith Options Database Key: 15369d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 15379d85da0cSMatthew G. Knepley 1538f6dfbefdSBarry Smith Note: 1539f6dfbefdSBarry Smith By default this is 0; that is `SNES` returns on the first failed linear solve 15403d4c4710SBarry Smith 1541f6dfbefdSBarry Smith .seealso: `SNESSetErrorIfNotConverged()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()` 15423d4c4710SBarry Smith @*/ 1543d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 1544d71ae5a4SJacob Faibussowitsch { 15453d4c4710SBarry Smith PetscFunctionBegin; 15460700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1547c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxFails, 2); 15483d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 15493d4c4710SBarry Smith PetscFunctionReturn(0); 15503d4c4710SBarry Smith } 15513d4c4710SBarry Smith 15523d4c4710SBarry Smith /*@ 15533d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 1554f6dfbefdSBarry Smith are allowed before `SNES` returns as unsuccessful 15553d4c4710SBarry Smith 15563d4c4710SBarry Smith Not Collective 15573d4c4710SBarry Smith 15583d4c4710SBarry Smith Input Parameter: 1559f6dfbefdSBarry Smith . snes - `SNES` context 15603d4c4710SBarry Smith 15613d4c4710SBarry Smith Output Parameter: 15623d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 15633d4c4710SBarry Smith 15643d4c4710SBarry Smith Level: intermediate 15653d4c4710SBarry Smith 1566f6dfbefdSBarry Smith Note: 1567f6dfbefdSBarry Smith By default this is 1; that is `SNES` returns on the first failed linear solve 15683d4c4710SBarry Smith 1569f6dfbefdSBarry Smith .seealso: `SNESSetErrorIfNotConverged()`, `SNESGetLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, 15703d4c4710SBarry Smith @*/ 1571d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 1572d71ae5a4SJacob Faibussowitsch { 15733d4c4710SBarry Smith PetscFunctionBegin; 15740700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 15753d4c4710SBarry Smith PetscValidIntPointer(maxFails, 2); 15763d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 15773d4c4710SBarry Smith PetscFunctionReturn(0); 15783d4c4710SBarry Smith } 15793d4c4710SBarry Smith 1580c96a6f78SLois Curfman McInnes /*@ 1581b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1582c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1583c96a6f78SLois Curfman McInnes 1584c7afd0dbSLois Curfman McInnes Not Collective 1585c7afd0dbSLois Curfman McInnes 1586c96a6f78SLois Curfman McInnes Input Parameter: 1587f6dfbefdSBarry Smith . snes - `SNES` context 1588c96a6f78SLois Curfman McInnes 1589c96a6f78SLois Curfman McInnes Output Parameter: 1590c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1591c96a6f78SLois Curfman McInnes 1592c96a6f78SLois Curfman McInnes Notes: 1593f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()` unless `SNESSetCountersReset()` is used. 1594c96a6f78SLois Curfman McInnes 1595f6dfbefdSBarry 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 1596f6dfbefdSBarry Smith then call `KSPGetIterationNumber()` after the failed solve. 1597010be392SBarry Smith 159836851e7fSLois Curfman McInnes Level: intermediate 159936851e7fSLois Curfman McInnes 1600f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetIterationNumber()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESSetCountersReset()` 1601c96a6f78SLois Curfman McInnes @*/ 1602d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLinearSolveIterations(SNES snes, PetscInt *lits) 1603d71ae5a4SJacob Faibussowitsch { 16043a40ed3dSBarry Smith PetscFunctionBegin; 16050700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 16064482741eSBarry Smith PetscValidIntPointer(lits, 2); 1607c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 16083a40ed3dSBarry Smith PetscFunctionReturn(0); 1609c96a6f78SLois Curfman McInnes } 1610c96a6f78SLois Curfman McInnes 1611971e163fSPeter Brune /*@ 1612971e163fSPeter Brune SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations 1613f6dfbefdSBarry Smith are reset every time `SNESSolve()` is called. 1614971e163fSPeter Brune 1615*c3339decSBarry Smith Logically Collective 1616971e163fSPeter Brune 1617d8d19677SJose E. Roman Input Parameters: 1618f6dfbefdSBarry Smith + snes - `SNES` context 1619f6dfbefdSBarry Smith - reset - whether to reset the counters or not, defaults to `PETSC_TRUE` 1620971e163fSPeter Brune 1621971e163fSPeter Brune Level: developer 1622971e163fSPeter Brune 1623db781477SPatrick Sanan .seealso: `SNESGetNumberFunctionEvals()`, `SNESGetLinearSolveIterations()`, `SNESGetNPC()` 1624971e163fSPeter Brune @*/ 1625d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetCountersReset(SNES snes, PetscBool reset) 1626d71ae5a4SJacob Faibussowitsch { 1627971e163fSPeter Brune PetscFunctionBegin; 1628971e163fSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1629971e163fSPeter Brune PetscValidLogicalCollectiveBool(snes, reset, 2); 1630971e163fSPeter Brune snes->counters_reset = reset; 1631971e163fSPeter Brune PetscFunctionReturn(0); 1632971e163fSPeter Brune } 1633971e163fSPeter Brune 16342999313aSBarry Smith /*@ 1635f6dfbefdSBarry Smith SNESSetKSP - Sets a `KSP` context for the `SNES` object to use 16362999313aSBarry Smith 1637f6dfbefdSBarry Smith Not Collective, but the `SNES` and `KSP` objects must live on the same MPI_Comm 16382999313aSBarry Smith 16392999313aSBarry Smith Input Parameters: 1640f6dfbefdSBarry Smith + snes - the `SNES` context 1641f6dfbefdSBarry Smith - ksp - the `KSP` context 16422999313aSBarry Smith 16432999313aSBarry Smith Notes: 1644f6dfbefdSBarry Smith The `SNES` object already has its `KSP` object, you can obtain with `SNESGetKSP()` 16452999313aSBarry Smith so this routine is rarely needed. 16462999313aSBarry Smith 1647f6dfbefdSBarry Smith The `KSP` object that is already in the `SNES` object has its reference count 16482999313aSBarry Smith decreased by one. 16492999313aSBarry Smith 16502999313aSBarry Smith Level: developer 16512999313aSBarry Smith 1652f6dfbefdSBarry Smith .seealso: `SNES`, `KSP`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()` 16532999313aSBarry Smith @*/ 1654d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetKSP(SNES snes, KSP ksp) 1655d71ae5a4SJacob Faibussowitsch { 16562999313aSBarry Smith PetscFunctionBegin; 16570700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 16580700a824SBarry Smith PetscValidHeaderSpecific(ksp, KSP_CLASSID, 2); 16592999313aSBarry Smith PetscCheckSameComm(snes, 1, ksp, 2); 16609566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ksp)); 16619566063dSJacob Faibussowitsch if (snes->ksp) PetscCall(PetscObjectDereference((PetscObject)snes->ksp)); 16622999313aSBarry Smith snes->ksp = ksp; 16632999313aSBarry Smith PetscFunctionReturn(0); 16642999313aSBarry Smith } 16652999313aSBarry Smith 166652baeb72SSatish Balay /*@ 16679b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 16689b94acceSBarry Smith 1669d083f849SBarry Smith Collective 1670c7afd0dbSLois Curfman McInnes 1671f6dfbefdSBarry Smith Input Parameter: 1672906ed7ccSBarry Smith . comm - MPI communicator 16739b94acceSBarry Smith 16749b94acceSBarry Smith Output Parameter: 16759b94acceSBarry Smith . outsnes - the new SNES context 16769b94acceSBarry Smith 1677c7afd0dbSLois Curfman McInnes Options Database Keys: 1678c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1679c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1680c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1681c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1682c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1683c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1684c1f60f51SBarry Smith 168536851e7fSLois Curfman McInnes Level: beginner 168636851e7fSLois Curfman McInnes 168795452b02SPatrick Sanan Developer Notes: 1688f6dfbefdSBarry Smith `SNES` always creates a `KSP` object even though many `SNES` methods do not use it. This is 1689efd4aadfSBarry Smith unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the 1690f6dfbefdSBarry Smith particular method does use `KSP` and regulates if the information about the `KSP` is printed 1691f6dfbefdSBarry Smith in `SNESView()`. 1692efd4aadfSBarry Smith 1693f6dfbefdSBarry Smith `TSSetFromOptions()` does call `SNESSetFromOptions()` which can lead to users being confused 1694f6dfbefdSBarry Smith by help messages about meaningless `SNES` options. 1695f6dfbefdSBarry Smith 1696f6dfbefdSBarry Smith `SNES` always creates the snes->kspconvctx even though it is used by only one type. This should 1697efd4aadfSBarry Smith be fixed. 1698efd4aadfSBarry Smith 1699f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESDestroy()`, `SNES`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 17009b94acceSBarry Smith @*/ 1701d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESCreate(MPI_Comm comm, SNES *outsnes) 1702d71ae5a4SJacob Faibussowitsch { 17039b94acceSBarry Smith SNES snes; 1704fa9f3622SBarry Smith SNESKSPEW *kctx; 170537fcc0dbSBarry Smith 17063a40ed3dSBarry Smith PetscFunctionBegin; 1707ed1caa07SMatthew Knepley PetscValidPointer(outsnes, 2); 17080298fd71SBarry Smith *outsnes = NULL; 17099566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 17108ba1e511SMatthew Knepley 17119566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(snes, SNES_CLASSID, "SNES", "Nonlinear solver", "SNES", comm, SNESDestroy, SNESView)); 17127adad957SLisandro Dalcin 17138d359177SBarry Smith snes->ops->converged = SNESConvergedDefault; 17142c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 171588976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 17169b94acceSBarry Smith snes->max_its = 50; 17179750a799SBarry Smith snes->max_funcs = 10000; 17189b94acceSBarry Smith snes->norm = 0.0; 1719c1e67a49SFande Kong snes->xnorm = 0.0; 1720c1e67a49SFande Kong snes->ynorm = 0.0; 1721365a6726SPeter Brune snes->normschedule = SNES_NORM_ALWAYS; 17226c67d002SPeter Brune snes->functype = SNES_FUNCTION_DEFAULT; 17233a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17243a2046daSBarry Smith snes->rtol = 1.e-5; 17253a2046daSBarry Smith #else 1726b4874afaSBarry Smith snes->rtol = 1.e-8; 17273a2046daSBarry Smith #endif 1728b4874afaSBarry Smith snes->ttol = 0.0; 17293a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17303a2046daSBarry Smith snes->abstol = 1.e-25; 17313a2046daSBarry Smith #else 173270441072SBarry Smith snes->abstol = 1.e-50; 17333a2046daSBarry Smith #endif 17347cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE) 17357cd0ae37SLisandro Dalcin snes->stol = 1.e-5; 17367cd0ae37SLisandro Dalcin #else 1737c60f73f4SPeter Brune snes->stol = 1.e-8; 17387cd0ae37SLisandro Dalcin #endif 17393a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17403a2046daSBarry Smith snes->deltatol = 1.e-6; 17413a2046daSBarry Smith #else 17424b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 17433a2046daSBarry Smith #endif 1744e37c518bSBarry Smith snes->divtol = 1.e4; 1745e37c518bSBarry Smith snes->rnorm0 = 0; 17469b94acceSBarry Smith snes->nfuncs = 0; 174750ffb88aSMatthew Knepley snes->numFailures = 0; 174850ffb88aSMatthew Knepley snes->maxFailures = 1; 17497a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1750e35cf81dSBarry Smith snes->lagjacobian = 1; 175137ec4e1aSPeter Brune snes->jac_iter = 0; 175237ec4e1aSPeter Brune snes->lagjac_persist = PETSC_FALSE; 1753a8054027SBarry Smith snes->lagpreconditioner = 1; 175437ec4e1aSPeter Brune snes->pre_iter = 0; 175537ec4e1aSPeter Brune snes->lagpre_persist = PETSC_FALSE; 1756639f9d9dSBarry Smith snes->numbermonitors = 0; 1757c4421ceaSFande Kong snes->numberreasonviews = 0; 17589e5d0892SLisandro Dalcin snes->data = NULL; 17594dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1760186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 17616f24a144SLois Curfman McInnes snes->nwork = 0; 17629e5d0892SLisandro Dalcin snes->work = NULL; 176358c9b817SLisandro Dalcin snes->nvwork = 0; 17649e5d0892SLisandro Dalcin snes->vwork = NULL; 1765758f92a0SBarry Smith snes->conv_hist_len = 0; 1766758f92a0SBarry Smith snes->conv_hist_max = 0; 17670298fd71SBarry Smith snes->conv_hist = NULL; 17680298fd71SBarry Smith snes->conv_hist_its = NULL; 1769758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1770971e163fSPeter Brune snes->counters_reset = PETSC_TRUE; 1771e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1772184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 1773efd4aadfSBarry Smith snes->npcside = PC_RIGHT; 1774b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled = 0; 1775c40d0f55SPeter Brune 1776d8f46077SPeter Brune snes->mf = PETSC_FALSE; 1777d8f46077SPeter Brune snes->mf_operator = PETSC_FALSE; 1778d8f46077SPeter Brune snes->mf_version = 1; 1779d8f46077SPeter Brune 17803d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 17813d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 17823d4c4710SBarry Smith 1783349187a7SBarry Smith snes->vizerotolerance = 1.e-8; 178476bd3646SJed Brown snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE; 1785349187a7SBarry Smith 17864fc747eaSLawrence Mitchell /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */ 17874fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 17884fc747eaSLawrence Mitchell 17899b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 17904dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&kctx)); 1791f5af7f23SKarl Rupp 17929b94acceSBarry Smith snes->kspconvctx = (void *)kctx; 17939b94acceSBarry Smith kctx->version = 2; 17940f0abf79SStefano Zampini kctx->rtol_0 = 0.3; /* Eisenstat and Walker suggest rtol_0=.5, but 17959b94acceSBarry Smith this was too large for some test cases */ 179675567043SBarry Smith kctx->rtol_last = 0.0; 17970f0abf79SStefano Zampini kctx->rtol_max = 0.9; 17989b94acceSBarry Smith kctx->gamma = 1.0; 17990f0abf79SStefano Zampini kctx->alpha = 0.5 * (1.0 + PetscSqrtReal(5.0)); 180071f87433Sdalcinl kctx->alpha2 = kctx->alpha; 18010f0abf79SStefano Zampini kctx->threshold = 0.1; 180275567043SBarry Smith kctx->lresid_last = 0.0; 180375567043SBarry Smith kctx->norm_last = 0.0; 18049b94acceSBarry Smith 18050f0abf79SStefano Zampini kctx->rk_last = 0.0; 18060f0abf79SStefano Zampini kctx->rk_last_2 = 0.0; 18070f0abf79SStefano Zampini kctx->rtol_last_2 = 0.0; 18080f0abf79SStefano Zampini kctx->v4_p1 = 0.1; 18090f0abf79SStefano Zampini kctx->v4_p2 = 0.4; 18100f0abf79SStefano Zampini kctx->v4_p3 = 0.7; 18110f0abf79SStefano Zampini kctx->v4_m1 = 0.8; 18120f0abf79SStefano Zampini kctx->v4_m2 = 0.5; 18130f0abf79SStefano Zampini kctx->v4_m3 = 0.1; 18140f0abf79SStefano Zampini kctx->v4_m4 = 0.5; 18150f0abf79SStefano Zampini 18169b94acceSBarry Smith *outsnes = snes; 18173a40ed3dSBarry Smith PetscFunctionReturn(0); 18189b94acceSBarry Smith } 18199b94acceSBarry Smith 182088f0584fSBarry Smith /*MC 1821f6dfbefdSBarry Smith SNESFunction - Functional form used to convey the nonlinear function to `SNES` in `SNESSetFunction()` 182288f0584fSBarry Smith 182388f0584fSBarry Smith Synopsis: 1824411c0326SBarry Smith #include "petscsnes.h" 1825411c0326SBarry Smith PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx); 182688f0584fSBarry Smith 1827*c3339decSBarry Smith Collective 18281843f636SBarry Smith 182988f0584fSBarry Smith Input Parameters: 1830f6dfbefdSBarry Smith + snes - the `SNES` context 183188f0584fSBarry Smith . x - state at which to evaluate residual 1832f6dfbefdSBarry Smith - ctx - optional user-defined function context, passed in with `SNESSetFunction()` 183388f0584fSBarry Smith 183488f0584fSBarry Smith Output Parameter: 183588f0584fSBarry Smith . f - vector to put residual (function value) 183688f0584fSBarry Smith 1837878cb397SSatish Balay Level: intermediate 1838878cb397SSatish Balay 1839db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetFunction()` 184088f0584fSBarry Smith M*/ 184188f0584fSBarry Smith 18429b94acceSBarry Smith /*@C 18439b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 1844f6dfbefdSBarry Smith vector for use by the `SNES` routines in solving systems of nonlinear 18459b94acceSBarry Smith equations. 18469b94acceSBarry Smith 1847*c3339decSBarry Smith Logically Collective 1848fee21e36SBarry Smith 1849c7afd0dbSLois Curfman McInnes Input Parameters: 1850f6dfbefdSBarry Smith + snes - the `SNES` context 18516b7fb656SBarry Smith . r - vector to store function values, may be NULL 1852f6dfbefdSBarry Smith . f - function evaluation routine; see `SNESFunction` for calling sequence details 1853c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 18540298fd71SBarry Smith function evaluation routine (may be NULL) 18559b94acceSBarry Smith 185636851e7fSLois Curfman McInnes Level: beginner 185736851e7fSLois Curfman McInnes 1858f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetPicard()`, `SNESFunction` 18599b94acceSBarry Smith @*/ 1860d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunction(SNES snes, Vec r, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) 1861d71ae5a4SJacob Faibussowitsch { 18626cab3a1bSJed Brown DM dm; 18636cab3a1bSJed Brown 18643a40ed3dSBarry Smith PetscFunctionBegin; 18650700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1866d2a683ecSLisandro Dalcin if (r) { 1867d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r, VEC_CLASSID, 2); 1868d2a683ecSLisandro Dalcin PetscCheckSameComm(snes, 1, r, 2); 18699566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)r)); 18709566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_func)); 187185385478SLisandro Dalcin snes->vec_func = r; 1872d2a683ecSLisandro Dalcin } 18739566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 18749566063dSJacob Faibussowitsch PetscCall(DMSNESSetFunction(dm, f, ctx)); 187548a46eb9SPierre Jolivet if (f == SNESPicardComputeFunction) PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx)); 18763a40ed3dSBarry Smith PetscFunctionReturn(0); 18779b94acceSBarry Smith } 18789b94acceSBarry Smith 1879e4ed7901SPeter Brune /*@C 1880e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1881f6dfbefdSBarry Smith initial function value at the initialization of the method. In some 1882e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1883f6dfbefdSBarry Smith `SNESSolve()`. This function allows one to avoid a redundant call 1884f6dfbefdSBarry Smith to `SNESComputeFunction()` in that case. 1885e4ed7901SPeter Brune 1886*c3339decSBarry Smith Logically Collective 1887e4ed7901SPeter Brune 1888e4ed7901SPeter Brune Input Parameters: 1889f6dfbefdSBarry Smith + snes - the `SNES` context 1890e4ed7901SPeter Brune - f - vector to store function value 1891e4ed7901SPeter Brune 1892e4ed7901SPeter Brune Notes: 1893e4ed7901SPeter Brune This should not be modified during the solution procedure. 1894e4ed7901SPeter Brune 1895f6dfbefdSBarry Smith This is used extensively in the `SNESFAS` hierarchy and in nonlinear preconditioning. 1896e4ed7901SPeter Brune 1897e4ed7901SPeter Brune Level: developer 1898e4ed7901SPeter Brune 1899f6dfbefdSBarry Smith .seealso: `SNES`, `SNESFAS`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetInitialFunctionNorm()` 1900e4ed7901SPeter Brune @*/ 1901d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1902d71ae5a4SJacob Faibussowitsch { 1903e4ed7901SPeter Brune Vec vec_func; 1904e4ed7901SPeter Brune 1905e4ed7901SPeter Brune PetscFunctionBegin; 1906e4ed7901SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1907e4ed7901SPeter Brune PetscValidHeaderSpecific(f, VEC_CLASSID, 2); 1908e4ed7901SPeter Brune PetscCheckSameComm(snes, 1, f, 2); 1909efd4aadfSBarry Smith if (snes->npcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) { 1910902f982fSPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1911902f982fSPeter Brune PetscFunctionReturn(0); 1912902f982fSPeter Brune } 19139566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &vec_func, NULL, NULL)); 19149566063dSJacob Faibussowitsch PetscCall(VecCopy(f, vec_func)); 1915f5af7f23SKarl Rupp 1916217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1917e4ed7901SPeter Brune PetscFunctionReturn(0); 1918e4ed7901SPeter Brune } 1919e4ed7901SPeter Brune 1920534ebe21SPeter Brune /*@ 1921f6dfbefdSBarry Smith SNESSetNormSchedule - Sets the `SNESNormSchedule` used in convergence and monitoring 1922f6dfbefdSBarry Smith of the `SNES` method, when norms are computed in the solving process 1923534ebe21SPeter Brune 1924*c3339decSBarry Smith Logically Collective 1925534ebe21SPeter Brune 1926534ebe21SPeter Brune Input Parameters: 1927f6dfbefdSBarry Smith + snes - the `SNES` context 1928365a6726SPeter Brune - normschedule - the frequency of norm computation 1929534ebe21SPeter Brune 1930517f1916SMatthew G. Knepley Options Database Key: 193167b8a455SSatish Balay . -snes_norm_schedule <none, always, initialonly, finalonly, initialfinalonly> - set the schedule 1932517f1916SMatthew G. Knepley 1933534ebe21SPeter Brune Notes: 1934f6dfbefdSBarry Smith Only certain `SNES` methods support certain `SNESNormSchedules`. Most require evaluation 1935534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1936534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1937f6dfbefdSBarry Smith `SNESNGS` and the like do not require the norm of the function to be computed, and therefore 1938534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1939534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1940534ebe21SPeter Brune their solution. 1941534ebe21SPeter Brune 1942f6dfbefdSBarry Smith Level: advanced 1943534ebe21SPeter Brune 1944f6dfbefdSBarry Smith .seealso: `SNESNormSchedule`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1945534ebe21SPeter Brune @*/ 1946d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule) 1947d71ae5a4SJacob Faibussowitsch { 1948534ebe21SPeter Brune PetscFunctionBegin; 1949534ebe21SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1950365a6726SPeter Brune snes->normschedule = normschedule; 1951534ebe21SPeter Brune PetscFunctionReturn(0); 1952534ebe21SPeter Brune } 1953534ebe21SPeter Brune 1954534ebe21SPeter Brune /*@ 1955f6dfbefdSBarry Smith SNESGetNormSchedule - Gets the `SNESNormSchedule` used in convergence and monitoring 1956f6dfbefdSBarry Smith of the `SNES` method. 1957534ebe21SPeter Brune 1958*c3339decSBarry Smith Logically Collective 1959534ebe21SPeter Brune 1960534ebe21SPeter Brune Input Parameters: 1961f6dfbefdSBarry Smith + snes - the `SNES` context 1962365a6726SPeter Brune - normschedule - the type of the norm used 1963534ebe21SPeter Brune 1964534ebe21SPeter Brune Level: advanced 1965534ebe21SPeter Brune 1966f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1967534ebe21SPeter Brune @*/ 1968d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule) 1969d71ae5a4SJacob Faibussowitsch { 1970534ebe21SPeter Brune PetscFunctionBegin; 1971534ebe21SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1972365a6726SPeter Brune *normschedule = snes->normschedule; 1973534ebe21SPeter Brune PetscFunctionReturn(0); 1974534ebe21SPeter Brune } 1975534ebe21SPeter Brune 1976c5ce4427SMatthew G. Knepley /*@ 1977c5ce4427SMatthew G. Knepley SNESSetFunctionNorm - Sets the last computed residual norm. 1978c5ce4427SMatthew G. Knepley 1979*c3339decSBarry Smith Logically Collective 1980c5ce4427SMatthew G. Knepley 1981c5ce4427SMatthew G. Knepley Input Parameters: 1982f6dfbefdSBarry Smith + snes - the `SNES` context 1983f6dfbefdSBarry Smith - norm - the value of the norm 1984c5ce4427SMatthew G. Knepley 1985c5ce4427SMatthew G. Knepley Level: developer 1986c5ce4427SMatthew G. Knepley 1987f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1988c5ce4427SMatthew G. Knepley @*/ 1989d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm) 1990d71ae5a4SJacob Faibussowitsch { 1991c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1992c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1993c5ce4427SMatthew G. Knepley snes->norm = norm; 1994c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 1995c5ce4427SMatthew G. Knepley } 1996c5ce4427SMatthew G. Knepley 1997c5ce4427SMatthew G. Knepley /*@ 1998c5ce4427SMatthew G. Knepley SNESGetFunctionNorm - Gets the last computed norm of the residual 1999c5ce4427SMatthew G. Knepley 2000c5ce4427SMatthew G. Knepley Not Collective 2001c5ce4427SMatthew G. Knepley 2002c5ce4427SMatthew G. Knepley Input Parameter: 2003f6dfbefdSBarry Smith . snes - the `SNES` context 2004c5ce4427SMatthew G. Knepley 2005c5ce4427SMatthew G. Knepley Output Parameter: 2006c5ce4427SMatthew G. Knepley . norm - the last computed residual norm 2007c5ce4427SMatthew G. Knepley 2008c5ce4427SMatthew G. Knepley Level: developer 2009c5ce4427SMatthew G. Knepley 2010f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 2011c5ce4427SMatthew G. Knepley @*/ 2012d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm) 2013d71ae5a4SJacob Faibussowitsch { 2014c5ce4427SMatthew G. Knepley PetscFunctionBegin; 2015c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2016dadcf809SJacob Faibussowitsch PetscValidRealPointer(norm, 2); 2017c5ce4427SMatthew G. Knepley *norm = snes->norm; 2018c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 2019c5ce4427SMatthew G. Knepley } 2020c5ce4427SMatthew G. Knepley 2021c1e67a49SFande Kong /*@ 2022f6dfbefdSBarry Smith SNESGetUpdateNorm - Gets the last computed norm of the solution update 2023c1e67a49SFande Kong 2024c1e67a49SFande Kong Not Collective 2025c1e67a49SFande Kong 2026c1e67a49SFande Kong Input Parameter: 2027f6dfbefdSBarry Smith . snes - the `SNES` context 2028c1e67a49SFande Kong 2029c1e67a49SFande Kong Output Parameter: 2030c1e67a49SFande Kong . ynorm - the last computed update norm 2031c1e67a49SFande Kong 2032c1e67a49SFande Kong Level: developer 2033c1e67a49SFande Kong 2034f6dfbefdSBarry Smith Note: 2035f6dfbefdSBarry Smith The new solution is the current solution plus the update, so this norm is an indication of the size of the update 2036f6dfbefdSBarry Smith 2037f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()` 2038c1e67a49SFande Kong @*/ 2039d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetUpdateNorm(SNES snes, PetscReal *ynorm) 2040d71ae5a4SJacob Faibussowitsch { 2041c1e67a49SFande Kong PetscFunctionBegin; 2042c1e67a49SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2043dadcf809SJacob Faibussowitsch PetscValidRealPointer(ynorm, 2); 2044c1e67a49SFande Kong *ynorm = snes->ynorm; 2045c1e67a49SFande Kong PetscFunctionReturn(0); 2046c1e67a49SFande Kong } 2047c1e67a49SFande Kong 2048c1e67a49SFande Kong /*@ 20494591eaf2SFande Kong SNESGetSolutionNorm - Gets the last computed norm of the solution 2050c1e67a49SFande Kong 2051c1e67a49SFande Kong Not Collective 2052c1e67a49SFande Kong 2053c1e67a49SFande Kong Input Parameter: 2054f6dfbefdSBarry Smith . snes - the `SNES` context 2055c1e67a49SFande Kong 2056c1e67a49SFande Kong Output Parameter: 2057c1e67a49SFande Kong . xnorm - the last computed solution norm 2058c1e67a49SFande Kong 2059c1e67a49SFande Kong Level: developer 2060c1e67a49SFande Kong 2061f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()`, `SNESGetUpdateNorm()` 2062c1e67a49SFande Kong @*/ 2063d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolutionNorm(SNES snes, PetscReal *xnorm) 2064d71ae5a4SJacob Faibussowitsch { 2065c1e67a49SFande Kong PetscFunctionBegin; 2066c1e67a49SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2067dadcf809SJacob Faibussowitsch PetscValidRealPointer(xnorm, 2); 2068c1e67a49SFande Kong *xnorm = snes->xnorm; 2069c1e67a49SFande Kong PetscFunctionReturn(0); 2070c1e67a49SFande Kong } 2071c1e67a49SFande Kong 207247073ea2SPeter Brune /*@C 2073f6dfbefdSBarry Smith SNESSetFunctionType - Sets the `SNESFunctionType` 2074f6dfbefdSBarry Smith of the `SNES` method. 207547073ea2SPeter Brune 2076*c3339decSBarry Smith Logically Collective 207747073ea2SPeter Brune 207847073ea2SPeter Brune Input Parameters: 2079f6dfbefdSBarry Smith + snes - the `SNES` context 2080f6dfbefdSBarry Smith - type - the function type 208147073ea2SPeter Brune 208247073ea2SPeter Brune Level: developer 208347073ea2SPeter Brune 2084f6dfbefdSBarry Smith Notes: 2085f6dfbefdSBarry Smith Possible values of the function type 2086f6dfbefdSBarry Smith + `SNES_FUNCTION_DEFAULT` - the default for the given `SNESType` 2087f6dfbefdSBarry Smith . `SNES_FUNCTION_UNPRECONDITIONED` - an unpreconditioned function evaluation (this is the function provided with `SNESSetFunction()` 2088f6dfbefdSBarry Smith - `SNES_FUNCTION_PRECONDITIONED` - a transformation of the function provided with `SNESSetFunction()` 2089f6dfbefdSBarry Smith 2090f6dfbefdSBarry Smith Different `SNESType`s use this value in different ways 2091f6dfbefdSBarry Smith 2092f6dfbefdSBarry Smith .seealso: `SNES`, `SNESFunctionType`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 209347073ea2SPeter Brune @*/ 2094d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type) 2095d71ae5a4SJacob Faibussowitsch { 209647073ea2SPeter Brune PetscFunctionBegin; 209747073ea2SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 209847073ea2SPeter Brune snes->functype = type; 209947073ea2SPeter Brune PetscFunctionReturn(0); 210047073ea2SPeter Brune } 210147073ea2SPeter Brune 210247073ea2SPeter Brune /*@C 2103f6dfbefdSBarry Smith SNESGetFunctionType - Gets the `SNESFunctionType` used in convergence and monitoring set with `SNESSetFunctionType()` 210447073ea2SPeter Brune of the SNES method. 210547073ea2SPeter Brune 2106*c3339decSBarry Smith Logically Collective 210747073ea2SPeter Brune 210847073ea2SPeter Brune Input Parameters: 2109f6dfbefdSBarry Smith + snes - the `SNES` context 2110f6dfbefdSBarry Smith - type - the type of the function evaluation, see `SNESSetFunctionType()` 211147073ea2SPeter Brune 211247073ea2SPeter Brune Level: advanced 211347073ea2SPeter Brune 2114f6dfbefdSBarry Smith .seealso: `SNESSetFunctionType()`, `SNESFunctionType`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 211547073ea2SPeter Brune @*/ 2116d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type) 2117d71ae5a4SJacob Faibussowitsch { 211847073ea2SPeter Brune PetscFunctionBegin; 211947073ea2SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 212047073ea2SPeter Brune *type = snes->functype; 2121534ebe21SPeter Brune PetscFunctionReturn(0); 2122534ebe21SPeter Brune } 2123534ebe21SPeter Brune 2124bf388a1fSBarry Smith /*MC 2125f6dfbefdSBarry Smith SNESNGSFunction - function used to apply a Gauss-Seidel sweep on the nonlinear function 2126bf388a1fSBarry Smith 2127bf388a1fSBarry Smith Synopsis: 2128aaa7dc30SBarry Smith #include <petscsnes.h> 2129be95d8f1SBarry Smith $ SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx); 2130bf388a1fSBarry Smith 2131*c3339decSBarry Smith Collective 21321843f636SBarry Smith 21331843f636SBarry Smith Input Parameters: 2134bf388a1fSBarry Smith + X - solution vector 2135bf388a1fSBarry Smith . B - RHS vector 2136bf388a1fSBarry Smith - ctx - optional user-defined Gauss-Seidel context 2137bf388a1fSBarry Smith 21381843f636SBarry Smith Output Parameter: 21391843f636SBarry Smith . X - solution vector 21401843f636SBarry Smith 2141878cb397SSatish Balay Level: intermediate 2142878cb397SSatish Balay 2143f6dfbefdSBarry Smith .seealso: `SNESNGS`, `SNESSetNGS()`, `SNESGetNGS()` 2144bf388a1fSBarry Smith M*/ 2145bf388a1fSBarry Smith 2146c79ef259SPeter Brune /*@C 2147be95d8f1SBarry Smith SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for 2148c79ef259SPeter Brune use with composed nonlinear solvers. 2149c79ef259SPeter Brune 2150c79ef259SPeter Brune Input Parameters: 2151c79ef259SPeter Brune + snes - the SNES context 2152f6dfbefdSBarry Smith . f - function evaluation routine to apply Gauss-Seidel see `SNESNGSFunction` 2153c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 21540298fd71SBarry Smith smoother evaluation routine (may be NULL) 2155c79ef259SPeter Brune 2156f6dfbefdSBarry Smith Calling sequence of f: 2157f6dfbefdSBarry Smith $ PetscErrorCode f(SNES snes,Vec X,Vec B,void *ctx); 2158f6dfbefdSBarry Smith 2159f6dfbefdSBarry Smith Arguments of f: 2160f6dfbefdSBarry Smith + snes - the `SNES` context 2161f6dfbefdSBarry Smith . X - the current solution 2162f6dfbefdSBarry Smith . B - the right hand side vector (which may be NULL) 2163f6dfbefdSBarry Smith - ctx - a user provided context 2164f6dfbefdSBarry Smith 2165f6dfbefdSBarry Smith Note: 2166f6dfbefdSBarry Smith The `SNESNGS` routines are used by the composed nonlinear solver to generate 2167f6dfbefdSBarry Smith a problem appropriate update to the solution, particularly `SNESFAS`. 2168c79ef259SPeter Brune 2169d28543b3SPeter Brune Level: intermediate 2170c79ef259SPeter Brune 2171f6dfbefdSBarry Smith .seealso: `SNESGetNGS()`, `SNESNGSFunction`, `SNESNCG`, `SNESGetFunction()`, `SNESComputeNGS()` 2172c79ef259SPeter Brune @*/ 2173d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNGS(SNES snes, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) 2174d71ae5a4SJacob Faibussowitsch { 21756cab3a1bSJed Brown DM dm; 21766cab3a1bSJed Brown 2177646217ecSPeter Brune PetscFunctionBegin; 21786cab3a1bSJed Brown PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 21799566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21809566063dSJacob Faibussowitsch PetscCall(DMSNESSetNGS(dm, f, ctx)); 2181646217ecSPeter Brune PetscFunctionReturn(0); 2182646217ecSPeter Brune } 2183646217ecSPeter Brune 2184bbc1464cSBarry Smith /* 2185bbc1464cSBarry Smith This is used for -snes_mf_operator; it uses a duplicate of snes->jacobian_pre because snes->jacobian_pre cannot be 2186bbc1464cSBarry Smith changed during the KSPSolve() 2187bbc1464cSBarry Smith */ 2188d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeMFFunction(SNES snes, Vec x, Vec f, void *ctx) 2189d71ae5a4SJacob Faibussowitsch { 2190bbc1464cSBarry Smith DM dm; 2191bbc1464cSBarry Smith DMSNES sdm; 2192bbc1464cSBarry Smith 2193bbc1464cSBarry Smith PetscFunctionBegin; 21949566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21959566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 2196bbc1464cSBarry Smith /* A(x)*x - b(x) */ 2197bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 2198792fecdfSBarry Smith PetscCallBack("SNES Picard callback function", (*sdm->ops->computepfunction)(snes, x, f, sdm->pctx)); 21999566063dSJacob Faibussowitsch PetscCall(VecScale(f, -1.0)); 22000df40c35SBarry Smith /* Cannot share nonzero pattern because of the possible use of SNESComputeJacobianDefault() */ 2201ef1023bdSBarry Smith if (!snes->picard) PetscCall(MatDuplicate(snes->jacobian_pre, MAT_DO_NOT_COPY_VALUES, &snes->picard)); 2202792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx)); 22039566063dSJacob Faibussowitsch PetscCall(MatMultAdd(snes->picard, x, f, f)); 2204bbc1464cSBarry Smith } else { 2205792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx)); 22069566063dSJacob Faibussowitsch PetscCall(MatMult(snes->picard, x, f)); 2207bbc1464cSBarry Smith } 2208bbc1464cSBarry Smith PetscFunctionReturn(0); 2209bbc1464cSBarry Smith } 2210bbc1464cSBarry Smith 2211d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeFunction(SNES snes, Vec x, Vec f, void *ctx) 2212d71ae5a4SJacob Faibussowitsch { 2213e03ab78fSPeter Brune DM dm; 2214942e3340SBarry Smith DMSNES sdm; 22156cab3a1bSJed Brown 22168b0a5094SBarry Smith PetscFunctionBegin; 22179566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 22189566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 22198b0a5094SBarry Smith /* A(x)*x - b(x) */ 2220bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 2221792fecdfSBarry Smith PetscCallBack("SNES Picard callback function", (*sdm->ops->computepfunction)(snes, x, f, sdm->pctx)); 22229566063dSJacob Faibussowitsch PetscCall(VecScale(f, -1.0)); 2223792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx)); 22249566063dSJacob Faibussowitsch PetscCall(MatMultAdd(snes->jacobian_pre, x, f, f)); 2225bbc1464cSBarry Smith } else { 2226792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx)); 22279566063dSJacob Faibussowitsch PetscCall(MatMult(snes->jacobian_pre, x, f)); 2228bbc1464cSBarry Smith } 22298b0a5094SBarry Smith PetscFunctionReturn(0); 22308b0a5094SBarry Smith } 22318b0a5094SBarry Smith 2232d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeJacobian(SNES snes, Vec x1, Mat J, Mat B, void *ctx) 2233d71ae5a4SJacob Faibussowitsch { 22348b0a5094SBarry Smith PetscFunctionBegin; 2235e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 2236bbc1464cSBarry Smith /* must assembly if matrix-free to get the last SNES solution */ 22379566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY)); 22389566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY)); 22398b0a5094SBarry Smith PetscFunctionReturn(0); 22408b0a5094SBarry Smith } 22418b0a5094SBarry Smith 22428b0a5094SBarry Smith /*@C 2243f6dfbefdSBarry Smith SNESSetPicard - Use `SNES` to solve the system A(x) x = bp(x) + b via a Picard type iteration (Picard linearization) 22448b0a5094SBarry Smith 2245*c3339decSBarry Smith Logically Collective 22468b0a5094SBarry Smith 22478b0a5094SBarry Smith Input Parameters: 2248f6dfbefdSBarry Smith + snes - the `SNES` context 22496b7fb656SBarry Smith . r - vector to store function values, may be NULL 22506b7fb656SBarry Smith . bp - function evaluation routine, may be NULL 22516b7fb656SBarry Smith . Amat - matrix with which A(x) x - bp(x) - b is to be computed 2252e5d3d808SBarry Smith . Pmat - matrix from which preconditioner is computed (usually the same as Amat) 22536b7fb656SBarry Smith . J - function to compute matrix values, see SNESJacobianFunction() for details on its calling sequence 22546b7fb656SBarry Smith - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 22558b0a5094SBarry Smith 22568b0a5094SBarry Smith Notes: 22576b7fb656SBarry Smith It is often better to provide the nonlinear function F() and some approximation to its Jacobian directly and use 2258f450aa47SBarry 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. 2259f450aa47SBarry Smith 2260f6dfbefdSBarry Smith One can call `SNESSetPicard()` or `SNESSetFunction()` (and possibly `SNESSetJacobian()`) but cannot call both 22618b0a5094SBarry Smith 22626b7fb656SBarry 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} 22636b7fb656SBarry Smith $ Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = bp(x^{n}) + b iteration. 22648b0a5094SBarry Smith 22658b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 22668b0a5094SBarry Smith 22670d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 22686b7fb656SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = bp(x^n) + b 22698b0a5094SBarry Smith 22708b0a5094SBarry 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 22718b0a5094SBarry 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 22728b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 22738b0a5094SBarry Smith 2274f6dfbefdSBarry 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 2275f6dfbefdSBarry Smith A(x^{n}) is used to build the preconditioner 22766b7fb656SBarry Smith 22776b7fb656SBarry 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. 22786b7fb656SBarry Smith 22796b7fb656SBarry 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 22806b7fb656SBarry 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 2281f6dfbefdSBarry 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`. 22826b7fb656SBarry Smith See the commment in src/snes/tutorials/ex15.c. 2283bbc1464cSBarry Smith 2284f450aa47SBarry Smith Level: intermediate 22858b0a5094SBarry Smith 2286f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetFunction()`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESGetPicard()`, `SNESLineSearchPreCheckPicard()`, `SNESJacobianFunction` 22878b0a5094SBarry Smith @*/ 2288d71ae5a4SJacob 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) 2289d71ae5a4SJacob Faibussowitsch { 2290e03ab78fSPeter Brune DM dm; 2291e03ab78fSPeter Brune 22928b0a5094SBarry Smith PetscFunctionBegin; 22938b0a5094SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 22949566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 22959566063dSJacob Faibussowitsch PetscCall(DMSNESSetPicard(dm, bp, J, ctx)); 22969566063dSJacob Faibussowitsch PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx)); 22979566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes, r, SNESPicardComputeFunction, ctx)); 22989566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, Amat, Pmat, SNESPicardComputeJacobian, ctx)); 22998b0a5094SBarry Smith PetscFunctionReturn(0); 23008b0a5094SBarry Smith } 23018b0a5094SBarry Smith 23027971a8bfSPeter Brune /*@C 23037971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 23047971a8bfSPeter Brune 2305f6dfbefdSBarry Smith Not Collective, but `Vec` is parallel if `SNES` is parallel. Collective if `Vec` is requested, but has not been created yet. 23067971a8bfSPeter Brune 23077971a8bfSPeter Brune Input Parameter: 2308f6dfbefdSBarry Smith . snes - the `SNES` context 23097971a8bfSPeter Brune 2310d8d19677SJose E. Roman Output Parameters: 23110298fd71SBarry Smith + r - the function (or NULL) 2312f6dfbefdSBarry Smith . f - the function (or NULL); see `SNESFunction` for calling sequence details 2313e4357dc4SBarry Smith . Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL) 2314e4357dc4SBarry Smith . Pmat - the matrix from which the preconditioner will be constructed (or NULL) 2315f6dfbefdSBarry Smith . J - the function for matrix evaluation (or NULL); see `SNESJacobianFunction` for calling sequence details 23160298fd71SBarry Smith - ctx - the function context (or NULL) 23177971a8bfSPeter Brune 23187971a8bfSPeter Brune Level: advanced 23197971a8bfSPeter Brune 2320f6dfbefdSBarry Smith .seealso: `SNESSetFunction()`, `SNESSetPicard()`, `SNESGetFunction()`, `SNESGetJacobian()`, `SNESGetDM()`, `SNESFunction`, `SNESJacobianFunction` 23217971a8bfSPeter Brune @*/ 2322d71ae5a4SJacob 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) 2323d71ae5a4SJacob Faibussowitsch { 23247971a8bfSPeter Brune DM dm; 23257971a8bfSPeter Brune 23267971a8bfSPeter Brune PetscFunctionBegin; 23277971a8bfSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 23289566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, r, NULL, NULL)); 23299566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, Amat, Pmat, NULL, NULL)); 23309566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 23319566063dSJacob Faibussowitsch PetscCall(DMSNESGetPicard(dm, f, J, ctx)); 23327971a8bfSPeter Brune PetscFunctionReturn(0); 23337971a8bfSPeter Brune } 23347971a8bfSPeter Brune 2335d25893d9SBarry Smith /*@C 2336d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 2337d25893d9SBarry Smith 2338*c3339decSBarry Smith Logically Collective 2339d25893d9SBarry Smith 2340d25893d9SBarry Smith Input Parameters: 2341f6dfbefdSBarry Smith + snes - the `SNES` context 2342d25893d9SBarry Smith . func - function evaluation routine 2343d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 23440298fd71SBarry Smith function evaluation routine (may be NULL) 2345d25893d9SBarry Smith 2346d25893d9SBarry Smith Calling sequence of func: 2347d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 2348d25893d9SBarry Smith 2349d25893d9SBarry Smith . f - function vector 2350d25893d9SBarry Smith - ctx - optional user-defined function context 2351d25893d9SBarry Smith 2352d25893d9SBarry Smith Level: intermediate 2353d25893d9SBarry Smith 2354f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()` 2355d25893d9SBarry Smith @*/ 2356d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetComputeInitialGuess(SNES snes, PetscErrorCode (*func)(SNES, Vec, void *), void *ctx) 2357d71ae5a4SJacob Faibussowitsch { 2358d25893d9SBarry Smith PetscFunctionBegin; 2359d25893d9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2360d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 2361d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 2362d25893d9SBarry Smith PetscFunctionReturn(0); 2363d25893d9SBarry Smith } 2364d25893d9SBarry Smith 23651096aae1SMatthew Knepley /*@C 23661096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 23671096aae1SMatthew Knepley it assumes a zero right hand side. 23681096aae1SMatthew Knepley 2369*c3339decSBarry Smith Logically Collective 23701096aae1SMatthew Knepley 23711096aae1SMatthew Knepley Input Parameter: 2372f6dfbefdSBarry Smith . snes - the `SNES` context 23731096aae1SMatthew Knepley 23741096aae1SMatthew Knepley Output Parameter: 23750298fd71SBarry Smith . rhs - the right hand side vector or NULL if the right hand side vector is null 23761096aae1SMatthew Knepley 23771096aae1SMatthew Knepley Level: intermediate 23781096aae1SMatthew Knepley 2379f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetSolution()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetFunction()` 23801096aae1SMatthew Knepley @*/ 2381d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetRhs(SNES snes, Vec *rhs) 2382d71ae5a4SJacob Faibussowitsch { 23831096aae1SMatthew Knepley PetscFunctionBegin; 23840700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 23851096aae1SMatthew Knepley PetscValidPointer(rhs, 2); 238685385478SLisandro Dalcin *rhs = snes->vec_rhs; 23871096aae1SMatthew Knepley PetscFunctionReturn(0); 23881096aae1SMatthew Knepley } 23891096aae1SMatthew Knepley 23909b94acceSBarry Smith /*@ 2391f6dfbefdSBarry Smith SNESComputeFunction - Calls the function that has been set with `SNESSetFunction()`. 23929b94acceSBarry Smith 2393*c3339decSBarry Smith Collective 2394c7afd0dbSLois Curfman McInnes 23959b94acceSBarry Smith Input Parameters: 2396f6dfbefdSBarry Smith + snes - the `SNES` context 2397c7afd0dbSLois Curfman McInnes - x - input vector 23989b94acceSBarry Smith 23999b94acceSBarry Smith Output Parameter: 2400f6dfbefdSBarry Smith . y - function vector, as set by `SNESSetFunction()` 24019b94acceSBarry Smith 2402f6dfbefdSBarry Smith Note: 2403f6dfbefdSBarry Smith `SNESComputeFunction()` is typically used within nonlinear solvers 2404bbc1464cSBarry Smith implementations, so users would not generally call this routine themselves. 240536851e7fSLois Curfman McInnes 240636851e7fSLois Curfman McInnes Level: developer 240736851e7fSLois Curfman McInnes 2408f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeMFFunction()` 24099b94acceSBarry Smith @*/ 2410d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeFunction(SNES snes, Vec x, Vec y) 2411d71ae5a4SJacob Faibussowitsch { 24126cab3a1bSJed Brown DM dm; 2413942e3340SBarry Smith DMSNES sdm; 24149b94acceSBarry Smith 24153a40ed3dSBarry Smith PetscFunctionBegin; 24160700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 24170700a824SBarry Smith PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 24180700a824SBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2419c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, x, 2); 2420c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, y, 3); 2421e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE)); 2422184914b5SBarry Smith 24239566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 24249566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 242532f3f7c2SPeter Brune if (sdm->ops->computefunction) { 242648a46eb9SPierre Jolivet if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0)); 24279566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(x)); 24288ddeebeaSSteve Benbow /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 24298ddeebeaSSteve Benbow snes->domainerror = PETSC_FALSE; 2430800f99ffSJeremy L Thompson { 2431800f99ffSJeremy L Thompson void *ctx; 2432800f99ffSJeremy L Thompson PetscErrorCode (*computefunction)(SNES, Vec, Vec, void *); 2433800f99ffSJeremy L Thompson PetscCall(DMSNESGetFunction(dm, &computefunction, &ctx)); 2434800f99ffSJeremy L Thompson PetscCallBack("SNES callback function", (*computefunction)(snes, x, y, ctx)); 2435800f99ffSJeremy L Thompson } 24369566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(x)); 243748a46eb9SPierre Jolivet if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0)); 2438c90fad12SPeter Brune } else if (snes->vec_rhs) { 24399566063dSJacob Faibussowitsch PetscCall(MatMult(snes->jacobian, x, y)); 2440644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 24411baa6e33SBarry Smith if (snes->vec_rhs) PetscCall(VecAXPY(y, -1.0, snes->vec_rhs)); 2442ae3c334cSLois Curfman McInnes snes->nfuncs++; 2443422a814eSBarry Smith /* 2444422a814eSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2445422a814eSBarry Smith propagate the value to all processes 2446422a814eSBarry Smith */ 24471baa6e33SBarry Smith if (snes->domainerror) PetscCall(VecSetInf(y)); 24483a40ed3dSBarry Smith PetscFunctionReturn(0); 24499b94acceSBarry Smith } 24509b94acceSBarry Smith 2451c79ef259SPeter Brune /*@ 2452f6dfbefdSBarry Smith SNESComputeMFFunction - Calls the function that has been set with `SNESSetMFFunction()`. 2453bbc1464cSBarry Smith 2454*c3339decSBarry Smith Collective 2455bbc1464cSBarry Smith 2456bbc1464cSBarry Smith Input Parameters: 2457f6dfbefdSBarry Smith + snes - the `SNES` context 2458bbc1464cSBarry Smith - x - input vector 2459bbc1464cSBarry Smith 2460bbc1464cSBarry Smith Output Parameter: 2461f6dfbefdSBarry Smith . y - function vector, as set by `SNESSetMFFunction()` 2462bbc1464cSBarry Smith 2463bbc1464cSBarry Smith Notes: 2464f6dfbefdSBarry Smith `SNESComputeMFFunction()` is used within the matrix vector products called by the matrix created with `MatCreateSNESMF()` 2465bbc1464cSBarry Smith so users would not generally call this routine themselves. 2466bbc1464cSBarry Smith 2467f6dfbefdSBarry Smith Since this function is intended for use with finite differencing it does not subtract the right hand side vector provided with `SNESSolve()` 2468f6dfbefdSBarry Smith while `SNESComputeFunction()` does. As such, this routine cannot be used with `MatMFFDSetBase()` with a provided F function value even if it applies the 2469f6dfbefdSBarry 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. 2470bbc1464cSBarry Smith 2471bbc1464cSBarry Smith Level: developer 2472bbc1464cSBarry Smith 2473f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeFunction()`, `MatCreateSNESMF` 2474bbc1464cSBarry Smith @*/ 2475d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeMFFunction(SNES snes, Vec x, Vec y) 2476d71ae5a4SJacob Faibussowitsch { 2477bbc1464cSBarry Smith DM dm; 2478bbc1464cSBarry Smith DMSNES sdm; 2479bbc1464cSBarry Smith 2480bbc1464cSBarry Smith PetscFunctionBegin; 2481bbc1464cSBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2482bbc1464cSBarry Smith PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2483bbc1464cSBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2484bbc1464cSBarry Smith PetscCheckSameComm(snes, 1, x, 2); 2485bbc1464cSBarry Smith PetscCheckSameComm(snes, 1, y, 3); 2486e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE)); 2487bbc1464cSBarry Smith 24889566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 24899566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 24909566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0)); 24919566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(x)); 2492bbc1464cSBarry Smith /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 2493bbc1464cSBarry Smith snes->domainerror = PETSC_FALSE; 2494792fecdfSBarry Smith PetscCallBack("SNES callback function", (*sdm->ops->computemffunction)(snes, x, y, sdm->mffunctionctx)); 24959566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(x)); 24969566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0)); 2497bbc1464cSBarry Smith snes->nfuncs++; 2498bbc1464cSBarry Smith /* 2499bbc1464cSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2500bbc1464cSBarry Smith propagate the value to all processes 2501bbc1464cSBarry Smith */ 25021baa6e33SBarry Smith if (snes->domainerror) PetscCall(VecSetInf(y)); 2503bbc1464cSBarry Smith PetscFunctionReturn(0); 2504bbc1464cSBarry Smith } 2505bbc1464cSBarry Smith 2506bbc1464cSBarry Smith /*@ 2507f6dfbefdSBarry Smith SNESComputeNGS - Calls the Gauss-Seidel function that has been set with `SNESSetNGS()`. 2508c79ef259SPeter Brune 2509*c3339decSBarry Smith Collective 2510c79ef259SPeter Brune 2511c79ef259SPeter Brune Input Parameters: 2512f6dfbefdSBarry Smith + snes - the `SNES` context 2513c79ef259SPeter Brune . x - input vector 2514c79ef259SPeter Brune - b - rhs vector 2515c79ef259SPeter Brune 2516c79ef259SPeter Brune Output Parameter: 2517c79ef259SPeter Brune . x - new solution vector 2518c79ef259SPeter Brune 2519f6dfbefdSBarry Smith Note: 2520f6dfbefdSBarry Smith `SNESComputeNGS()` is typically used within composed nonlinear solver 2521c79ef259SPeter Brune implementations, so most users would not generally call this routine 2522c79ef259SPeter Brune themselves. 2523c79ef259SPeter Brune 2524c79ef259SPeter Brune Level: developer 2525c79ef259SPeter Brune 2526f6dfbefdSBarry Smith .seealso: `SNESNGS`, `SNESSetNGS()`, `SNESComputeFunction()` 2527c79ef259SPeter Brune @*/ 2528d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeNGS(SNES snes, Vec b, Vec x) 2529d71ae5a4SJacob Faibussowitsch { 25306cab3a1bSJed Brown DM dm; 2531942e3340SBarry Smith DMSNES sdm; 2532646217ecSPeter Brune 2533646217ecSPeter Brune PetscFunctionBegin; 2534646217ecSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2535064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 2536064a246eSJacob Faibussowitsch if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 2537064a246eSJacob Faibussowitsch PetscCheckSameComm(snes, 1, x, 3); 2538064a246eSJacob Faibussowitsch if (b) PetscCheckSameComm(snes, 1, b, 2); 2539e0f629ddSJacob Faibussowitsch if (b) PetscCall(VecValidValues_Internal(b, 2, PETSC_TRUE)); 25409566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_NGSEval, snes, x, b, 0)); 25419566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 25429566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 254322c6f798SBarry Smith if (sdm->ops->computegs) { 25449566063dSJacob Faibussowitsch if (b) PetscCall(VecLockReadPush(b)); 2545792fecdfSBarry Smith PetscCallBack("SNES callback NGS", (*sdm->ops->computegs)(snes, x, b, sdm->gsctx)); 25469566063dSJacob Faibussowitsch if (b) PetscCall(VecLockReadPop(b)); 2547be95d8f1SBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 25489566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_NGSEval, snes, x, b, 0)); 2549646217ecSPeter Brune PetscFunctionReturn(0); 2550646217ecSPeter Brune } 2551646217ecSPeter Brune 2552d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESTestJacobian(SNES snes) 2553d71ae5a4SJacob Faibussowitsch { 255412837594SBarry Smith Mat A, B, C, D, jacobian; 2555e885f1abSBarry Smith Vec x = snes->vec_sol, f = snes->vec_func; 2556e885f1abSBarry Smith PetscReal nrm, gnorm; 255781e7118cSBarry Smith PetscReal threshold = 1.e-5; 25580e276705SLisandro Dalcin MatType mattype; 2559e885f1abSBarry Smith PetscInt m, n, M, N; 2560e885f1abSBarry Smith void *functx; 25612cd624f9SStefano Zampini PetscBool complete_print = PETSC_FALSE, threshold_print = PETSC_FALSE, test = PETSC_FALSE, flg, istranspose; 25623325ff46SBarry Smith PetscViewer viewer, mviewer; 2563e885f1abSBarry Smith MPI_Comm comm; 2564e885f1abSBarry Smith PetscInt tabs; 256512837594SBarry Smith static PetscBool directionsprinted = PETSC_FALSE; 25663325ff46SBarry Smith PetscViewerFormat format; 2567e885f1abSBarry Smith 2568e885f1abSBarry Smith PetscFunctionBegin; 2569d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)snes); 25709566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-snes_test_jacobian", "Compare hand-coded and finite difference Jacobians", "None", &test)); 25719566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold, NULL)); 25729566063dSJacob Faibussowitsch PetscCall(PetscOptionsViewer("-snes_test_jacobian_view", "View difference between hand-coded and finite difference Jacobians element entries", "None", &mviewer, &format, &complete_print)); 257318d89885SKarl Rupp if (!complete_print) { 25749566063dSJacob Faibussowitsch PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display", "-snes_test_jacobian_view", "3.13", NULL)); 25759566063dSJacob Faibussowitsch PetscCall(PetscOptionsViewer("-snes_test_jacobian_display", "Display difference between hand-coded and finite difference Jacobians", "None", &mviewer, &format, &complete_print)); 257618d89885SKarl Rupp } 257718d89885SKarl Rupp /* for compatibility with PETSc 3.9 and older. */ 25789566063dSJacob Faibussowitsch PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display_threshold", "-snes_test_jacobian", "3.13", "-snes_test_jacobian accepts an optional threshold (since v3.10)")); 25799566063dSJacob 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)); 2580d0609cedSBarry Smith PetscOptionsEnd(); 2581e885f1abSBarry Smith if (!test) PetscFunctionReturn(0); 2582e885f1abSBarry Smith 25839566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)snes, &comm)); 25849566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(comm, &viewer)); 25859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tabs)); 25869566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel)); 25879566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Jacobian -------------\n")); 258812837594SBarry Smith if (!complete_print && !directionsprinted) { 25899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n")); 25909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " of hand-coded and finite difference Jacobian entries greater than <threshold>.\n")); 259112837594SBarry Smith } 259212837594SBarry Smith if (!directionsprinted) { 25939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n")); 25949566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " O(1.e-8), the hand-coded Jacobian is probably correct.\n")); 259512837594SBarry Smith directionsprinted = PETSC_TRUE; 2596e885f1abSBarry Smith } 25971baa6e33SBarry Smith if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format)); 2598e885f1abSBarry Smith 25999566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes->jacobian, MATMFFD, &flg)); 260012837594SBarry Smith if (!flg) jacobian = snes->jacobian; 260112837594SBarry Smith else jacobian = snes->jacobian_pre; 260212837594SBarry Smith 2603a82339d0SMatthew G. Knepley if (!x) { 26049566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(jacobian, &x, NULL)); 2605a82339d0SMatthew G. Knepley } else { 26069566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)x)); 2607a82339d0SMatthew G. Knepley } 2608a82339d0SMatthew G. Knepley if (!f) { 26099566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &f)); 2610a82339d0SMatthew G. Knepley } else { 26119566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)f)); 2612a82339d0SMatthew G. Knepley } 2613a82339d0SMatthew G. Knepley /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */ 26149566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, x, f)); 26159566063dSJacob Faibussowitsch PetscCall(VecDestroy(&f)); 26169566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESKSPTRANSPOSEONLY, &istranspose)); 261712837594SBarry Smith while (jacobian) { 26182cd624f9SStefano Zampini Mat JT = NULL, Jsave = NULL; 26192cd624f9SStefano Zampini 26202cd624f9SStefano Zampini if (istranspose) { 26219566063dSJacob Faibussowitsch PetscCall(MatCreateTranspose(jacobian, &JT)); 26222cd624f9SStefano Zampini Jsave = jacobian; 26232cd624f9SStefano Zampini jacobian = JT; 26242cd624f9SStefano Zampini } 26259566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)jacobian, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ, "")); 262612837594SBarry Smith if (flg) { 262712837594SBarry Smith A = jacobian; 26289566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 262912837594SBarry Smith } else { 26309566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(jacobian, MATAIJ, &A)); 263112837594SBarry Smith } 2632e885f1abSBarry Smith 26339566063dSJacob Faibussowitsch PetscCall(MatGetType(A, &mattype)); 26349566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &M, &N)); 26359566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, &n)); 26369566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 26379566063dSJacob Faibussowitsch PetscCall(MatSetType(B, mattype)); 26389566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, m, n, M, N)); 26399566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizesFromMats(B, A, A)); 26409566063dSJacob Faibussowitsch PetscCall(MatSetUp(B)); 26419566063dSJacob Faibussowitsch PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 2642e885f1abSBarry Smith 26439566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 26449566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobianDefault(snes, x, B, B, functx)); 264512837594SBarry Smith 26469566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &D)); 26479566063dSJacob Faibussowitsch PetscCall(MatAYPX(D, -1.0, A, DIFFERENT_NONZERO_PATTERN)); 26489566063dSJacob Faibussowitsch PetscCall(MatNorm(D, NORM_FROBENIUS, &nrm)); 26499566063dSJacob Faibussowitsch PetscCall(MatNorm(A, NORM_FROBENIUS, &gnorm)); 26509566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 265112837594SBarry Smith if (!gnorm) gnorm = 1; /* just in case */ 26529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n", (double)(nrm / gnorm), (double)nrm)); 265312837594SBarry Smith 2654e885f1abSBarry Smith if (complete_print) { 26559566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded Jacobian ----------\n")); 26569566063dSJacob Faibussowitsch PetscCall(MatView(A, mviewer)); 26579566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Finite difference Jacobian ----------\n")); 26589566063dSJacob Faibussowitsch PetscCall(MatView(B, mviewer)); 2659e885f1abSBarry Smith } 2660e885f1abSBarry Smith 2661df10fb39SFande Kong if (threshold_print || complete_print) { 2662e885f1abSBarry Smith PetscInt Istart, Iend, *ccols, bncols, cncols, j, row; 2663e885f1abSBarry Smith PetscScalar *cvals; 2664e885f1abSBarry Smith const PetscInt *bcols; 2665e885f1abSBarry Smith const PetscScalar *bvals; 2666e885f1abSBarry Smith 26679566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &C)); 26689566063dSJacob Faibussowitsch PetscCall(MatSetType(C, mattype)); 26699566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, M, N)); 26709566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizesFromMats(C, A, A)); 26719566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 26729566063dSJacob Faibussowitsch PetscCall(MatSetOption(C, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 26730e276705SLisandro Dalcin 26749566063dSJacob Faibussowitsch PetscCall(MatAYPX(B, -1.0, A, DIFFERENT_NONZERO_PATTERN)); 26759566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(B, &Istart, &Iend)); 2676e885f1abSBarry Smith 2677e885f1abSBarry Smith for (row = Istart; row < Iend; row++) { 26789566063dSJacob Faibussowitsch PetscCall(MatGetRow(B, row, &bncols, &bcols, &bvals)); 26799566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(bncols, &ccols, bncols, &cvals)); 2680e885f1abSBarry Smith for (j = 0, cncols = 0; j < bncols; j++) { 268123a52b1dSBarry Smith if (PetscAbsScalar(bvals[j]) > threshold) { 2682e885f1abSBarry Smith ccols[cncols] = bcols[j]; 2683e885f1abSBarry Smith cvals[cncols] = bvals[j]; 2684e885f1abSBarry Smith cncols += 1; 2685e885f1abSBarry Smith } 2686e885f1abSBarry Smith } 268748a46eb9SPierre Jolivet if (cncols) PetscCall(MatSetValues(C, 1, &row, cncols, ccols, cvals, INSERT_VALUES)); 26889566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(B, row, &bncols, &bcols, &bvals)); 26899566063dSJacob Faibussowitsch PetscCall(PetscFree2(ccols, cvals)); 2690e885f1abSBarry Smith } 26919566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY)); 26929566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY)); 26939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n", (double)threshold)); 26949566063dSJacob Faibussowitsch PetscCall(MatView(C, complete_print ? mviewer : viewer)); 26959566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2696e885f1abSBarry Smith } 26979566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 26989566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 26999566063dSJacob Faibussowitsch PetscCall(MatDestroy(&JT)); 27002cd624f9SStefano Zampini if (Jsave) jacobian = Jsave; 270112837594SBarry Smith if (jacobian != snes->jacobian_pre) { 270212837594SBarry Smith jacobian = snes->jacobian_pre; 27039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Jacobian for preconditioner -------------\n")); 27049371c9d4SSatish Balay } else jacobian = NULL; 270512837594SBarry Smith } 27069566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 27071baa6e33SBarry Smith if (complete_print) PetscCall(PetscViewerPopFormat(mviewer)); 27089566063dSJacob Faibussowitsch if (mviewer) PetscCall(PetscViewerDestroy(&mviewer)); 27099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tabs)); 2710e885f1abSBarry Smith PetscFunctionReturn(0); 2711e885f1abSBarry Smith } 2712e885f1abSBarry Smith 271362fef451SLois Curfman McInnes /*@ 2714f6dfbefdSBarry Smith SNESComputeJacobian - Computes the Jacobian matrix that has been set with `SNESSetJacobian()`. 271562fef451SLois Curfman McInnes 2716*c3339decSBarry Smith Collective 2717c7afd0dbSLois Curfman McInnes 271862fef451SLois Curfman McInnes Input Parameters: 2719f6dfbefdSBarry Smith + snes - the `SNES` context 2720c7afd0dbSLois Curfman McInnes - x - input vector 272162fef451SLois Curfman McInnes 272262fef451SLois Curfman McInnes Output Parameters: 2723c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 2724f6dfbefdSBarry Smith - B - optional matrix for building the preconditioner 2725fee21e36SBarry Smith 2726e35cf81dSBarry Smith Options Database Keys: 272767b8a455SSatish Balay + -snes_lag_preconditioner <lag> - how often to rebuild preconditioner 272867b8a455SSatish Balay . -snes_lag_jacobian <lag> - how often to rebuild Jacobian 2729455a5933SJed 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. 2730455a5933SJed 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 2731693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2732693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2733693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 27344c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 273594d6a431SBarry Smith . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2736a5b23f4aSJose E. Roman . -snes_compare_coloring_display - Compute the finite difference Jacobian using coloring and display verbose differences 2737c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2738c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2739c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2740a5b23f4aSJose E. Roman . -snes_compare_coloring_draw - Compute the finite difference Jacobian using coloring and draw differences 2741a5b23f4aSJose E. Roman - -snes_compare_coloring_draw_contour - Compute the finite difference Jacobian using coloring and show contours of matrices and differences 2742c01495d3SJed Brown 2743f6dfbefdSBarry Smith Note: 274462fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 274562fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 274662fef451SLois Curfman McInnes 2747f6dfbefdSBarry Smith Developer Note: 274895452b02SPatrick Sanan This has duplicative ways of checking the accuracy of the user provided Jacobian (see the options above). This is for historical reasons, the routine SNESTestJacobian() use to used 2749e885f1abSBarry Smith for with the SNESType of test that has been removed. 2750e885f1abSBarry Smith 275136851e7fSLois Curfman McInnes Level: developer 275236851e7fSLois Curfman McInnes 2753db781477SPatrick Sanan .seealso: `SNESSetJacobian()`, `KSPSetOperators()`, `MatStructure`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 275462fef451SLois Curfman McInnes @*/ 2755d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeJacobian(SNES snes, Vec X, Mat A, Mat B) 2756d71ae5a4SJacob Faibussowitsch { 2757ace3abfcSBarry Smith PetscBool flag; 27586cab3a1bSJed Brown DM dm; 2759942e3340SBarry Smith DMSNES sdm; 2760e0e3a89bSBarry Smith KSP ksp; 27613a40ed3dSBarry Smith 27623a40ed3dSBarry Smith PetscFunctionBegin; 27630700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 27640700a824SBarry Smith PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 2765c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, X, 2); 2766e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(X, 2, PETSC_TRUE)); 27679566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 27689566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 27693232da50SPeter Brune 2770ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2771fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2772fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2773f5af7f23SKarl Rupp 27749566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n")); 2775fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 27769566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is -1\n")); 27779566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag)); 2778ebd3b9afSBarry Smith if (flag) { 27799566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27809566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 2781ebd3b9afSBarry Smith } 2782e35cf81dSBarry Smith PetscFunctionReturn(0); 278337ec4e1aSPeter Brune } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 278463a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagjacobian, snes->iter)); 27859566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag)); 2786ebd3b9afSBarry Smith if (flag) { 27879566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27889566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 2789ebd3b9afSBarry Smith } 2790e35cf81dSBarry Smith PetscFunctionReturn(0); 2791e35cf81dSBarry Smith } 2792efd4aadfSBarry Smith if (snes->npc && snes->npcside == PC_LEFT) { 27939566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27949566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 2795d728fb7dSPeter Brune PetscFunctionReturn(0); 2796d728fb7dSPeter Brune } 2797e35cf81dSBarry Smith 27989566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_JacobianEval, snes, X, A, B)); 27999566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 2800800f99ffSJeremy L Thompson { 2801800f99ffSJeremy L Thompson void *ctx; 2802800f99ffSJeremy L Thompson PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *); 2803800f99ffSJeremy L Thompson PetscCall(DMSNESGetJacobian(dm, &J, &ctx)); 2804800f99ffSJeremy L Thompson PetscCallBack("SNES callback Jacobian", (*J)(snes, X, A, B, ctx)); 2805800f99ffSJeremy L Thompson } 28069566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 28079566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_JacobianEval, snes, X, A, B)); 280828d58a37SPierre Jolivet 280928d58a37SPierre Jolivet /* attach latest linearization point to the preconditioning matrix */ 28109566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)B, "__SNES_latest_X", (PetscObject)X)); 2811a8054027SBarry Smith 2812e0e3a89bSBarry Smith /* the next line ensures that snes->ksp exists */ 28139566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 28143b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 28159566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Rebuilding preconditioner exactly once since lag is -2\n")); 28169566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE)); 28173b4f5425SBarry Smith snes->lagpreconditioner = -1; 28183b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 28199566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is -1\n")); 28209566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE)); 282137ec4e1aSPeter Brune } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 282263a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagpreconditioner, snes->iter)); 28239566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE)); 2824d1e9a80fSBarry Smith } else { 28259566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Rebuilding preconditioner\n")); 28269566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE)); 2827a8054027SBarry Smith } 2828a8054027SBarry Smith 28299566063dSJacob Faibussowitsch PetscCall(SNESTestJacobian(snes)); 28306d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 283194ab13aaSBarry Smith /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 283294ab13aaSBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2833693365a8SJed Brown { 2834693365a8SJed Brown PetscBool flag = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_operator = PETSC_FALSE; 28359566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit", NULL, NULL, &flag)); 28369566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw", NULL, NULL, &flag_draw)); 28379566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw_contour", NULL, NULL, &flag_contour)); 28389566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_operator", NULL, NULL, &flag_operator)); 2839693365a8SJed Brown if (flag || flag_draw || flag_contour) { 28400298fd71SBarry Smith Mat Bexp_mine = NULL, Bexp, FDexp; 2841693365a8SJed Brown PetscViewer vdraw, vstdout; 28426b3a5b13SJed Brown PetscBool flg; 2843693365a8SJed Brown if (flag_operator) { 28449566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(A, MATAIJ, &Bexp_mine)); 2845693365a8SJed Brown Bexp = Bexp_mine; 2846693365a8SJed Brown } else { 2847693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 28489566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)B, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPIBAIJ, "")); 284994ab13aaSBarry Smith if (flg) Bexp = B; 2850693365a8SJed Brown else { 2851693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 28529566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(B, MATAIJ, &Bexp_mine)); 2853693365a8SJed Brown Bexp = Bexp_mine; 2854693365a8SJed Brown } 2855693365a8SJed Brown } 28569566063dSJacob Faibussowitsch PetscCall(MatConvert(Bexp, MATSAME, MAT_INITIAL_MATRIX, &FDexp)); 28579566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobianDefault(snes, X, FDexp, FDexp, NULL)); 28589566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout)); 2859693365a8SJed Brown if (flag_draw || flag_contour) { 28609566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Explicit Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw)); 28619566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 28620298fd71SBarry Smith } else vdraw = NULL; 28639566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit %s\n", flag_operator ? "Jacobian" : "preconditioning Jacobian")); 28649566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(Bexp, vstdout)); 28659566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(Bexp, vdraw)); 28669566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Finite difference Jacobian\n")); 28679566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(FDexp, vstdout)); 28689566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(FDexp, vdraw)); 28699566063dSJacob Faibussowitsch PetscCall(MatAYPX(FDexp, -1.0, Bexp, SAME_NONZERO_PATTERN)); 28709566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian\n")); 28719566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(FDexp, vstdout)); 2872693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 28739566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 28749566063dSJacob Faibussowitsch PetscCall(MatView(FDexp, vdraw)); 28759566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(vdraw)); 2876693365a8SJed Brown } 28779566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 28789566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&vdraw)); 28799566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bexp_mine)); 28809566063dSJacob Faibussowitsch PetscCall(MatDestroy(&FDexp)); 2881693365a8SJed Brown } 2882693365a8SJed Brown } 28834c30e9fbSJed Brown { 28846719d8e4SJed Brown PetscBool flag = PETSC_FALSE, flag_display = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_threshold = PETSC_FALSE; 28856719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON, threshold_rtol = 10 * PETSC_SQRT_MACHINE_EPSILON; 28869566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring", NULL, NULL, &flag)); 28879566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_display", NULL, NULL, &flag_display)); 28889566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw", NULL, NULL, &flag_draw)); 28899566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw_contour", NULL, NULL, &flag_contour)); 28909566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold", NULL, NULL, &flag_threshold)); 289127b0f280SBarry Smith if (flag_threshold) { 28929566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_rtol", &threshold_rtol, NULL)); 28939566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_atol", &threshold_atol, NULL)); 289427b0f280SBarry Smith } 28956719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 28964c30e9fbSJed Brown Mat Bfd; 28974c30e9fbSJed Brown PetscViewer vdraw, vstdout; 2898335efc43SPeter Brune MatColoring coloring; 28994c30e9fbSJed Brown ISColoring iscoloring; 29004c30e9fbSJed Brown MatFDColoring matfdcoloring; 29014c30e9fbSJed Brown PetscErrorCode (*func)(SNES, Vec, Vec, void *); 29024c30e9fbSJed Brown void *funcctx; 29036719d8e4SJed Brown PetscReal norm1, norm2, normmax; 29044c30e9fbSJed Brown 29059566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &Bfd)); 29069566063dSJacob Faibussowitsch PetscCall(MatColoringCreate(Bfd, &coloring)); 29079566063dSJacob Faibussowitsch PetscCall(MatColoringSetType(coloring, MATCOLORINGSL)); 29089566063dSJacob Faibussowitsch PetscCall(MatColoringSetFromOptions(coloring)); 29099566063dSJacob Faibussowitsch PetscCall(MatColoringApply(coloring, &iscoloring)); 29109566063dSJacob Faibussowitsch PetscCall(MatColoringDestroy(&coloring)); 29119566063dSJacob Faibussowitsch PetscCall(MatFDColoringCreate(Bfd, iscoloring, &matfdcoloring)); 29129566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 29139566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetUp(Bfd, iscoloring, matfdcoloring)); 29149566063dSJacob Faibussowitsch PetscCall(ISColoringDestroy(&iscoloring)); 29154c30e9fbSJed Brown 29164c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 29179566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, &func, &funcctx)); 29189566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFunction(matfdcoloring, (PetscErrorCode(*)(void))func, funcctx)); 29199566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring, ((PetscObject)snes)->prefix)); 29209566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring, "coloring_")); 29219566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 29229566063dSJacob Faibussowitsch PetscCall(MatFDColoringApply(Bfd, matfdcoloring, X, snes)); 29239566063dSJacob Faibussowitsch PetscCall(MatFDColoringDestroy(&matfdcoloring)); 29244c30e9fbSJed Brown 29259566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout)); 29264c30e9fbSJed Brown if (flag_draw || flag_contour) { 29279566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Colored Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw)); 29289566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 29290298fd71SBarry Smith } else vdraw = NULL; 29309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit preconditioning Jacobian\n")); 29319566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(B, vstdout)); 29329566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(B, vdraw)); 29339566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Colored Finite difference Jacobian\n")); 29349566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(Bfd, vstdout)); 29359566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(Bfd, vdraw)); 29369566063dSJacob Faibussowitsch PetscCall(MatAYPX(Bfd, -1.0, B, SAME_NONZERO_PATTERN)); 29379566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_1, &norm1)); 29389566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_FROBENIUS, &norm2)); 29399566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_MAX, &normmax)); 29409566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n", (double)norm1, (double)norm2, (double)normmax)); 29419566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(Bfd, vstdout)); 29424c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 29439566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 29449566063dSJacob Faibussowitsch PetscCall(MatView(Bfd, vdraw)); 29459566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(vdraw)); 29464c30e9fbSJed Brown } 29479566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 29486719d8e4SJed Brown 29496719d8e4SJed Brown if (flag_threshold) { 29506719d8e4SJed Brown PetscInt bs, rstart, rend, i; 29519566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(B, &bs)); 29529566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(B, &rstart, &rend)); 29536719d8e4SJed Brown for (i = rstart; i < rend; i++) { 29546719d8e4SJed Brown const PetscScalar *ba, *ca; 29556719d8e4SJed Brown const PetscInt *bj, *cj; 29566719d8e4SJed Brown PetscInt bn, cn, j, maxentrycol = -1, maxdiffcol = -1, maxrdiffcol = -1; 29576719d8e4SJed Brown PetscReal maxentry = 0, maxdiff = 0, maxrdiff = 0; 29589566063dSJacob Faibussowitsch PetscCall(MatGetRow(B, i, &bn, &bj, &ba)); 29599566063dSJacob Faibussowitsch PetscCall(MatGetRow(Bfd, i, &cn, &cj, &ca)); 29605f80ce2aSJacob Faibussowitsch PetscCheck(bn == cn, ((PetscObject)A)->comm, PETSC_ERR_PLIB, "Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 29616719d8e4SJed Brown for (j = 0; j < bn; j++) { 29626719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j])); 29636719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 29646719d8e4SJed Brown maxentrycol = bj[j]; 29656719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 29666719d8e4SJed Brown } 29676719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 29686719d8e4SJed Brown maxdiffcol = bj[j]; 29696719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 29706719d8e4SJed Brown } 29716719d8e4SJed Brown if (rdiff > maxrdiff) { 29726719d8e4SJed Brown maxrdiffcol = bj[j]; 29736719d8e4SJed Brown maxrdiff = rdiff; 29746719d8e4SJed Brown } 29756719d8e4SJed Brown } 29766719d8e4SJed Brown if (maxrdiff > 1) { 297763a3b9bcSJacob 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)); 29786719d8e4SJed Brown for (j = 0; j < bn; j++) { 29796719d8e4SJed Brown PetscReal rdiff; 29806719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j])); 298148a46eb9SPierre Jolivet if (rdiff > 1) PetscCall(PetscViewerASCIIPrintf(vstdout, " (%" PetscInt_FMT ",%g:%g)", bj[j], (double)PetscRealPart(ba[j]), (double)PetscRealPart(ca[j]))); 29826719d8e4SJed Brown } 298363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "\n")); 29846719d8e4SJed Brown } 29859566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(B, i, &bn, &bj, &ba)); 29869566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(Bfd, i, &cn, &cj, &ca)); 29876719d8e4SJed Brown } 29886719d8e4SJed Brown } 29899566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&vdraw)); 29909566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bfd)); 29914c30e9fbSJed Brown } 29924c30e9fbSJed Brown } 29933a40ed3dSBarry Smith PetscFunctionReturn(0); 29949b94acceSBarry Smith } 29959b94acceSBarry Smith 2996bf388a1fSBarry Smith /*MC 2997f6dfbefdSBarry Smith SNESJacobianFunction - Function used by `SNES` to compute the nonlinear Jacobian of the function to be solved by `SNES` 2998bf388a1fSBarry Smith 2999bf388a1fSBarry Smith Synopsis: 3000411c0326SBarry Smith #include "petscsnes.h" 3001411c0326SBarry Smith PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 3002bf388a1fSBarry Smith 3003*c3339decSBarry Smith Collective 30041843f636SBarry Smith 30051843f636SBarry Smith Input Parameters: 30061843f636SBarry Smith + x - input vector, the Jacobian is to be computed at this value 3007bf388a1fSBarry Smith - ctx - [optional] user-defined Jacobian context 3008bf388a1fSBarry Smith 30091843f636SBarry Smith Output Parameters: 30101843f636SBarry Smith + Amat - the matrix that defines the (approximate) Jacobian 30111843f636SBarry Smith - Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 30121843f636SBarry Smith 3013878cb397SSatish Balay Level: intermediate 3014878cb397SSatish Balay 3015f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESSetJacobian()`, `SNESGetJacobian()` 3016bf388a1fSBarry Smith M*/ 3017bf388a1fSBarry Smith 30189b94acceSBarry Smith /*@C 30199b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 3020044dda88SLois Curfman McInnes location to store the matrix. 30219b94acceSBarry Smith 3022*c3339decSBarry Smith Logically Collective 3023c7afd0dbSLois Curfman McInnes 30249b94acceSBarry Smith Input Parameters: 3025f6dfbefdSBarry Smith + snes - the `SNES` context 3026e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 3027e5d3d808SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 3028f6dfbefdSBarry Smith . J - Jacobian evaluation routine (if NULL then `SNES` retains any previously set value), see `SNESJacobianFunction` for details 3029c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 30300298fd71SBarry Smith Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value) 30319b94acceSBarry Smith 30329b94acceSBarry Smith Notes: 3033f6dfbefdSBarry Smith If the Amat matrix and Pmat matrix are different you must call `MatAssemblyBegin()`/`MatAssemblyEnd()` on 303416913363SBarry Smith each matrix. 303516913363SBarry Smith 3036f6dfbefdSBarry Smith If you know the operator Amat has a null space you can use `MatSetNullSpace()` and `MatSetTransposeNullSpace()` to supply the null 3037895c21f2SBarry Smith space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 3038895c21f2SBarry Smith 3039f6dfbefdSBarry Smith If using `SNESComputeJacobianDefaultColor()` to assemble a Jacobian, the ctx argument 3040f6dfbefdSBarry Smith must be a `MatFDColoring`. 3041a8a26c1eSJed Brown 3042c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 3043f6dfbefdSBarry Smith example is to use the "Picard linearization" which only differentiates through the highest order parts of each term using `SNESSetPicard()` 3044c3cc8fd1SJed Brown 304536851e7fSLois Curfman McInnes Level: beginner 304636851e7fSLois Curfman McInnes 3047f6dfbefdSBarry Smith .seealso: `SNES`, `KSPSetOperators()`, `SNESSetFunction()`, `MatMFFDComputeJacobian()`, `SNESComputeJacobianDefaultColor()`, `MatStructure`, `J`, 3048db781477SPatrick Sanan `SNESSetPicard()`, `SNESJacobianFunction` 30499b94acceSBarry Smith @*/ 3050d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetJacobian(SNES snes, Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx) 3051d71ae5a4SJacob Faibussowitsch { 30526cab3a1bSJed Brown DM dm; 30533a7fca6bSBarry Smith 30543a40ed3dSBarry Smith PetscFunctionBegin; 30550700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3056e5d3d808SBarry Smith if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2); 3057e5d3d808SBarry Smith if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3); 3058e5d3d808SBarry Smith if (Amat) PetscCheckSameComm(snes, 1, Amat, 2); 3059e5d3d808SBarry Smith if (Pmat) PetscCheckSameComm(snes, 1, Pmat, 3); 30609566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 30619566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, J, ctx)); 3062e5d3d808SBarry Smith if (Amat) { 30639566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Amat)); 30649566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian)); 3065f5af7f23SKarl Rupp 3066e5d3d808SBarry Smith snes->jacobian = Amat; 30673a7fca6bSBarry Smith } 3068e5d3d808SBarry Smith if (Pmat) { 30699566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Pmat)); 30709566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian_pre)); 3071f5af7f23SKarl Rupp 3072e5d3d808SBarry Smith snes->jacobian_pre = Pmat; 30733a7fca6bSBarry Smith } 30743a40ed3dSBarry Smith PetscFunctionReturn(0); 30759b94acceSBarry Smith } 307662fef451SLois Curfman McInnes 3077c2aafc4cSSatish Balay /*@C 3078b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 3079b4fd4287SBarry Smith provided context for evaluating the Jacobian. 3080b4fd4287SBarry Smith 3081f6dfbefdSBarry Smith Not Collective, but `Mat` object will be parallel if `SNES` object is 3082c7afd0dbSLois Curfman McInnes 3083b4fd4287SBarry Smith Input Parameter: 3084b4fd4287SBarry Smith . snes - the nonlinear solver context 3085b4fd4287SBarry Smith 3086b4fd4287SBarry Smith Output Parameters: 3087e5d3d808SBarry Smith + Amat - location to stash (approximate) Jacobian matrix (or NULL) 3088e5d3d808SBarry Smith . Pmat - location to stash matrix used to compute the preconditioner (or NULL) 3089411c0326SBarry Smith . J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence 30900298fd71SBarry Smith - ctx - location to stash Jacobian ctx (or NULL) 3091fee21e36SBarry Smith 309236851e7fSLois Curfman McInnes Level: advanced 309336851e7fSLois Curfman McInnes 3094f6dfbefdSBarry Smith .seealso: `SNES`, `Mat`, `SNESSetJacobian()`, `SNESComputeJacobian()`, `SNESJacobianFunction`, `SNESGetFunction()` 3095b4fd4287SBarry Smith @*/ 3096d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetJacobian(SNES snes, Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES, Vec, Mat, Mat, void *), void **ctx) 3097d71ae5a4SJacob Faibussowitsch { 30986cab3a1bSJed Brown DM dm; 30996cab3a1bSJed Brown 31003a40ed3dSBarry Smith PetscFunctionBegin; 31010700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3102e5d3d808SBarry Smith if (Amat) *Amat = snes->jacobian; 3103e5d3d808SBarry Smith if (Pmat) *Pmat = snes->jacobian_pre; 31049566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 3105800f99ffSJeremy L Thompson PetscCall(DMSNESGetJacobian(dm, J, ctx)); 31063a40ed3dSBarry Smith PetscFunctionReturn(0); 3107b4fd4287SBarry Smith } 3108b4fd4287SBarry Smith 3109d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes) 3110d71ae5a4SJacob Faibussowitsch { 311158b371f3SBarry Smith DM dm; 311258b371f3SBarry Smith DMSNES sdm; 311358b371f3SBarry Smith 311458b371f3SBarry Smith PetscFunctionBegin; 31159566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31169566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 311758b371f3SBarry Smith if (!sdm->ops->computejacobian && snes->jacobian_pre) { 311858b371f3SBarry Smith DM dm; 311958b371f3SBarry Smith PetscBool isdense, ismf; 312058b371f3SBarry Smith 31219566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31229566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &isdense, MATSEQDENSE, MATMPIDENSE, MATDENSE, NULL)); 31239566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &ismf, MATMFFD, MATSHELL, NULL)); 312458b371f3SBarry Smith if (isdense) { 31259566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefault, NULL)); 312658b371f3SBarry Smith } else if (!ismf) { 31279566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefaultColor, NULL)); 312858b371f3SBarry Smith } 312958b371f3SBarry Smith } 313058b371f3SBarry Smith PetscFunctionReturn(0); 313158b371f3SBarry Smith } 313258b371f3SBarry Smith 31339b94acceSBarry Smith /*@ 31349b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 3135272ac6f2SLois Curfman McInnes of a nonlinear solver. 31369b94acceSBarry Smith 3137*c3339decSBarry Smith Collective 3138fee21e36SBarry Smith 3139c7afd0dbSLois Curfman McInnes Input Parameters: 3140f6dfbefdSBarry Smith . snes - the `SNES` context 3141c7afd0dbSLois Curfman McInnes 3142f6dfbefdSBarry Smith Note: 3143f6dfbefdSBarry Smith For basic use of the `SNES` solvers the user need not explicitly call 3144f6dfbefdSBarry Smith `SNESSetUp()`, since these actions will automatically occur during 3145f6dfbefdSBarry Smith the call to `SNESSolve()`. However, if one wishes to control this 3146f6dfbefdSBarry Smith phase separately, `SNESSetUp()` should be called after `SNESCreate()` 3147f6dfbefdSBarry Smith and optional routines of the form SNESSetXXX(), but before `SNESSolve()`. 3148272ac6f2SLois Curfman McInnes 314936851e7fSLois Curfman McInnes Level: advanced 315036851e7fSLois Curfman McInnes 3151f6dfbefdSBarry Smith .seealso: `SNES`, `SNESCreate()`, `SNESSolve()`, `SNESDestroy()` 31529b94acceSBarry Smith @*/ 3153d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUp(SNES snes) 3154d71ae5a4SJacob Faibussowitsch { 31556cab3a1bSJed Brown DM dm; 3156942e3340SBarry Smith DMSNES sdm; 3157c35f09e5SBarry Smith SNESLineSearch linesearch, pclinesearch; 31586e2a1849SPeter Brune void *lsprectx, *lspostctx; 31596b2b7091SBarry Smith PetscErrorCode (*precheck)(SNESLineSearch, Vec, Vec, PetscBool *, void *); 31606b2b7091SBarry Smith PetscErrorCode (*postcheck)(SNESLineSearch, Vec, Vec, Vec, PetscBool *, PetscBool *, void *); 31616e2a1849SPeter Brune PetscErrorCode (*func)(SNES, Vec, Vec, void *); 31626e2a1849SPeter Brune Vec f, fpc; 31636e2a1849SPeter Brune void *funcctx; 3164d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *); 31651eb13d49SPeter Brune void *jacctx, *appctx; 316632b97717SPeter Brune Mat j, jpre; 31673a40ed3dSBarry Smith 31683a40ed3dSBarry Smith PetscFunctionBegin; 31690700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 31704dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 31719566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_Setup, snes, 0, 0, 0)); 31729b94acceSBarry Smith 317348a46eb9SPierre Jolivet if (!((PetscObject)snes)->type_name) PetscCall(SNESSetType(snes, SNESNEWTONLS)); 317485385478SLisandro Dalcin 31759566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &snes->vec_func, NULL, NULL)); 317658c9b817SLisandro Dalcin 31779566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31789566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 31799566063dSJacob Faibussowitsch PetscCall(SNESSetDefaultComputeJacobian(snes)); 318058b371f3SBarry Smith 318148a46eb9SPierre Jolivet if (!snes->vec_func) PetscCall(DMCreateGlobalVector(dm, &snes->vec_func)); 3182efd51863SBarry Smith 318348a46eb9SPierre Jolivet if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 3184b710008aSBarry Smith 3185d8d34be6SBarry Smith if (snes->linesearch) { 31869566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 31879566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFunction(snes->linesearch, SNESComputeFunction)); 3188d8d34be6SBarry Smith } 31899e764e56SPeter Brune 3190b552625fSStefano Zampini if (snes->npc && snes->npcside == PC_LEFT) { 3191172a4300SPeter Brune snes->mf = PETSC_TRUE; 3192172a4300SPeter Brune snes->mf_operator = PETSC_FALSE; 3193172a4300SPeter Brune } 3194d8f46077SPeter Brune 3195efd4aadfSBarry Smith if (snes->npc) { 31966e2a1849SPeter Brune /* copy the DM over */ 31979566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31989566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes->npc, dm)); 31996e2a1849SPeter Brune 32009566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &f, &func, &funcctx)); 32019566063dSJacob Faibussowitsch PetscCall(VecDuplicate(f, &fpc)); 32029566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes->npc, fpc, func, funcctx)); 32039566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, &j, &jpre, &jac, &jacctx)); 32049566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes->npc, j, jpre, jac, jacctx)); 32059566063dSJacob Faibussowitsch PetscCall(SNESGetApplicationContext(snes, &appctx)); 32069566063dSJacob Faibussowitsch PetscCall(SNESSetApplicationContext(snes->npc, appctx)); 32079566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fpc)); 32086e2a1849SPeter Brune 32096e2a1849SPeter Brune /* copy the function pointers over */ 32109566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)snes->npc)); 32116e2a1849SPeter Brune 32126e2a1849SPeter Brune /* default to 1 iteration */ 32139566063dSJacob Faibussowitsch PetscCall(SNESSetTolerances(snes->npc, 0.0, 0.0, 0.0, 1, snes->npc->max_funcs)); 3214efd4aadfSBarry Smith if (snes->npcside == PC_RIGHT) { 32159566063dSJacob Faibussowitsch PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_FINAL_ONLY)); 3216a9936a0cSPeter Brune } else { 32179566063dSJacob Faibussowitsch PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_NONE)); 3218a9936a0cSPeter Brune } 32199566063dSJacob Faibussowitsch PetscCall(SNESSetFromOptions(snes->npc)); 32206e2a1849SPeter Brune 32216e2a1849SPeter Brune /* copy the line search context over */ 3222d8d34be6SBarry Smith if (snes->linesearch && snes->npc->linesearch) { 32239566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 32249566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes->npc, &pclinesearch)); 32259566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetPreCheck(linesearch, &precheck, &lsprectx)); 32269566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetPostCheck(linesearch, &postcheck, &lspostctx)); 32279566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetPreCheck(pclinesearch, precheck, lsprectx)); 32289566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetPostCheck(pclinesearch, postcheck, lspostctx)); 32299566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch)); 32306e2a1849SPeter Brune } 3231d8d34be6SBarry Smith } 32321baa6e33SBarry Smith if (snes->mf) PetscCall(SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version)); 323348a46eb9SPierre Jolivet if (snes->ops->usercompute && !snes->user) PetscCall((*snes->ops->usercompute)(snes, (void **)&snes->user)); 32346e2a1849SPeter Brune 323537ec4e1aSPeter Brune snes->jac_iter = 0; 323637ec4e1aSPeter Brune snes->pre_iter = 0; 323737ec4e1aSPeter Brune 3238dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, setup); 323958c9b817SLisandro Dalcin 32409566063dSJacob Faibussowitsch PetscCall(SNESSetDefaultComputeJacobian(snes)); 324158b371f3SBarry Smith 3242b552625fSStefano Zampini if (snes->npc && snes->npcside == PC_LEFT) { 32436c67d002SPeter Brune if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 3244d8d34be6SBarry Smith if (snes->linesearch) { 32459566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 32469566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFunction(linesearch, SNESComputeFunctionDefaultNPC)); 32476c67d002SPeter Brune } 32486c67d002SPeter Brune } 3249d8d34be6SBarry Smith } 32509566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_Setup, snes, 0, 0, 0)); 32517aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 32523a40ed3dSBarry Smith PetscFunctionReturn(0); 32539b94acceSBarry Smith } 32549b94acceSBarry Smith 325537596af1SLisandro Dalcin /*@ 3256f6dfbefdSBarry Smith SNESReset - Resets a `SNES` context to the snessetupcalled = 0 state and removes any allocated `Vec`s and `Mat`s 325737596af1SLisandro Dalcin 3258*c3339decSBarry Smith Collective 325937596af1SLisandro Dalcin 326037596af1SLisandro Dalcin Input Parameter: 3261f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 326237596af1SLisandro Dalcin 3263d25893d9SBarry Smith Level: intermediate 3264d25893d9SBarry Smith 326595452b02SPatrick Sanan Notes: 3266f6dfbefdSBarry Smith Call this if you wish to reuse a `SNES` but with different size vectors 326737596af1SLisandro Dalcin 3268f6dfbefdSBarry Smith Also calls the application context destroy routine set with `SNESSetComputeApplicationContext()` 3269f6dfbefdSBarry Smith 3270f6dfbefdSBarry Smith .seealso: `SNES`, `SNESDestroy()`, `SNESCreate()`, `SNESSetUp()`, `SNESSolve()` 327137596af1SLisandro Dalcin @*/ 3272d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESReset(SNES snes) 3273d71ae5a4SJacob Faibussowitsch { 327437596af1SLisandro Dalcin PetscFunctionBegin; 327537596af1SLisandro Dalcin PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3276d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 32779566063dSJacob Faibussowitsch PetscCall((*snes->ops->userdestroy)((void **)&snes->user)); 32780298fd71SBarry Smith snes->user = NULL; 3279d25893d9SBarry Smith } 32801baa6e33SBarry Smith if (snes->npc) PetscCall(SNESReset(snes->npc)); 32818a23116dSBarry Smith 3282dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, reset); 32831baa6e33SBarry Smith if (snes->ksp) PetscCall(KSPReset(snes->ksp)); 32849e764e56SPeter Brune 32851baa6e33SBarry Smith if (snes->linesearch) PetscCall(SNESLineSearchReset(snes->linesearch)); 32869e764e56SPeter Brune 32879566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_rhs)); 32889566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 32899566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol_update)); 32909566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_func)); 32919566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian)); 32929566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian_pre)); 32939566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->picard)); 32949566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(snes->nwork, &snes->work)); 32959566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(snes->nvwork, &snes->vwork)); 3296f5af7f23SKarl Rupp 329740fdac6aSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 329840fdac6aSLawrence Mitchell 329937596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 330037596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 330137596af1SLisandro Dalcin PetscFunctionReturn(0); 330237596af1SLisandro Dalcin } 330337596af1SLisandro Dalcin 330452baeb72SSatish Balay /*@ 3305f6dfbefdSBarry Smith SNESConvergedReasonViewCancel - Clears all the reason view functions for a `SNES` object. 3306c4421ceaSFande Kong 3307*c3339decSBarry Smith Collective 3308c4421ceaSFande Kong 3309c4421ceaSFande Kong Input Parameter: 3310f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 3311c4421ceaSFande Kong 3312c4421ceaSFande Kong Level: intermediate 3313c4421ceaSFande Kong 3314f6dfbefdSBarry Smith .seealso: `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESReset()` 3315c4421ceaSFande Kong @*/ 3316d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewCancel(SNES snes) 3317d71ae5a4SJacob Faibussowitsch { 3318c4421ceaSFande Kong PetscInt i; 3319c4421ceaSFande Kong 3320c4421ceaSFande Kong PetscFunctionBegin; 3321c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3322c4421ceaSFande Kong for (i = 0; i < snes->numberreasonviews; i++) { 332348a46eb9SPierre Jolivet if (snes->reasonviewdestroy[i]) PetscCall((*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i])); 3324c4421ceaSFande Kong } 3325c4421ceaSFande Kong snes->numberreasonviews = 0; 3326c4421ceaSFande Kong PetscFunctionReturn(0); 3327c4421ceaSFande Kong } 3328c4421ceaSFande Kong 33291fb7b255SJunchao Zhang /*@C 33309b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 3331f6dfbefdSBarry Smith with `SNESCreate()`. 33329b94acceSBarry Smith 3333*c3339decSBarry Smith Collective 3334c7afd0dbSLois Curfman McInnes 33359b94acceSBarry Smith Input Parameter: 3336f6dfbefdSBarry Smith . snes - the `SNES` context 33379b94acceSBarry Smith 333836851e7fSLois Curfman McInnes Level: beginner 333936851e7fSLois Curfman McInnes 3340f6dfbefdSBarry Smith .seealso: `SNES`, `SNESCreate()`, `SNESSolve()` 33419b94acceSBarry Smith @*/ 3342d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESDestroy(SNES *snes) 3343d71ae5a4SJacob Faibussowitsch { 33443a40ed3dSBarry Smith PetscFunctionBegin; 33456bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 33466bf464f9SBarry Smith PetscValidHeaderSpecific((*snes), SNES_CLASSID, 1); 33479371c9d4SSatish Balay if (--((PetscObject)(*snes))->refct > 0) { 33489371c9d4SSatish Balay *snes = NULL; 33499371c9d4SSatish Balay PetscFunctionReturn(0); 33509371c9d4SSatish Balay } 3351d4bb536fSBarry Smith 33529566063dSJacob Faibussowitsch PetscCall(SNESReset((*snes))); 33539566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&(*snes)->npc)); 33546b8b9a38SLisandro Dalcin 3355e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 33569566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsViewOff((PetscObject)*snes)); 3357dbbe0bcdSBarry Smith PetscTryTypeMethod((*snes), destroy); 33586d4c513bSLisandro Dalcin 33599566063dSJacob Faibussowitsch if ((*snes)->dm) PetscCall(DMCoarsenHookRemove((*snes)->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, *snes)); 33609566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*snes)->dm)); 33619566063dSJacob Faibussowitsch PetscCall(KSPDestroy(&(*snes)->ksp)); 33629566063dSJacob Faibussowitsch PetscCall(SNESLineSearchDestroy(&(*snes)->linesearch)); 33636b8b9a38SLisandro Dalcin 33649566063dSJacob Faibussowitsch PetscCall(PetscFree((*snes)->kspconvctx)); 336548a46eb9SPierre Jolivet if ((*snes)->ops->convergeddestroy) PetscCall((*(*snes)->ops->convergeddestroy)((*snes)->cnvP)); 336648a46eb9SPierre Jolivet if ((*snes)->conv_hist_alloc) PetscCall(PetscFree2((*snes)->conv_hist, (*snes)->conv_hist_its)); 33679566063dSJacob Faibussowitsch PetscCall(SNESMonitorCancel((*snes))); 33689566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonViewCancel((*snes))); 33699566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(snes)); 33703a40ed3dSBarry Smith PetscFunctionReturn(0); 33719b94acceSBarry Smith } 33729b94acceSBarry Smith 33739b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 33749b94acceSBarry Smith 3375a8054027SBarry Smith /*@ 3376a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 3377a8054027SBarry Smith 3378*c3339decSBarry Smith Logically Collective 3379a8054027SBarry Smith 3380a8054027SBarry Smith Input Parameters: 3381f6dfbefdSBarry Smith + snes - the `SNES` context 3382d8e291bfSBarry Smith - lag - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 33833b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3384a8054027SBarry Smith 3385a8054027SBarry Smith Options Database Keys: 33863d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 33873d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 33883d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 33893d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3390a8054027SBarry Smith 3391a8054027SBarry Smith Notes: 3392a8054027SBarry Smith The default is 1 3393f6dfbefdSBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagPreconditionerPersists()` was called 3394d8e291bfSBarry Smith 3395f6dfbefdSBarry Smith `SNESSetLagPreconditionerPersists()` allows using the same uniform lagging (for example every second linear solve) across multiple nonlinear solves. 3396a8054027SBarry Smith 3397a8054027SBarry Smith Level: intermediate 3398a8054027SBarry Smith 3399db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetLagPreconditionerPersists()`, 3400f6dfbefdSBarry Smith `SNESSetLagJacobianPersists()`, `SNES`, `SNESSolve()` 3401a8054027SBarry Smith @*/ 3402d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagPreconditioner(SNES snes, PetscInt lag) 3403d71ae5a4SJacob Faibussowitsch { 3404a8054027SBarry Smith PetscFunctionBegin; 34050700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 34065f80ce2aSJacob Faibussowitsch PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater"); 34075f80ce2aSJacob Faibussowitsch PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0"); 3408c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, lag, 2); 3409a8054027SBarry Smith snes->lagpreconditioner = lag; 3410a8054027SBarry Smith PetscFunctionReturn(0); 3411a8054027SBarry Smith } 3412a8054027SBarry Smith 3413efd51863SBarry Smith /*@ 3414f6dfbefdSBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that `SNES` will do 3415efd51863SBarry Smith 3416*c3339decSBarry Smith Logically Collective 3417efd51863SBarry Smith 3418efd51863SBarry Smith Input Parameters: 3419f6dfbefdSBarry Smith + snes - the `SNES` context 3420efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 3421efd51863SBarry Smith 3422f6dfbefdSBarry Smith Options Database Key: 342367b8a455SSatish Balay . -snes_grid_sequence <steps> - Use grid sequencing to generate initial guess 3424efd51863SBarry Smith 3425efd51863SBarry Smith Level: intermediate 3426efd51863SBarry Smith 3427f6dfbefdSBarry Smith Note: 3428f6dfbefdSBarry Smith Use `SNESGetSolution()` to extract the fine grid solution after grid sequencing. 3429c0df2a02SJed Brown 3430f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetGridSequence()` 3431efd51863SBarry Smith @*/ 3432d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetGridSequence(SNES snes, PetscInt steps) 3433d71ae5a4SJacob Faibussowitsch { 3434efd51863SBarry Smith PetscFunctionBegin; 3435efd51863SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3436efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes, steps, 2); 3437efd51863SBarry Smith snes->gridsequence = steps; 3438efd51863SBarry Smith PetscFunctionReturn(0); 3439efd51863SBarry Smith } 3440efd51863SBarry Smith 3441fa19ca70SBarry Smith /*@ 3442f6dfbefdSBarry Smith SNESGetGridSequence - gets the number of steps of grid sequencing that `SNES` will do 3443fa19ca70SBarry Smith 3444*c3339decSBarry Smith Logically Collective 3445fa19ca70SBarry Smith 3446fa19ca70SBarry Smith Input Parameter: 3447f6dfbefdSBarry Smith . snes - the `SNES` context 3448fa19ca70SBarry Smith 3449fa19ca70SBarry Smith Output Parameter: 3450fa19ca70SBarry Smith . steps - the number of refinements to do, defaults to 0 3451fa19ca70SBarry Smith 3452f6dfbefdSBarry Smith Options Database Key: 345367b8a455SSatish Balay . -snes_grid_sequence <steps> - set number of refinements 3454fa19ca70SBarry Smith 3455fa19ca70SBarry Smith Level: intermediate 3456fa19ca70SBarry Smith 3457f6dfbefdSBarry Smith Note: 3458f6dfbefdSBarry Smith Use `SNESGetSolution()` to extract the fine grid solution after grid sequencing. 3459fa19ca70SBarry Smith 3460db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetGridSequence()` 3461fa19ca70SBarry Smith @*/ 3462d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetGridSequence(SNES snes, PetscInt *steps) 3463d71ae5a4SJacob Faibussowitsch { 3464fa19ca70SBarry Smith PetscFunctionBegin; 3465fa19ca70SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3466fa19ca70SBarry Smith *steps = snes->gridsequence; 3467fa19ca70SBarry Smith PetscFunctionReturn(0); 3468fa19ca70SBarry Smith } 3469fa19ca70SBarry Smith 3470a8054027SBarry Smith /*@ 3471f6dfbefdSBarry Smith SNESGetLagPreconditioner - Return how often the preconditioner is rebuilt 3472a8054027SBarry Smith 34733f9fe445SBarry Smith Not Collective 3474a8054027SBarry Smith 3475a8054027SBarry Smith Input Parameter: 3476f6dfbefdSBarry Smith . snes - the `SNES` context 3477a8054027SBarry Smith 3478a8054027SBarry Smith Output Parameter: 3479a8054027SBarry 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 34803b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3481a8054027SBarry Smith 3482a8054027SBarry Smith Options Database Keys: 34833d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 34843d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 34853d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 34863d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3487a8054027SBarry Smith 3488a8054027SBarry Smith Notes: 3489a8054027SBarry Smith The default is 1 3490f6dfbefdSBarry Smith 3491a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3492a8054027SBarry Smith 3493a8054027SBarry Smith Level: intermediate 3494a8054027SBarry Smith 3495f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3496a8054027SBarry Smith @*/ 3497d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLagPreconditioner(SNES snes, PetscInt *lag) 3498d71ae5a4SJacob Faibussowitsch { 3499a8054027SBarry Smith PetscFunctionBegin; 35000700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3501a8054027SBarry Smith *lag = snes->lagpreconditioner; 3502a8054027SBarry Smith PetscFunctionReturn(0); 3503a8054027SBarry Smith } 3504a8054027SBarry Smith 3505e35cf81dSBarry Smith /*@ 3506f6dfbefdSBarry Smith SNESSetLagJacobian - Set when the Jacobian is rebuilt in the nonlinear solve. See `SNESSetLagPreconditioner()` for determining how 3507e35cf81dSBarry Smith often the preconditioner is rebuilt. 3508e35cf81dSBarry Smith 3509*c3339decSBarry Smith Logically Collective 3510e35cf81dSBarry Smith 3511e35cf81dSBarry Smith Input Parameters: 3512f6dfbefdSBarry Smith + snes - the `SNES` context 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 3514fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 3515e35cf81dSBarry Smith 3516e35cf81dSBarry Smith Options Database Keys: 35173d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35183d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35193d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35203d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag. 3521e35cf81dSBarry Smith 3522e35cf81dSBarry Smith Notes: 3523e35cf81dSBarry Smith The default is 1 3524f6dfbefdSBarry Smith 3525e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3526f6dfbefdSBarry Smith 3527fe3ffe1eSBarry 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 3528fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 3529e35cf81dSBarry Smith 3530e35cf81dSBarry Smith Level: intermediate 3531e35cf81dSBarry Smith 3532f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagPreconditioner()`, `SNESGetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3533e35cf81dSBarry Smith @*/ 3534d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagJacobian(SNES snes, PetscInt lag) 3535d71ae5a4SJacob Faibussowitsch { 3536e35cf81dSBarry Smith PetscFunctionBegin; 35370700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 35385f80ce2aSJacob Faibussowitsch PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater"); 35395f80ce2aSJacob Faibussowitsch PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0"); 3540c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, lag, 2); 3541e35cf81dSBarry Smith snes->lagjacobian = lag; 3542e35cf81dSBarry Smith PetscFunctionReturn(0); 3543e35cf81dSBarry Smith } 3544e35cf81dSBarry Smith 3545e35cf81dSBarry Smith /*@ 3546f6dfbefdSBarry Smith SNESGetLagJacobian - Get how often the Jacobian is rebuilt. See `SNESGetLagPreconditioner()` to determine when the preconditioner is rebuilt 3547e35cf81dSBarry Smith 35483f9fe445SBarry Smith Not Collective 3549e35cf81dSBarry Smith 3550e35cf81dSBarry Smith Input Parameter: 3551f6dfbefdSBarry Smith . snes - the `SNES` context 3552e35cf81dSBarry Smith 3553e35cf81dSBarry Smith Output Parameter: 3554e35cf81dSBarry 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 3555e35cf81dSBarry Smith the Jacobian is built etc. 3556e35cf81dSBarry Smith 3557e35cf81dSBarry Smith Notes: 3558e35cf81dSBarry Smith The default is 1 3559f6dfbefdSBarry Smith 3560f6dfbefdSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagJacobianPersists()` was called. 3561e35cf81dSBarry Smith 3562e35cf81dSBarry Smith Level: intermediate 3563e35cf81dSBarry Smith 3564f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetLagJacobian()`, `SNESSetLagPreconditioner()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3565e35cf81dSBarry Smith 3566e35cf81dSBarry Smith @*/ 3567d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLagJacobian(SNES snes, PetscInt *lag) 3568d71ae5a4SJacob Faibussowitsch { 3569e35cf81dSBarry Smith PetscFunctionBegin; 35700700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3571e35cf81dSBarry Smith *lag = snes->lagjacobian; 3572e35cf81dSBarry Smith PetscFunctionReturn(0); 3573e35cf81dSBarry Smith } 3574e35cf81dSBarry Smith 357537ec4e1aSPeter Brune /*@ 3576f6dfbefdSBarry Smith SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple nonlinear solves 357737ec4e1aSPeter Brune 3578*c3339decSBarry Smith Logically collective 357937ec4e1aSPeter Brune 3580d8d19677SJose E. Roman Input Parameters: 3581f6dfbefdSBarry Smith + snes - the `SNES` context 35829d7e2deaSPeter Brune - flg - jacobian lagging persists if true 358337ec4e1aSPeter Brune 358437ec4e1aSPeter Brune Options Database Keys: 35853d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35863d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35873d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35883d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 35893d5a8a6aSBarry Smith 359095452b02SPatrick Sanan Notes: 3591f6dfbefdSBarry Smith Normally when `SNESSetLagJacobian()` is used, the Jacobian is always rebuilt at the beginning of each new nonlinear solve, this removes that. 3592f6dfbefdSBarry Smith 359395452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 359437ec4e1aSPeter Brune several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 359537ec4e1aSPeter Brune timesteps may present huge efficiency gains. 359637ec4e1aSPeter Brune 3597f6dfbefdSBarry Smith Level: advanced 359837ec4e1aSPeter Brune 3599f6dfbefdSBarry Smith .seealso: `SNES, `SNESSetLagPreconditionerPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagJacobianPersists()` 360037ec4e1aSPeter Brune @*/ 3601d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagJacobianPersists(SNES snes, PetscBool flg) 3602d71ae5a4SJacob Faibussowitsch { 360337ec4e1aSPeter Brune PetscFunctionBegin; 360437ec4e1aSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 360537ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes, flg, 2); 360637ec4e1aSPeter Brune snes->lagjac_persist = flg; 360737ec4e1aSPeter Brune PetscFunctionReturn(0); 360837ec4e1aSPeter Brune } 360937ec4e1aSPeter Brune 361037ec4e1aSPeter Brune /*@ 3611d8e291bfSBarry Smith SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple nonlinear solves 361237ec4e1aSPeter Brune 3613*c3339decSBarry Smith Logically Collective 361437ec4e1aSPeter Brune 3615d8d19677SJose E. Roman Input Parameters: 3616f6dfbefdSBarry Smith + snes - the `SNES` context 36179d7e2deaSPeter Brune - flg - preconditioner lagging persists if true 361837ec4e1aSPeter Brune 361937ec4e1aSPeter Brune Options Database Keys: 36203d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 36213d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 36223d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 36233d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 362437ec4e1aSPeter Brune 362595452b02SPatrick Sanan Notes: 3626f6dfbefdSBarry Smith Normally when `SNESSetLagPreconditioner()` is used, the preconditioner is always rebuilt at the beginning of each new nonlinear solve, this removes that. 3627f6dfbefdSBarry Smith 362895452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 362937ec4e1aSPeter Brune by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 363037ec4e1aSPeter Brune several timesteps may present huge efficiency gains. 363137ec4e1aSPeter Brune 363237ec4e1aSPeter Brune Level: developer 363337ec4e1aSPeter Brune 3634f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetLagJacobianPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagPreconditioner()` 363537ec4e1aSPeter Brune @*/ 3636d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes, PetscBool flg) 3637d71ae5a4SJacob Faibussowitsch { 363837ec4e1aSPeter Brune PetscFunctionBegin; 363937ec4e1aSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 364037ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes, flg, 2); 364137ec4e1aSPeter Brune snes->lagpre_persist = flg; 364237ec4e1aSPeter Brune PetscFunctionReturn(0); 364337ec4e1aSPeter Brune } 364437ec4e1aSPeter Brune 36459b94acceSBarry Smith /*@ 3646f6dfbefdSBarry Smith SNESSetForceIteration - force `SNESSolve()` to take at least one iteration regardless of the initial residual norm 3647be5caee7SBarry Smith 3648*c3339decSBarry Smith Logically Collective 3649be5caee7SBarry Smith 3650be5caee7SBarry Smith Input Parameters: 3651f6dfbefdSBarry Smith + snes - the `SNES` context 3652f6dfbefdSBarry Smith - force - `PETSC_TRUE` require at least one iteration 3653be5caee7SBarry Smith 3654f6dfbefdSBarry Smith Options Database Key: 3655be5caee7SBarry Smith . -snes_force_iteration <force> - Sets forcing an iteration 3656be5caee7SBarry Smith 3657f6dfbefdSBarry Smith Note: 3658f6dfbefdSBarry Smith This is used sometimes with `TS` to prevent `TS` from detecting a false steady state solution 3659be5caee7SBarry Smith 3660be5caee7SBarry Smith Level: intermediate 3661be5caee7SBarry Smith 3662f6dfbefdSBarry Smith .seealso: `SNES`, `TS`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 3663be5caee7SBarry Smith @*/ 3664d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetForceIteration(SNES snes, PetscBool force) 3665d71ae5a4SJacob Faibussowitsch { 3666be5caee7SBarry Smith PetscFunctionBegin; 3667be5caee7SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3668be5caee7SBarry Smith snes->forceiteration = force; 3669be5caee7SBarry Smith PetscFunctionReturn(0); 3670be5caee7SBarry Smith } 3671be5caee7SBarry Smith 367285216dc7SFande Kong /*@ 3673f6dfbefdSBarry Smith SNESGetForceIteration - Check whether or not `SNESSolve()` take at least one iteration regardless of the initial residual norm 367485216dc7SFande Kong 3675*c3339decSBarry Smith Logically Collective 367685216dc7SFande Kong 367785216dc7SFande Kong Input Parameters: 3678f6dfbefdSBarry Smith . snes - the `SNES` context 367985216dc7SFande Kong 368085216dc7SFande Kong Output Parameter: 368185216dc7SFande Kong . force - PETSC_TRUE requires at least one iteration. 368285216dc7SFande Kong 368306dd6b0eSSatish Balay Level: intermediate 368406dd6b0eSSatish Balay 3685f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetForceIteration()`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 368685216dc7SFande Kong @*/ 3687d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetForceIteration(SNES snes, PetscBool *force) 3688d71ae5a4SJacob Faibussowitsch { 368985216dc7SFande Kong PetscFunctionBegin; 369085216dc7SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 369185216dc7SFande Kong *force = snes->forceiteration; 369285216dc7SFande Kong PetscFunctionReturn(0); 369385216dc7SFande Kong } 3694be5caee7SBarry Smith 3695be5caee7SBarry Smith /*@ 3696f6dfbefdSBarry Smith SNESSetTolerances - Sets `SNES` various parameters used in convergence tests. 36979b94acceSBarry Smith 3698*c3339decSBarry Smith Logically Collective 3699c7afd0dbSLois Curfman McInnes 37009b94acceSBarry Smith Input Parameters: 3701f6dfbefdSBarry Smith + snes - the `SNES` context 370270441072SBarry Smith . abstol - absolute convergence tolerance 370333174efeSLois Curfman McInnes . rtol - relative convergence tolerance 37045358d0d4SBarry Smith . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 3705f6dfbefdSBarry Smith . maxit - maximum number of iterations, default 50. 3706f6dfbefdSBarry Smith - maxf - maximum number of function evaluations (-1 indicates no limit), default 1000 3707fee21e36SBarry Smith 370833174efeSLois Curfman McInnes Options Database Keys: 370970441072SBarry Smith + -snes_atol <abstol> - Sets abstol 3710c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 3711c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 3712c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 3713c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 37149b94acceSBarry Smith 371536851e7fSLois Curfman McInnes Level: intermediate 371636851e7fSLois Curfman McInnes 3717f6dfbefdSBarry Smith .seealso: `SNESolve()`, `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`, `SNESSetForceIteration()` 37189b94acceSBarry Smith @*/ 3719d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetTolerances(SNES snes, PetscReal abstol, PetscReal rtol, PetscReal stol, PetscInt maxit, PetscInt maxf) 3720d71ae5a4SJacob Faibussowitsch { 37213a40ed3dSBarry Smith PetscFunctionBegin; 37220700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3723c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, abstol, 2); 3724c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol, 3); 3725c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, stol, 4); 3726c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxit, 5); 3727c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxf, 6); 3728c5eb9154SBarry Smith 3729ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 37305f80ce2aSJacob Faibussowitsch PetscCheck(abstol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Absolute tolerance %g must be non-negative", (double)abstol); 3731ab54825eSJed Brown snes->abstol = abstol; 3732ab54825eSJed Brown } 3733ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 37345f80ce2aSJacob 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); 3735ab54825eSJed Brown snes->rtol = rtol; 3736ab54825eSJed Brown } 3737ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 37385f80ce2aSJacob Faibussowitsch PetscCheck(stol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Step tolerance %g must be non-negative", (double)stol); 3739c60f73f4SPeter Brune snes->stol = stol; 3740ab54825eSJed Brown } 3741ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 374263a3b9bcSJacob Faibussowitsch PetscCheck(maxit >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of iterations %" PetscInt_FMT " must be non-negative", maxit); 3743ab54825eSJed Brown snes->max_its = maxit; 3744ab54825eSJed Brown } 3745ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 374663a3b9bcSJacob Faibussowitsch PetscCheck(maxf >= -1, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of function evaluations %" PetscInt_FMT " must be -1 or nonnegative", maxf); 3747ab54825eSJed Brown snes->max_funcs = maxf; 3748ab54825eSJed Brown } 374988976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 37503a40ed3dSBarry Smith PetscFunctionReturn(0); 37519b94acceSBarry Smith } 37529b94acceSBarry Smith 3753e4d06f11SPatrick Farrell /*@ 3754f6dfbefdSBarry Smith SNESSetDivergenceTolerance - Sets the divergence tolerance used for the `SNES` divergence test. 3755e4d06f11SPatrick Farrell 3756*c3339decSBarry Smith Logically Collective 3757e4d06f11SPatrick Farrell 3758e4d06f11SPatrick Farrell Input Parameters: 3759f6dfbefdSBarry Smith + snes - the `SNES` context 3760f6dfbefdSBarry Smith - divtol - the divergence tolerance. Use -1 to deactivate the test, default is 1e4 3761e4d06f11SPatrick Farrell 3762f6dfbefdSBarry Smith Options Database Key: 3763a2b725a8SWilliam Gropp . -snes_divergence_tolerance <divtol> - Sets divtol 3764e4d06f11SPatrick Farrell 3765e4d06f11SPatrick Farrell Level: intermediate 3766e4d06f11SPatrick Farrell 3767f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESSetTolerances()`, `SNESGetDivergenceTolerance` 3768e4d06f11SPatrick Farrell @*/ 3769d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetDivergenceTolerance(SNES snes, PetscReal divtol) 3770d71ae5a4SJacob Faibussowitsch { 3771e4d06f11SPatrick Farrell PetscFunctionBegin; 3772e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3773e4d06f11SPatrick Farrell PetscValidLogicalCollectiveReal(snes, divtol, 2); 3774e4d06f11SPatrick Farrell 3775e4d06f11SPatrick Farrell if (divtol != PETSC_DEFAULT) { 3776e4d06f11SPatrick Farrell snes->divtol = divtol; 37779371c9d4SSatish Balay } else { 3778e4d06f11SPatrick Farrell snes->divtol = 1.0e4; 3779e4d06f11SPatrick Farrell } 3780e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3781e4d06f11SPatrick Farrell } 3782e4d06f11SPatrick Farrell 37839b94acceSBarry Smith /*@ 378433174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 378533174efeSLois Curfman McInnes 3786c7afd0dbSLois Curfman McInnes Not Collective 3787c7afd0dbSLois Curfman McInnes 378833174efeSLois Curfman McInnes Input Parameters: 3789f6dfbefdSBarry Smith + snes - the `SNES` context 379085385478SLisandro Dalcin . atol - absolute convergence tolerance 379133174efeSLois Curfman McInnes . rtol - relative convergence tolerance 379233174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 379333174efeSLois Curfman McInnes of the change in the solution between steps 379433174efeSLois Curfman McInnes . maxit - maximum number of iterations 3795c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 3796fee21e36SBarry Smith 3797f6dfbefdSBarry Smith Note: 37980298fd71SBarry Smith The user can specify NULL for any parameter that is not needed. 379933174efeSLois Curfman McInnes 380036851e7fSLois Curfman McInnes Level: intermediate 380136851e7fSLois Curfman McInnes 3802f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetTolerances()` 380333174efeSLois Curfman McInnes @*/ 3804d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetTolerances(SNES snes, PetscReal *atol, PetscReal *rtol, PetscReal *stol, PetscInt *maxit, PetscInt *maxf) 3805d71ae5a4SJacob Faibussowitsch { 38063a40ed3dSBarry Smith PetscFunctionBegin; 38070700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 380885385478SLisandro Dalcin if (atol) *atol = snes->abstol; 380933174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 3810c60f73f4SPeter Brune if (stol) *stol = snes->stol; 381133174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 381233174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 38133a40ed3dSBarry Smith PetscFunctionReturn(0); 381433174efeSLois Curfman McInnes } 381533174efeSLois Curfman McInnes 3816e4d06f11SPatrick Farrell /*@ 3817e4d06f11SPatrick Farrell SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test. 3818e4d06f11SPatrick Farrell 3819e4d06f11SPatrick Farrell Not Collective 3820e4d06f11SPatrick Farrell 3821e4d06f11SPatrick Farrell Input Parameters: 3822f6dfbefdSBarry Smith + snes - the `SNES` context 3823e4d06f11SPatrick Farrell - divtol - divergence tolerance 3824e4d06f11SPatrick Farrell 3825e4d06f11SPatrick Farrell Level: intermediate 3826e4d06f11SPatrick Farrell 3827f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetDivergenceTolerance()` 3828e4d06f11SPatrick Farrell @*/ 3829d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetDivergenceTolerance(SNES snes, PetscReal *divtol) 3830d71ae5a4SJacob Faibussowitsch { 3831e4d06f11SPatrick Farrell PetscFunctionBegin; 3832e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3833e4d06f11SPatrick Farrell if (divtol) *divtol = snes->divtol; 3834e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3835e4d06f11SPatrick Farrell } 3836e4d06f11SPatrick Farrell 383733174efeSLois Curfman McInnes /*@ 38389b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 38399b94acceSBarry Smith 3840*c3339decSBarry Smith Logically Collective 3841fee21e36SBarry Smith 3842c7afd0dbSLois Curfman McInnes Input Parameters: 3843f6dfbefdSBarry Smith + snes - the `SNES` context 3844c7afd0dbSLois Curfman McInnes - tol - tolerance 3845c7afd0dbSLois Curfman McInnes 38469b94acceSBarry Smith Options Database Key: 3847c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 38489b94acceSBarry Smith 384936851e7fSLois Curfman McInnes Level: intermediate 385036851e7fSLois Curfman McInnes 3851f6dfbefdSBarry Smith .seealso: `SNES`, `SNESNEWTONTRDC`, `SNESSetTolerances()` 38529b94acceSBarry Smith @*/ 3853d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetTrustRegionTolerance(SNES snes, PetscReal tol) 3854d71ae5a4SJacob Faibussowitsch { 38553a40ed3dSBarry Smith PetscFunctionBegin; 38560700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3857c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, tol, 2); 38589b94acceSBarry Smith snes->deltatol = tol; 38593a40ed3dSBarry Smith PetscFunctionReturn(0); 38609b94acceSBarry Smith } 38619b94acceSBarry Smith 38626ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *); 38636ba87a44SLisandro Dalcin 3864d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorLGRange(SNES snes, PetscInt n, PetscReal rnorm, void *monctx) 3865d71ae5a4SJacob Faibussowitsch { 3866b271bb04SBarry Smith PetscDrawLG lg; 3867b271bb04SBarry Smith PetscReal x, y, per; 3868b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 3869b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 3870b271bb04SBarry Smith PetscDraw draw; 3871b271bb04SBarry Smith 3872459f5d12SBarry Smith PetscFunctionBegin; 38734d4332d5SBarry Smith PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 4); 38749566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 0, &lg)); 38759566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 38769566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 38779566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "Residual norm")); 3878b271bb04SBarry Smith x = (PetscReal)n; 387977b4d14cSPeter Brune if (rnorm > 0.0) y = PetscLog10Real(rnorm); 388094c9c6d3SKarl Rupp else y = -15.0; 38819566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 38826934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38839566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38849566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3885b271bb04SBarry Smith } 3886b271bb04SBarry Smith 38879566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 1, &lg)); 38889566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 38899566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 38909566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "% elemts > .2*max elemt")); 38919566063dSJacob Faibussowitsch PetscCall(SNESMonitorRange_Private(snes, n, &per)); 3892b271bb04SBarry Smith x = (PetscReal)n; 3893b271bb04SBarry Smith y = 100.0 * per; 38949566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 38956934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38969566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38979566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3898b271bb04SBarry Smith } 3899b271bb04SBarry Smith 39009566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 2, &lg)); 39019371c9d4SSatish Balay if (!n) { 39029371c9d4SSatish Balay prev = rnorm; 39039371c9d4SSatish Balay PetscCall(PetscDrawLGReset(lg)); 39049371c9d4SSatish Balay } 39059566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 39069566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm")); 3907b271bb04SBarry Smith x = (PetscReal)n; 3908b271bb04SBarry Smith y = (prev - rnorm) / prev; 39099566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 39106934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 39119566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 39129566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3913b271bb04SBarry Smith } 3914b271bb04SBarry Smith 39159566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 3, &lg)); 39169566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 39179566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 39189566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm*(% > .2 max)")); 3919b271bb04SBarry Smith x = (PetscReal)n; 3920b271bb04SBarry Smith y = (prev - rnorm) / (prev * per); 3921b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 39229566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 3923b271bb04SBarry Smith } 39246934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 39259566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 39269566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3927b271bb04SBarry Smith } 3928b271bb04SBarry Smith prev = rnorm; 3929b271bb04SBarry Smith PetscFunctionReturn(0); 3930b271bb04SBarry Smith } 3931b271bb04SBarry Smith 3932228d79bcSJed Brown /*@ 3933228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 3934228d79bcSJed Brown 3935*c3339decSBarry Smith Collective 3936228d79bcSJed Brown 3937228d79bcSJed Brown Input Parameters: 3938f6dfbefdSBarry Smith + snes - nonlinear solver context obtained from `SNESCreate()` 3939228d79bcSJed Brown . iter - iteration number 3940228d79bcSJed Brown - rnorm - relative norm of the residual 3941228d79bcSJed Brown 3942f6dfbefdSBarry Smith Note: 3943f6dfbefdSBarry Smith This routine is called by the `SNES` implementations. 3944228d79bcSJed Brown It does not typically need to be called by the user. 3945228d79bcSJed Brown 3946228d79bcSJed Brown Level: developer 3947228d79bcSJed Brown 3948f6dfbefdSBarry Smith .seealso: `SNES`, `SNESMonitorSet()` 3949228d79bcSJed Brown @*/ 3950d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitor(SNES snes, PetscInt iter, PetscReal rnorm) 3951d71ae5a4SJacob Faibussowitsch { 39527a03ce2fSLisandro Dalcin PetscInt i, n = snes->numbermonitors; 39537a03ce2fSLisandro Dalcin 39547a03ce2fSLisandro Dalcin PetscFunctionBegin; 39559566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(snes->vec_sol)); 395648a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall((*snes->monitor[i])(snes, iter, rnorm, snes->monitorcontext[i])); 39579566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(snes->vec_sol)); 39587a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 39597a03ce2fSLisandro Dalcin } 39607a03ce2fSLisandro Dalcin 39619b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 39629b94acceSBarry Smith 3963bf388a1fSBarry Smith /*MC 3964f6dfbefdSBarry Smith SNESMonitorFunction - functional form passed to `SNESMonitorSet()` to monitor convergence of nonlinear solver 3965bf388a1fSBarry Smith 3966bf388a1fSBarry Smith Synopsis: 3967aaa7dc30SBarry Smith #include <petscsnes.h> 3968bf388a1fSBarry Smith $ PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3969bf388a1fSBarry Smith 3970*c3339decSBarry Smith Collective 39711843f636SBarry Smith 39721843f636SBarry Smith Input Parameters: 3973f6dfbefdSBarry Smith + snes - the `SNES` context 3974bf388a1fSBarry Smith . its - iteration number 3975bf388a1fSBarry Smith . norm - 2-norm function value (may be estimated) 3976bf388a1fSBarry Smith - mctx - [optional] monitoring context 3977bf388a1fSBarry Smith 3978878cb397SSatish Balay Level: advanced 3979878cb397SSatish Balay 3980f6dfbefdSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorSet()`, `SNESMonitorGet()` 3981bf388a1fSBarry Smith M*/ 3982bf388a1fSBarry Smith 39839b94acceSBarry Smith /*@C 3984a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 39859b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 39869b94acceSBarry Smith progress. 39879b94acceSBarry Smith 3988*c3339decSBarry Smith Logically Collective 3989fee21e36SBarry Smith 3990c7afd0dbSLois Curfman McInnes Input Parameters: 3991f6dfbefdSBarry Smith + snes - the `SNES` context 3992f6dfbefdSBarry Smith . f - the monitor function, see `SNESMonitorFunction` for the calling sequence 3993b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 39940298fd71SBarry Smith monitor routine (use NULL if no context is desired) 3995b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 39960298fd71SBarry Smith (may be NULL) 39979b94acceSBarry Smith 39989665c990SLois Curfman McInnes Options Database Keys: 3999f6dfbefdSBarry Smith + -snes_monitor - sets `SNESMonitorDefault()` 4000798534f6SMatthew G. Knepley . -snes_monitor draw::draw_lg - sets line graph monitor, 4001cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 4002c7afd0dbSLois Curfman McInnes been hardwired into a code by 4003a6570f20SBarry Smith calls to SNESMonitorSet(), but 4004c7afd0dbSLois Curfman McInnes does not cancel those set via 4005c7afd0dbSLois Curfman McInnes the options database. 40069665c990SLois Curfman McInnes 4007f6dfbefdSBarry Smith Note: 40086bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 4009f6dfbefdSBarry Smith `SNESMonitorSet()` multiple times; all will be called in the 40106bc08f3fSLois Curfman McInnes order in which they were set. 4011639f9d9dSBarry Smith 4012f6dfbefdSBarry Smith Fortran Note: 4013f6dfbefdSBarry Smith Only a single monitor function can be set for each `SNES` object 4014025f1a04SBarry Smith 401536851e7fSLois Curfman McInnes Level: intermediate 401636851e7fSLois Curfman McInnes 4017f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESMonitorDefault()`, `SNESMonitorCancel()`, `SNESMonitorFunction` 40189b94acceSBarry Smith @*/ 4019d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSet(SNES snes, PetscErrorCode (*f)(SNES, PetscInt, PetscReal, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **)) 4020d71ae5a4SJacob Faibussowitsch { 4021b90d0a6eSBarry Smith PetscInt i; 402278064530SBarry Smith PetscBool identical; 4023b90d0a6eSBarry Smith 40243a40ed3dSBarry Smith PetscFunctionBegin; 40250700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4026b90d0a6eSBarry Smith for (i = 0; i < snes->numbermonitors; i++) { 40279566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, mctx, monitordestroy, (PetscErrorCode(*)(void))snes->monitor[i], snes->monitorcontext[i], snes->monitordestroy[i], &identical)); 402878064530SBarry Smith if (identical) PetscFunctionReturn(0); 4029649052a6SBarry Smith } 40305f80ce2aSJacob Faibussowitsch PetscCheck(snes->numbermonitors < MAXSNESMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 40316e4dcb14SBarry Smith snes->monitor[snes->numbermonitors] = f; 4032b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 4033639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void *)mctx; 40343a40ed3dSBarry Smith PetscFunctionReturn(0); 40359b94acceSBarry Smith } 40369b94acceSBarry Smith 4037a278d85bSSatish Balay /*@ 4038f6dfbefdSBarry Smith SNESMonitorCancel - Clears all the monitor functions for a `SNES` object. 40395cd90555SBarry Smith 4040*c3339decSBarry Smith Logically Collective 4041c7afd0dbSLois Curfman McInnes 40425cd90555SBarry Smith Input Parameters: 4043f6dfbefdSBarry Smith . snes - the `SNES` context 40445cd90555SBarry Smith 40451a480d89SAdministrator Options Database Key: 4046a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 4047a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 4048c7afd0dbSLois Curfman McInnes set via the options database 40495cd90555SBarry Smith 4050f6dfbefdSBarry Smith Note: 4051f6dfbefdSBarry Smith There is no way to clear one specific monitor from a `SNES` object. 40525cd90555SBarry Smith 405336851e7fSLois Curfman McInnes Level: intermediate 405436851e7fSLois Curfman McInnes 4055f6dfbefdSBarry Smith .seealso: `SNES`, `SNESMonitorGet()`, `SNESMonitorDefault()`, `SNESMonitorSet()` 40565cd90555SBarry Smith @*/ 4057d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorCancel(SNES snes) 4058d71ae5a4SJacob Faibussowitsch { 4059d952e501SBarry Smith PetscInt i; 4060d952e501SBarry Smith 40615cd90555SBarry Smith PetscFunctionBegin; 40620700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4063d952e501SBarry Smith for (i = 0; i < snes->numbermonitors; i++) { 406448a46eb9SPierre Jolivet if (snes->monitordestroy[i]) PetscCall((*snes->monitordestroy[i])(&snes->monitorcontext[i])); 4065d952e501SBarry Smith } 40665cd90555SBarry Smith snes->numbermonitors = 0; 40675cd90555SBarry Smith PetscFunctionReturn(0); 40685cd90555SBarry Smith } 40695cd90555SBarry Smith 4070bf388a1fSBarry Smith /*MC 4071bf388a1fSBarry Smith SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 4072bf388a1fSBarry Smith 4073bf388a1fSBarry Smith Synopsis: 4074aaa7dc30SBarry Smith #include <petscsnes.h> 4075bf388a1fSBarry Smith $ PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 4076bf388a1fSBarry Smith 4077*c3339decSBarry Smith Collective 40781843f636SBarry Smith 40791843f636SBarry Smith Input Parameters: 4080f6dfbefdSBarry Smith + snes - the `SNES` context 4081bf388a1fSBarry Smith . it - current iteration (0 is the first and is before any Newton step) 4082bf388a1fSBarry Smith . xnorm - 2-norm of current iterate 4083bf388a1fSBarry Smith . gnorm - 2-norm of current step 40841843f636SBarry Smith . f - 2-norm of function 40851843f636SBarry Smith - cctx - [optional] convergence context 40861843f636SBarry Smith 40871843f636SBarry Smith Output Parameter: 40881843f636SBarry Smith . reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected 4089bf388a1fSBarry Smith 4090878cb397SSatish Balay Level: intermediate 4091bf388a1fSBarry Smith 4092f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve`, `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()` 4093bf388a1fSBarry Smith M*/ 4094bf388a1fSBarry Smith 40959b94acceSBarry Smith /*@C 40969b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 40979b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 40989b94acceSBarry Smith 4099*c3339decSBarry Smith Logically Collective 4100fee21e36SBarry Smith 4101c7afd0dbSLois Curfman McInnes Input Parameters: 4102f6dfbefdSBarry Smith + snes - the `SNES` context 4103f6dfbefdSBarry Smith . `SNESConvergenceTestFunction` - routine to test for convergence 41040298fd71SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be NULL) 4105cf90aa19SBarry Smith - destroy - [optional] destructor for the context (may be NULL; PETSC_NULL_FUNCTION in Fortran) 41069b94acceSBarry Smith 410736851e7fSLois Curfman McInnes Level: advanced 410836851e7fSLois Curfman McInnes 4109f6dfbefdSBarry Smith .seealso: `SNES`, `SNESConvergedDefault()`, `SNESConvergedSkip()`, `SNESConvergenceTestFunction` 41109b94acceSBarry Smith @*/ 4111d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergenceTest(SNES snes, PetscErrorCode (*SNESConvergenceTestFunction)(SNES, PetscInt, PetscReal, PetscReal, PetscReal, SNESConvergedReason *, void *), void *cctx, PetscErrorCode (*destroy)(void *)) 4112d71ae5a4SJacob Faibussowitsch { 41133a40ed3dSBarry Smith PetscFunctionBegin; 41140700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4115e2a6519dSDmitry Karpeev if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 41161baa6e33SBarry Smith if (snes->ops->convergeddestroy) PetscCall((*snes->ops->convergeddestroy)(snes->cnvP)); 4117bf388a1fSBarry Smith snes->ops->converged = SNESConvergenceTestFunction; 41187f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 411985385478SLisandro Dalcin snes->cnvP = cctx; 41203a40ed3dSBarry Smith PetscFunctionReturn(0); 41219b94acceSBarry Smith } 41229b94acceSBarry Smith 412352baeb72SSatish Balay /*@ 4124f6dfbefdSBarry Smith SNESGetConvergedReason - Gets the reason the `SNES` iteration was stopped. 4125184914b5SBarry Smith 4126184914b5SBarry Smith Not Collective 4127184914b5SBarry Smith 4128184914b5SBarry Smith Input Parameter: 4129f6dfbefdSBarry Smith . snes - the `SNES` context 4130184914b5SBarry Smith 4131184914b5SBarry Smith Output Parameter: 4132f6dfbefdSBarry Smith . reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` for the individual convergence tests for complete lists 4133184914b5SBarry Smith 4134f6dfbefdSBarry Smith Options Database Key: 41356a4d7782SBarry Smith . -snes_converged_reason - prints the reason to standard out 41366a4d7782SBarry Smith 4137184914b5SBarry Smith Level: intermediate 4138184914b5SBarry Smith 4139f6dfbefdSBarry Smith Note: 4140f6dfbefdSBarry Smith Should only be called after the call the `SNESSolve()` is complete, if it is called earlier it returns the value `SNES__CONVERGED_ITERATING`. 4141184914b5SBarry Smith 4142f6dfbefdSBarry Smith .seealso: `SNESSolve()`, `SNESSetConvergenceTest()`, `SNESSetConvergedReason()`, `SNESConvergedReason`, `SNESGetConvergedReasonString()` 4143184914b5SBarry Smith @*/ 4144d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergedReason(SNES snes, SNESConvergedReason *reason) 4145d71ae5a4SJacob Faibussowitsch { 4146184914b5SBarry Smith PetscFunctionBegin; 41470700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 41484482741eSBarry Smith PetscValidPointer(reason, 2); 4149184914b5SBarry Smith *reason = snes->reason; 4150184914b5SBarry Smith PetscFunctionReturn(0); 4151184914b5SBarry Smith } 4152184914b5SBarry Smith 4153c4421ceaSFande Kong /*@C 4154f6dfbefdSBarry Smith SNESGetConvergedReasonString - Return a human readable string for `SNESConvergedReason` 4155c4421ceaSFande Kong 4156c4421ceaSFande Kong Not Collective 4157c4421ceaSFande Kong 4158c4421ceaSFande Kong Input Parameter: 4159f6dfbefdSBarry Smith . snes - the `SNES` context 4160c4421ceaSFande Kong 4161c4421ceaSFande Kong Output Parameter: 4162c4421ceaSFande Kong . strreason - a human readable string that describes SNES converged reason 4163c4421ceaSFande Kong 416499c90e12SSatish Balay Level: beginner 4165c4421ceaSFande Kong 4166f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetConvergedReason()` 4167c4421ceaSFande Kong @*/ 4168d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char **strreason) 4169d71ae5a4SJacob Faibussowitsch { 4170c4421ceaSFande Kong PetscFunctionBegin; 4171c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4172dadcf809SJacob Faibussowitsch PetscValidPointer(strreason, 2); 4173c4421ceaSFande Kong *strreason = SNESConvergedReasons[snes->reason]; 4174c4421ceaSFande Kong PetscFunctionReturn(0); 4175c4421ceaSFande Kong } 4176c4421ceaSFande Kong 417733866048SMatthew G. Knepley /*@ 4178f6dfbefdSBarry Smith SNESSetConvergedReason - Sets the reason the `SNES` iteration was stopped. 417933866048SMatthew G. Knepley 418033866048SMatthew G. Knepley Not Collective 418133866048SMatthew G. Knepley 418233866048SMatthew G. Knepley Input Parameters: 4183f6dfbefdSBarry Smith + snes - the `SNES` context 4184f6dfbefdSBarry Smith - reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` or the 418533866048SMatthew G. Knepley manual pages for the individual convergence tests for complete lists 418633866048SMatthew G. Knepley 4187f6dfbefdSBarry Smith Level: developer 4188f6dfbefdSBarry Smith 4189f6dfbefdSBarry Smith Developer Note: 4190f6dfbefdSBarry Smith Called inside the various `SNESSolve()` implementations 419133866048SMatthew G. Knepley 4192db781477SPatrick Sanan .seealso: `SNESGetConvergedReason()`, `SNESSetConvergenceTest()`, `SNESConvergedReason` 419333866048SMatthew G. Knepley @*/ 4194d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergedReason(SNES snes, SNESConvergedReason reason) 4195d71ae5a4SJacob Faibussowitsch { 419633866048SMatthew G. Knepley PetscFunctionBegin; 419733866048SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 419833866048SMatthew G. Knepley snes->reason = reason; 419933866048SMatthew G. Knepley PetscFunctionReturn(0); 420033866048SMatthew G. Knepley } 420133866048SMatthew G. Knepley 4202c9005455SLois Curfman McInnes /*@ 4203c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 4204c9005455SLois Curfman McInnes 4205*c3339decSBarry Smith Logically Collective 4206fee21e36SBarry Smith 4207c7afd0dbSLois Curfman McInnes Input Parameters: 4208f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 42098c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 4210cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 4211758f92a0SBarry Smith . na - size of a and its 4212f6dfbefdSBarry Smith - reset - `PETSC_TRUE` indicates each new nonlinear solve resets the history counter to zero, 4213758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 4214c7afd0dbSLois Curfman McInnes 4215308dcc3eSBarry Smith Notes: 4216f6dfbefdSBarry Smith If 'a' and 'its' are NULL then space is allocated for the history. If 'na' `PETSC_DECIDE` or `PETSC_DEFAULT` then a 4217308dcc3eSBarry Smith default array of length 10000 is allocated. 4218308dcc3eSBarry Smith 4219c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 4220c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 4221c9005455SLois Curfman McInnes during the section of code that is being timed. 4222c9005455SLois Curfman McInnes 422336851e7fSLois Curfman McInnes Level: intermediate 422436851e7fSLois Curfman McInnes 4225f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESGetConvergenceHistory()` 4226c9005455SLois Curfman McInnes @*/ 4227d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergenceHistory(SNES snes, PetscReal a[], PetscInt its[], PetscInt na, PetscBool reset) 4228d71ae5a4SJacob Faibussowitsch { 42293a40ed3dSBarry Smith PetscFunctionBegin; 42300700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4231064a246eSJacob Faibussowitsch if (a) PetscValidRealPointer(a, 2); 4232a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its, 3); 42337a1ec6d4SBarry Smith if (!a) { 4234308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 42359566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(na, &a, na, &its)); 4236071fcb05SBarry Smith snes->conv_hist_alloc = PETSC_TRUE; 4237308dcc3eSBarry Smith } 4238c9005455SLois Curfman McInnes snes->conv_hist = a; 4239758f92a0SBarry Smith snes->conv_hist_its = its; 4240115dd874SBarry Smith snes->conv_hist_max = (size_t)na; 4241a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 4242758f92a0SBarry Smith snes->conv_hist_reset = reset; 4243758f92a0SBarry Smith PetscFunctionReturn(0); 4244758f92a0SBarry Smith } 4245758f92a0SBarry Smith 4246d1e78c4fSBarry Smith #if defined(PETSC_HAVE_MATLAB) 4247c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 4248c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 424999e0435eSBarry Smith 4250d71ae5a4SJacob Faibussowitsch PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 4251d71ae5a4SJacob Faibussowitsch { 4252308dcc3eSBarry Smith mxArray *mat; 4253308dcc3eSBarry Smith PetscInt i; 4254308dcc3eSBarry Smith PetscReal *ar; 4255308dcc3eSBarry Smith 4256308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len, 1, mxREAL); 4257308dcc3eSBarry Smith ar = (PetscReal *)mxGetData(mat); 4258f5af7f23SKarl Rupp for (i = 0; i < snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 425911cc89d2SBarry Smith return mat; 4260308dcc3eSBarry Smith } 4261308dcc3eSBarry Smith #endif 4262308dcc3eSBarry Smith 42630c4c9dddSBarry Smith /*@C 4264758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 4265758f92a0SBarry Smith 42663f9fe445SBarry Smith Not Collective 4267758f92a0SBarry Smith 4268758f92a0SBarry Smith Input Parameter: 4269f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 4270758f92a0SBarry Smith 4271758f92a0SBarry Smith Output Parameters: 4272f6dfbefdSBarry Smith + a - array to hold history, usually was set with `SNESSetConvergenceHistory()` 4273758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 4274758f92a0SBarry Smith negative if not converged) for each solve. 4275758f92a0SBarry Smith - na - size of a and its 4276758f92a0SBarry Smith 4277758f92a0SBarry Smith Notes: 4278758f92a0SBarry Smith The calling sequence for this routine in Fortran is 4279758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 4280758f92a0SBarry Smith 4281758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 4282758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 4283758f92a0SBarry Smith during the section of code that is being timed. 4284758f92a0SBarry Smith 4285758f92a0SBarry Smith Level: intermediate 4286758f92a0SBarry Smith 4287f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESSetConvergenceHistory()` 4288758f92a0SBarry Smith @*/ 4289d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergenceHistory(SNES snes, PetscReal *a[], PetscInt *its[], PetscInt *na) 4290d71ae5a4SJacob Faibussowitsch { 4291758f92a0SBarry Smith PetscFunctionBegin; 42920700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4293758f92a0SBarry Smith if (a) *a = snes->conv_hist; 4294758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 4295115dd874SBarry Smith if (na) *na = (PetscInt)snes->conv_hist_len; 42963a40ed3dSBarry Smith PetscFunctionReturn(0); 4297c9005455SLois Curfman McInnes } 4298c9005455SLois Curfman McInnes 4299ac226902SBarry Smith /*@C 430076b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 4301eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 43027e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 430376b2cf59SMatthew Knepley 4304*c3339decSBarry Smith Logically Collective 430576b2cf59SMatthew Knepley 430676b2cf59SMatthew Knepley Input Parameters: 4307a2b725a8SWilliam Gropp + snes - The nonlinear solver context 4308a2b725a8SWilliam Gropp - func - The function 430976b2cf59SMatthew Knepley 431076b2cf59SMatthew Knepley Calling sequence of func: 4311a2b725a8SWilliam Gropp $ func (SNES snes, PetscInt step); 431276b2cf59SMatthew Knepley 431376b2cf59SMatthew Knepley . step - The current step of the iteration 431476b2cf59SMatthew Knepley 4315fe97e370SBarry Smith Level: advanced 4316fe97e370SBarry Smith 43176b7fb656SBarry Smith Note: 4318f6dfbefdSBarry 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 4319f6dfbefdSBarry Smith to `SNESSetFunction()`, or `SNESSetPicard()` 4320fe97e370SBarry Smith This is not used by most users. 432176b2cf59SMatthew Knepley 43226b7fb656SBarry Smith There are a varity of function hooks one many set that are called at different stages of the nonlinear solution process, see the functions listed below. 43236b7fb656SBarry Smith 4324f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESSetJacobian()`, `SNESSolve()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRSetPostCheck()`, 4325db781477SPatrick Sanan `SNESMonitorSet()`, `SNESSetDivergenceTest()` 432676b2cf59SMatthew Knepley @*/ 4327d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 4328d71ae5a4SJacob Faibussowitsch { 432976b2cf59SMatthew Knepley PetscFunctionBegin; 43300700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4331e7788613SBarry Smith snes->ops->update = func; 433276b2cf59SMatthew Knepley PetscFunctionReturn(0); 433376b2cf59SMatthew Knepley } 433476b2cf59SMatthew Knepley 43359b94acceSBarry Smith /* 43369b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 43379b94acceSBarry Smith positive parameter delta. 43389b94acceSBarry Smith 43399b94acceSBarry Smith Input Parameters: 4340f6dfbefdSBarry Smith + snes - the `SNES` context 43419b94acceSBarry Smith . y - approximate solution of linear system 43429b94acceSBarry Smith . fnorm - 2-norm of current function 4343c7afd0dbSLois Curfman McInnes - delta - trust region size 43449b94acceSBarry Smith 43459b94acceSBarry Smith Output Parameters: 4346c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 43479b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 43489b94acceSBarry Smith region, and exceeds zero otherwise. 4349c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 43509b94acceSBarry Smith 4351f6dfbefdSBarry Smith Level: developer 43529b94acceSBarry Smith 4353f6dfbefdSBarry Smith Note: 4354f6dfbefdSBarry Smith For non-trust region methods such as `SNESNEWTONLS`, the parameter delta 4355f6dfbefdSBarry Smith is set to be the maximum allowable step size. 43569b94acceSBarry Smith */ 4357d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESScaleStep_Private(SNES snes, Vec y, PetscReal *fnorm, PetscReal *delta, PetscReal *gpnorm, PetscReal *ynorm) 4358d71ae5a4SJacob Faibussowitsch { 4359064f8208SBarry Smith PetscReal nrm; 4360ea709b57SSatish Balay PetscScalar cnorm; 43613a40ed3dSBarry Smith 43623a40ed3dSBarry Smith PetscFunctionBegin; 43630700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 43640700a824SBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 2); 4365c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, y, 2); 4366184914b5SBarry Smith 43679566063dSJacob Faibussowitsch PetscCall(VecNorm(y, NORM_2, &nrm)); 4368064f8208SBarry Smith if (nrm > *delta) { 4369064f8208SBarry Smith nrm = *delta / nrm; 4370064f8208SBarry Smith *gpnorm = (1.0 - nrm) * (*fnorm); 4371064f8208SBarry Smith cnorm = nrm; 43729566063dSJacob Faibussowitsch PetscCall(VecScale(y, cnorm)); 43739b94acceSBarry Smith *ynorm = *delta; 43749b94acceSBarry Smith } else { 43759b94acceSBarry Smith *gpnorm = 0.0; 4376064f8208SBarry Smith *ynorm = nrm; 43779b94acceSBarry Smith } 43783a40ed3dSBarry Smith PetscFunctionReturn(0); 43799b94acceSBarry Smith } 43809b94acceSBarry Smith 438191f3e32bSBarry Smith /*@C 4382f6dfbefdSBarry Smith SNESConvergedReasonView - Displays the reason a `SNES` solve converged or diverged to a viewer 43832a359c20SBarry Smith 4384*c3339decSBarry Smith Collective 43852a359c20SBarry Smith 43862a359c20SBarry Smith Parameter: 4387f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 43882a359c20SBarry Smith - viewer - the viewer to display the reason 43892a359c20SBarry Smith 43902a359c20SBarry Smith Options Database Keys: 4391ee300463SSatish Balay + -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 4392ee300463SSatish Balay - -snes_converged_reason ::failed - only print reason and number of iterations when diverged 4393eafd5ff0SAlex Lindsay 4394f6dfbefdSBarry Smith Note: 4395f6dfbefdSBarry Smith To change the format of the output call `PetscViewerPushFormat`(viewer,format) before this call. Use `PETSC_VIEWER_DEFAULT` for the default, 4396f6dfbefdSBarry Smith use `PETSC_VIEWER_FAILED` to only display a reason if it fails. 43972a359c20SBarry Smith 43982a359c20SBarry Smith Level: beginner 43992a359c20SBarry Smith 4400f6dfbefdSBarry Smith .seealso: `SNESConvergedReason`, `PetscViewer`, `SNES`, 4401f6dfbefdSBarry Smith `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, 4402f6dfbefdSBarry Smith `SNESConvergedReasonViewFromOptions()`, 4403db781477SPatrick Sanan `PetscViewerPushFormat()`, `PetscViewerPopFormat()` 44042a359c20SBarry Smith @*/ 4405d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonView(SNES snes, PetscViewer viewer) 4406d71ae5a4SJacob Faibussowitsch { 440775cca76cSMatthew G. Knepley PetscViewerFormat format; 44082a359c20SBarry Smith PetscBool isAscii; 44092a359c20SBarry Smith 44102a359c20SBarry Smith PetscFunctionBegin; 441119a666eeSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 44129566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii)); 44132a359c20SBarry Smith if (isAscii) { 44149566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 44159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 441675cca76cSMatthew G. Knepley if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 441775cca76cSMatthew G. Knepley DM dm; 441875cca76cSMatthew G. Knepley Vec u; 441975cca76cSMatthew G. Knepley PetscDS prob; 442075cca76cSMatthew G. Knepley PetscInt Nf, f; 442195cbbfd3SMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 442295cbbfd3SMatthew G. Knepley void **exactCtx; 442375cca76cSMatthew G. Knepley PetscReal error; 442475cca76cSMatthew G. Knepley 44259566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 44269566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &u)); 44279566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 44289566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(prob, &Nf)); 44299566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &exactSol, Nf, &exactCtx)); 44309566063dSJacob Faibussowitsch for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f])); 44319566063dSJacob Faibussowitsch PetscCall(DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error)); 44329566063dSJacob Faibussowitsch PetscCall(PetscFree2(exactSol, exactCtx)); 44339566063dSJacob Faibussowitsch if (error < 1.0e-11) PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n")); 443463a3b9bcSJacob Faibussowitsch else PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", (double)error)); 443575cca76cSMatthew G. Knepley } 4436eafd5ff0SAlex Lindsay if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) { 44372a359c20SBarry Smith if (((PetscObject)snes)->prefix) { 443863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear %s solve converged due to %s iterations %" PetscInt_FMT "\n", ((PetscObject)snes)->prefix, SNESConvergedReasons[snes->reason], snes->iter)); 44392a359c20SBarry Smith } else { 444063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve converged due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter)); 44412a359c20SBarry Smith } 4442eafd5ff0SAlex Lindsay } else if (snes->reason <= 0) { 44432a359c20SBarry Smith if (((PetscObject)snes)->prefix) { 444463a3b9bcSJacob 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)); 44452a359c20SBarry Smith } else { 444663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve did not converge due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter)); 44472a359c20SBarry Smith } 44482a359c20SBarry Smith } 44499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 44502a359c20SBarry Smith } 44512a359c20SBarry Smith PetscFunctionReturn(0); 44522a359c20SBarry Smith } 44532a359c20SBarry Smith 4454c4421ceaSFande Kong /*@C 4455c4421ceaSFande Kong SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the 4456c4421ceaSFande Kong end of the nonlinear solver to display the conver reason of the nonlinear solver. 4457c4421ceaSFande Kong 4458*c3339decSBarry Smith Logically Collective 4459c4421ceaSFande Kong 4460c4421ceaSFande Kong Input Parameters: 4461f6dfbefdSBarry Smith + snes - the `SNES` context 4462c4421ceaSFande Kong . f - the snes converged reason view function 4463c4421ceaSFande Kong . vctx - [optional] user-defined context for private data for the 4464c4421ceaSFande Kong snes converged reason view routine (use NULL if no context is desired) 4465c4421ceaSFande Kong - reasonviewdestroy - [optional] routine that frees reasonview context 4466c4421ceaSFande Kong (may be NULL) 4467c4421ceaSFande Kong 4468c4421ceaSFande Kong Options Database Keys: 4469f6dfbefdSBarry Smith + -snes_converged_reason - sets a default `SNESConvergedReasonView()` 4470c4421ceaSFande Kong - -snes_converged_reason_view_cancel - cancels all converged reason viewers that have 4471c4421ceaSFande Kong been hardwired into a code by 4472f6dfbefdSBarry Smith calls to `SNESConvergedReasonViewSet()`, but 4473c4421ceaSFande Kong does not cancel those set via 4474c4421ceaSFande Kong the options database. 4475c4421ceaSFande Kong 4476f6dfbefdSBarry Smith Note: 4477c4421ceaSFande Kong Several different converged reason view routines may be set by calling 4478f6dfbefdSBarry Smith `SNESConvergedReasonViewSet()` multiple times; all will be called in the 4479c4421ceaSFande Kong order in which they were set. 4480c4421ceaSFande Kong 4481c4421ceaSFande Kong Level: intermediate 4482c4421ceaSFande Kong 4483f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESConvergedReason`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()`, `SNESConvergedReasonViewCancel()` 4484c4421ceaSFande Kong @*/ 4485d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewSet(SNES snes, PetscErrorCode (*f)(SNES, void *), void *vctx, PetscErrorCode (*reasonviewdestroy)(void **)) 4486d71ae5a4SJacob Faibussowitsch { 4487c4421ceaSFande Kong PetscInt i; 4488c4421ceaSFande Kong PetscBool identical; 4489c4421ceaSFande Kong 4490c4421ceaSFande Kong PetscFunctionBegin; 4491c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4492c4421ceaSFande Kong for (i = 0; i < snes->numberreasonviews; i++) { 44939566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, vctx, reasonviewdestroy, (PetscErrorCode(*)(void))snes->reasonview[i], snes->reasonviewcontext[i], snes->reasonviewdestroy[i], &identical)); 4494c4421ceaSFande Kong if (identical) PetscFunctionReturn(0); 4495c4421ceaSFande Kong } 44965f80ce2aSJacob Faibussowitsch PetscCheck(snes->numberreasonviews < MAXSNESREASONVIEWS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many SNES reasonview set"); 4497c4421ceaSFande Kong snes->reasonview[snes->numberreasonviews] = f; 4498c4421ceaSFande Kong snes->reasonviewdestroy[snes->numberreasonviews] = reasonviewdestroy; 4499c4421ceaSFande Kong snes->reasonviewcontext[snes->numberreasonviews++] = (void *)vctx; 4500c4421ceaSFande Kong PetscFunctionReturn(0); 4501c4421ceaSFande Kong } 4502c4421ceaSFande Kong 450391f3e32bSBarry Smith /*@ 4504f6dfbefdSBarry Smith SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a `SNESConvergedReason` is to be viewed. 4505c4421ceaSFande Kong All the user-provided convergedReasonView routines will be involved as well, if they exist. 45062a359c20SBarry Smith 4507*c3339decSBarry Smith Collective 45082a359c20SBarry Smith 45092a359c20SBarry Smith Input Parameters: 4510f6dfbefdSBarry Smith . snes - the `SNES` object 45112a359c20SBarry Smith 4512f6dfbefdSBarry Smith Level: advanced 45132a359c20SBarry Smith 4514f6dfbefdSBarry Smith .seealso: `SNES`, `SNESConvergedReason`, `SNESConvergedReasonViewSet()`, `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, 4515f6dfbefdSBarry Smith `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()` 45162a359c20SBarry Smith @*/ 4517d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes) 4518d71ae5a4SJacob Faibussowitsch { 45192a359c20SBarry Smith PetscViewer viewer; 45202a359c20SBarry Smith PetscBool flg; 45212a359c20SBarry Smith static PetscBool incall = PETSC_FALSE; 45222a359c20SBarry Smith PetscViewerFormat format; 4523c4421ceaSFande Kong PetscInt i; 45242a359c20SBarry Smith 45252a359c20SBarry Smith PetscFunctionBegin; 45262a359c20SBarry Smith if (incall) PetscFunctionReturn(0); 45272a359c20SBarry Smith incall = PETSC_TRUE; 4528c4421ceaSFande Kong 4529c4421ceaSFande Kong /* All user-provided viewers are called first, if they exist. */ 453048a46eb9SPierre Jolivet for (i = 0; i < snes->numberreasonviews; i++) PetscCall((*snes->reasonview[i])(snes, snes->reasonviewcontext[i])); 4531c4421ceaSFande Kong 4532c4421ceaSFande Kong /* Call PETSc default routine if users ask for it */ 45339566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_converged_reason", &viewer, &format, &flg)); 45342a359c20SBarry Smith if (flg) { 45359566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 45369566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonView(snes, viewer)); 45379566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 45389566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 45392a359c20SBarry Smith } 45402a359c20SBarry Smith incall = PETSC_FALSE; 45412a359c20SBarry Smith PetscFunctionReturn(0); 45422a359c20SBarry Smith } 45432a359c20SBarry Smith 4544487a658cSBarry Smith /*@ 4545f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 4546f6dfbefdSBarry Smith Call `SNESSolve()` after calling `SNESCreate()` and optional routines of the form `SNESSetXXX()`. 45479b94acceSBarry Smith 4548*c3339decSBarry Smith Collective 4549c7afd0dbSLois Curfman McInnes 4550b2002411SLois Curfman McInnes Input Parameters: 4551f6dfbefdSBarry Smith + snes - the `SNES` context 45520298fd71SBarry Smith . b - the constant part of the equation F(x) = b, or NULL to use zero. 455385385478SLisandro Dalcin - x - the solution vector. 45549b94acceSBarry Smith 4555f6dfbefdSBarry Smith Note: 45568ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 4557f6dfbefdSBarry Smith for the nonlinear solve prior to calling `SNESSolve()`. In particular, 45588ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 4559f6dfbefdSBarry Smith this vector to zero by calling `VecSet()`. 45608ddd3da0SLois Curfman McInnes 456136851e7fSLois Curfman McInnes Level: beginner 456236851e7fSLois Curfman McInnes 4563f6dfbefdSBarry Smith .seealso: `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESSetFunction()`, `SNESSetJacobian()`, `SNESSetGridSequence()`, `SNESGetSolution()`, 4564db781477SPatrick Sanan `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRGetPreCheck()`, `SNESNewtonTRSetPostCheck()`, `SNESNewtonTRGetPostCheck()`, 4565db781477SPatrick Sanan `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()` 45669b94acceSBarry Smith @*/ 4567d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSolve(SNES snes, Vec b, Vec x) 4568d71ae5a4SJacob Faibussowitsch { 4569ace3abfcSBarry Smith PetscBool flg; 4570efd51863SBarry Smith PetscInt grid; 45710298fd71SBarry Smith Vec xcreated = NULL; 4572caa4e7f2SJed Brown DM dm; 4573052efed2SBarry Smith 45743a40ed3dSBarry Smith PetscFunctionBegin; 45750700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4576a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 4577a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes, 1, x, 3); 45780700a824SBarry Smith if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 457985385478SLisandro Dalcin if (b) PetscCheckSameComm(snes, 1, b, 2); 458085385478SLisandro Dalcin 458134b4d3a8SMatthew G. Knepley /* High level operations using the nonlinear solver */ 458206fc46c8SMatthew G. Knepley { 458306fc46c8SMatthew G. Knepley PetscViewer viewer; 458406fc46c8SMatthew G. Knepley PetscViewerFormat format; 45857c88af5aSMatthew G. Knepley PetscInt num; 458606fc46c8SMatthew G. Knepley PetscBool flg; 458706fc46c8SMatthew G. Knepley static PetscBool incall = PETSC_FALSE; 458806fc46c8SMatthew G. Knepley 458906fc46c8SMatthew G. Knepley if (!incall) { 459034b4d3a8SMatthew G. Knepley /* Estimate the convergence rate of the discretization */ 45919566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg)); 459206fc46c8SMatthew G. Knepley if (flg) { 459306fc46c8SMatthew G. Knepley PetscConvEst conv; 459446079b62SMatthew G. Knepley DM dm; 459546079b62SMatthew G. Knepley PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 459646079b62SMatthew G. Knepley PetscInt Nf; 459706fc46c8SMatthew G. Knepley 459806fc46c8SMatthew G. Knepley incall = PETSC_TRUE; 45999566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 46009566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 46019566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nf, &alpha)); 46029566063dSJacob Faibussowitsch PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject)snes), &conv)); 46039566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetSolver(conv, (PetscObject)snes)); 46049566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetFromOptions(conv)); 46059566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetUp(conv)); 46069566063dSJacob Faibussowitsch PetscCall(PetscConvEstGetConvRate(conv, alpha)); 46079566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 46089566063dSJacob Faibussowitsch PetscCall(PetscConvEstRateView(conv, alpha, viewer)); 46099566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 46109566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 46119566063dSJacob Faibussowitsch PetscCall(PetscConvEstDestroy(&conv)); 46129566063dSJacob Faibussowitsch PetscCall(PetscFree(alpha)); 461306fc46c8SMatthew G. Knepley incall = PETSC_FALSE; 461406fc46c8SMatthew G. Knepley } 461534b4d3a8SMatthew G. Knepley /* Adaptively refine the initial grid */ 4616b2588ea6SMatthew G. Knepley num = 1; 46179566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_initial", &num, &flg)); 461834b4d3a8SMatthew G. Knepley if (flg) { 461934b4d3a8SMatthew G. Knepley DMAdaptor adaptor; 462034b4d3a8SMatthew G. Knepley 462134b4d3a8SMatthew G. Knepley incall = PETSC_TRUE; 46229566063dSJacob Faibussowitsch PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 46239566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSolver(adaptor, snes)); 46249566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 46259566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetFromOptions(adaptor)); 46269566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetUp(adaptor)); 46279566063dSJacob Faibussowitsch PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x)); 46289566063dSJacob Faibussowitsch PetscCall(DMAdaptorDestroy(&adaptor)); 462934b4d3a8SMatthew G. Knepley incall = PETSC_FALSE; 463034b4d3a8SMatthew G. Knepley } 46317c88af5aSMatthew G. Knepley /* Use grid sequencing to adapt */ 46327c88af5aSMatthew G. Knepley num = 0; 46339566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_sequence", &num, NULL)); 46347c88af5aSMatthew G. Knepley if (num) { 46357c88af5aSMatthew G. Knepley DMAdaptor adaptor; 46367c88af5aSMatthew G. Knepley 46377c88af5aSMatthew G. Knepley incall = PETSC_TRUE; 46389566063dSJacob Faibussowitsch PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 46399566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSolver(adaptor, snes)); 46409566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 46419566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetFromOptions(adaptor)); 46429566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetUp(adaptor)); 46439566063dSJacob Faibussowitsch PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x)); 46449566063dSJacob Faibussowitsch PetscCall(DMAdaptorDestroy(&adaptor)); 46457c88af5aSMatthew G. Knepley incall = PETSC_FALSE; 46467c88af5aSMatthew G. Knepley } 464706fc46c8SMatthew G. Knepley } 464806fc46c8SMatthew G. Knepley } 4649ad540459SPierre Jolivet if (!x) x = snes->vec_sol; 4650caa4e7f2SJed Brown if (!x) { 46519566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 46529566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dm, &xcreated)); 4653a69afd8bSBarry Smith x = xcreated; 4654a69afd8bSBarry Smith } 46559566063dSJacob Faibussowitsch PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view_pre")); 4656f05ece33SBarry Smith 46579566063dSJacob Faibussowitsch for (grid = 0; grid < snes->gridsequence; grid++) PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4658efd51863SBarry Smith for (grid = 0; grid < snes->gridsequence + 1; grid++) { 465985385478SLisandro Dalcin /* set solution vector */ 46609566063dSJacob Faibussowitsch if (!grid) PetscCall(PetscObjectReference((PetscObject)x)); 46619566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 466285385478SLisandro Dalcin snes->vec_sol = x; 46639566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 4664caa4e7f2SJed Brown 4665caa4e7f2SJed Brown /* set affine vector if provided */ 46669566063dSJacob Faibussowitsch if (b) PetscCall(PetscObjectReference((PetscObject)b)); 46679566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_rhs)); 466885385478SLisandro Dalcin snes->vec_rhs = b; 466985385478SLisandro Dalcin 46705f80ce2aSJacob 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"); 46715f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_func != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be function vector"); 46725f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_rhs != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be right hand side vector"); 46734dfa11a4SJacob Faibussowitsch if (!snes->vec_sol_update /* && snes->vec_sol */) { PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_sol_update)); } 46749566063dSJacob Faibussowitsch PetscCall(DMShellSetGlobalVector(dm, snes->vec_sol)); 46759566063dSJacob Faibussowitsch PetscCall(SNESSetUp(snes)); 46763f149594SLisandro Dalcin 46777eee914bSBarry Smith if (!grid) { 467825e27a38SBarry Smith if (snes->ops->computeinitialguess) PetscCallBack("SNES callback initial guess", (*snes->ops->computeinitialguess)(snes, snes->vec_sol, snes->initialguessP)); 4679dd568438SSatish Balay } 4680d25893d9SBarry Smith 4681abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 46829371c9d4SSatish Balay if (snes->counters_reset) { 46839371c9d4SSatish Balay snes->nfuncs = 0; 46849371c9d4SSatish Balay snes->linear_its = 0; 46859371c9d4SSatish Balay snes->numFailures = 0; 46869371c9d4SSatish Balay } 4687d5e45103SBarry Smith 46889566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_Solve, snes, 0, 0, 0)); 4689dbbe0bcdSBarry Smith PetscUseTypeMethod(snes, solve); 46909566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_Solve, snes, 0, 0, 0)); 46915f80ce2aSJacob Faibussowitsch PetscCheck(snes->reason, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Internal error, solver returned without setting converged reason"); 4692422a814eSBarry Smith snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 46933f149594SLisandro Dalcin 469437ec4e1aSPeter Brune if (snes->lagjac_persist) snes->jac_iter += snes->iter; 469537ec4e1aSPeter Brune if (snes->lagpre_persist) snes->pre_iter += snes->iter; 469637ec4e1aSPeter Brune 46979566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_test_local_min", NULL, NULL, &flg)); 46989566063dSJacob Faibussowitsch if (flg && !PetscPreLoadingOn) PetscCall(SNESTestLocalMin(snes)); 4699c4421ceaSFande Kong /* Call converged reason views. This may involve user-provided viewers as well */ 47009566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonViewFromOptions(snes)); 47015968eb51SBarry Smith 47025f80ce2aSJacob Faibussowitsch if (snes->errorifnotconverged) PetscCheck(snes->reason >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_NOT_CONVERGED, "SNESSolve has not converged"); 47039c8e83a9SBarry Smith if (snes->reason < 0) break; 4704efd51863SBarry Smith if (grid < snes->gridsequence) { 4705efd51863SBarry Smith DM fine; 4706efd51863SBarry Smith Vec xnew; 4707efd51863SBarry Smith Mat interp; 4708efd51863SBarry Smith 47099566063dSJacob Faibussowitsch PetscCall(DMRefine(snes->dm, PetscObjectComm((PetscObject)snes), &fine)); 47105f80ce2aSJacob Faibussowitsch PetscCheck(fine, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_INCOMP, "DMRefine() did not perform any refinement, cannot continue grid sequencing"); 47119566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(snes->dm, fine, &interp, NULL)); 47129566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(fine, &xnew)); 47139566063dSJacob Faibussowitsch PetscCall(MatInterpolate(interp, x, xnew)); 47149566063dSJacob Faibussowitsch PetscCall(DMInterpolate(snes->dm, interp, fine)); 47159566063dSJacob Faibussowitsch PetscCall(MatDestroy(&interp)); 4716efd51863SBarry Smith x = xnew; 4717efd51863SBarry Smith 47189566063dSJacob Faibussowitsch PetscCall(SNESReset(snes)); 47199566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes, fine)); 47209566063dSJacob Faibussowitsch PetscCall(SNESResetFromOptions(snes)); 47219566063dSJacob Faibussowitsch PetscCall(DMDestroy(&fine)); 47229566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4723efd51863SBarry Smith } 4724efd51863SBarry Smith } 47259566063dSJacob Faibussowitsch PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view")); 47269566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(snes->vec_sol, (PetscObject)snes, "-snes_view_solution")); 47279566063dSJacob Faibussowitsch PetscCall(DMMonitor(snes->dm)); 47289566063dSJacob Faibussowitsch PetscCall(SNESMonitorPauseFinal_Internal(snes)); 47293f7e2da0SPeter Brune 47309566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xcreated)); 47319566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsBlock((PetscObject)snes)); 47323a40ed3dSBarry Smith PetscFunctionReturn(0); 47339b94acceSBarry Smith } 47349b94acceSBarry Smith 47359b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 47369b94acceSBarry Smith 473782bf6240SBarry Smith /*@C 47384b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 47399b94acceSBarry Smith 4740*c3339decSBarry Smith Collective 4741fee21e36SBarry Smith 4742c7afd0dbSLois Curfman McInnes Input Parameters: 4743f6dfbefdSBarry Smith + snes - the `SNES` context 4744454a90a3SBarry Smith - type - a known method 4745c7afd0dbSLois Curfman McInnes 4746c7afd0dbSLois Curfman McInnes Options Database Key: 4747454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 474804d7464bSBarry Smith of available methods (for instance, newtonls or newtontr) 4749ae12b187SLois Curfman McInnes 47509b94acceSBarry Smith Notes: 4751e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 4752f6dfbefdSBarry Smith + `SNESNEWTONLS` - Newton's method with line search 4753c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 4754f6dfbefdSBarry Smith - `SNESNEWTONTRDC` - Newton's method with trust region 4755c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 47569b94acceSBarry Smith 4757f6dfbefdSBarry Smith Normally, it is best to use the `SNESSetFromOptions()` command and then 4758f6dfbefdSBarry Smith set the `SNES` solver type from the options database rather than by using 4759ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 4760ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 4761f6dfbefdSBarry Smith The `SNESSetType()` routine is provided for those situations where it 4762ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 4763ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 4764ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 4765ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 4766b0a32e0cSBarry Smith appropriate method. 476736851e7fSLois Curfman McInnes 4768f6dfbefdSBarry Smith Developer Note: 4769f6dfbefdSBarry Smith `SNESRegister()` adds a constructor for a new `SNESType` to `SNESList`, `SNESSetType()` locates 4770f6dfbefdSBarry Smith the constructor in that list and calls it to create the specific object. 47718f6c3df8SBarry Smith 477236851e7fSLois Curfman McInnes Level: intermediate 4773a703fe33SLois Curfman McInnes 4774f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESType`, `SNESCreate()`, `SNESDestroy()`, `SNESGetType()`, `SNESSetFromOptions()` 47759b94acceSBarry Smith @*/ 4776d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetType(SNES snes, SNESType type) 4777d71ae5a4SJacob Faibussowitsch { 4778ace3abfcSBarry Smith PetscBool match; 47795f80ce2aSJacob Faibussowitsch PetscErrorCode (*r)(SNES); 47803a40ed3dSBarry Smith 47813a40ed3dSBarry Smith PetscFunctionBegin; 47820700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 47834482741eSBarry Smith PetscValidCharPointer(type, 2); 478482bf6240SBarry Smith 47859566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, type, &match)); 47860f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 478792ff6ae8SBarry Smith 47889566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(SNESList, type, &r)); 47895f80ce2aSJacob Faibussowitsch PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested SNES type %s", type); 479075396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 4791dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, destroy); 479275396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 47939e5d0892SLisandro Dalcin snes->ops->setup = NULL; 47949e5d0892SLisandro Dalcin snes->ops->solve = NULL; 47959e5d0892SLisandro Dalcin snes->ops->view = NULL; 47969e5d0892SLisandro Dalcin snes->ops->setfromoptions = NULL; 47979e5d0892SLisandro Dalcin snes->ops->destroy = NULL; 47987fe760d5SStefano Zampini 47997fe760d5SStefano Zampini /* It may happen the user has customized the line search before calling SNESSetType */ 48009566063dSJacob Faibussowitsch if (((PetscObject)snes)->type_name) PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 48017fe760d5SStefano Zampini 480275396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 480375396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 4804f5af7f23SKarl Rupp 48059566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)snes, type)); 48069566063dSJacob Faibussowitsch PetscCall((*r)(snes)); 48073a40ed3dSBarry Smith PetscFunctionReturn(0); 48089b94acceSBarry Smith } 48099b94acceSBarry Smith 48109b94acceSBarry Smith /*@C 4811f6dfbefdSBarry Smith SNESGetType - Gets the `SNES` method type and name (as a string). 48129b94acceSBarry Smith 4813c7afd0dbSLois Curfman McInnes Not Collective 4814c7afd0dbSLois Curfman McInnes 48159b94acceSBarry Smith Input Parameter: 48164b0e389bSBarry Smith . snes - nonlinear solver context 48179b94acceSBarry Smith 48189b94acceSBarry Smith Output Parameter: 4819f6dfbefdSBarry Smith . type - `SNES` method (a character string) 48209b94acceSBarry Smith 482136851e7fSLois Curfman McInnes Level: intermediate 482236851e7fSLois Curfman McInnes 4823f6dfbefdSBarry Smith .seealso: `SNESSetType()`, `SNESType`, `SNESSetFromOptions()`, `SNES` 48249b94acceSBarry Smith @*/ 4825d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetType(SNES snes, SNESType *type) 4826d71ae5a4SJacob Faibussowitsch { 48273a40ed3dSBarry Smith PetscFunctionBegin; 48280700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48294482741eSBarry Smith PetscValidPointer(type, 2); 48307adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 48313a40ed3dSBarry Smith PetscFunctionReturn(0); 48329b94acceSBarry Smith } 48339b94acceSBarry Smith 48343cd8a7caSMatthew G. Knepley /*@ 4835f6dfbefdSBarry Smith SNESSetSolution - Sets the solution vector for use by the `SNES` routines. 48363cd8a7caSMatthew G. Knepley 4837*c3339decSBarry Smith Logically Collective 48383cd8a7caSMatthew G. Knepley 48393cd8a7caSMatthew G. Knepley Input Parameters: 4840f6dfbefdSBarry Smith + snes - the `SNES` context obtained from `SNESCreate()` 48413cd8a7caSMatthew G. Knepley - u - the solution vector 48423cd8a7caSMatthew G. Knepley 48433cd8a7caSMatthew G. Knepley Level: beginner 48443cd8a7caSMatthew G. Knepley 4845f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESGetSolution()`, `Vec` 48463cd8a7caSMatthew G. Knepley @*/ 4847d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetSolution(SNES snes, Vec u) 4848d71ae5a4SJacob Faibussowitsch { 48493cd8a7caSMatthew G. Knepley DM dm; 48503cd8a7caSMatthew G. Knepley 48513cd8a7caSMatthew G. Knepley PetscFunctionBegin; 48523cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48533cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 48549566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)u)); 48559566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 48563cd8a7caSMatthew G. Knepley 48573cd8a7caSMatthew G. Knepley snes->vec_sol = u; 48583cd8a7caSMatthew G. Knepley 48599566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 48609566063dSJacob Faibussowitsch PetscCall(DMShellSetGlobalVector(dm, u)); 48613cd8a7caSMatthew G. Knepley PetscFunctionReturn(0); 48623cd8a7caSMatthew G. Knepley } 48633cd8a7caSMatthew G. Knepley 486452baeb72SSatish Balay /*@ 48659b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 4866f6dfbefdSBarry Smith stored. This is the fine grid solution when using `SNESSetGridSequence()`. 48679b94acceSBarry Smith 4868f6dfbefdSBarry Smith Not Collective, but x is parallel if snes is parallel 4869c7afd0dbSLois Curfman McInnes 48709b94acceSBarry Smith Input Parameter: 4871f6dfbefdSBarry Smith . snes - the `SNES` context 48729b94acceSBarry Smith 48739b94acceSBarry Smith Output Parameter: 48749b94acceSBarry Smith . x - the solution 48759b94acceSBarry Smith 487670e92668SMatthew Knepley Level: intermediate 487736851e7fSLois Curfman McInnes 4878f6dfbefdSBarry Smith .seealso: `SNESSetSolution()`, `SNESSolve()`, `SNES`, `SNESGetSolutionUpdate()`, `SNESGetFunction()` 48799b94acceSBarry Smith @*/ 4880d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolution(SNES snes, Vec *x) 4881d71ae5a4SJacob Faibussowitsch { 48823a40ed3dSBarry Smith PetscFunctionBegin; 48830700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48844482741eSBarry Smith PetscValidPointer(x, 2); 488585385478SLisandro Dalcin *x = snes->vec_sol; 488670e92668SMatthew Knepley PetscFunctionReturn(0); 488770e92668SMatthew Knepley } 488870e92668SMatthew Knepley 488952baeb72SSatish Balay /*@ 48909b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 48919b94acceSBarry Smith stored. 48929b94acceSBarry Smith 4893f6dfbefdSBarry Smith Not Collective, but x is parallel if snes is parallel 4894c7afd0dbSLois Curfman McInnes 48959b94acceSBarry Smith Input Parameter: 4896f6dfbefdSBarry Smith . snes - the `SNES` context 48979b94acceSBarry Smith 48989b94acceSBarry Smith Output Parameter: 48999b94acceSBarry Smith . x - the solution update 49009b94acceSBarry Smith 490136851e7fSLois Curfman McInnes Level: advanced 490236851e7fSLois Curfman McInnes 4903f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetSolution()`, `SNESGetFunction()` 49049b94acceSBarry Smith @*/ 4905d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolutionUpdate(SNES snes, Vec *x) 4906d71ae5a4SJacob Faibussowitsch { 49073a40ed3dSBarry Smith PetscFunctionBegin; 49080700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49094482741eSBarry Smith PetscValidPointer(x, 2); 491085385478SLisandro Dalcin *x = snes->vec_sol_update; 49113a40ed3dSBarry Smith PetscFunctionReturn(0); 49129b94acceSBarry Smith } 49139b94acceSBarry Smith 49149b94acceSBarry Smith /*@C 4915f6dfbefdSBarry Smith SNESGetFunction - Returns the function that defines the nonlinear system set with `SNESSetFunction()` 49169b94acceSBarry Smith 4917f6dfbefdSBarry Smith Not Collective, but r is parallel if snes is parallel. Collective if r is requested, but has not been created yet. 4918c7afd0dbSLois Curfman McInnes 49199b94acceSBarry Smith Input Parameter: 4920f6dfbefdSBarry Smith . snes - the `SNES` context 49219b94acceSBarry Smith 4922d8d19677SJose E. Roman Output Parameters: 49230298fd71SBarry Smith + r - the vector that is used to store residuals (or NULL if you don't want it) 4924f6dfbefdSBarry Smith . f - the function (or NULL if you don't want it); see `SNESFunction` for calling sequence details 49250298fd71SBarry Smith - ctx - the function context (or NULL if you don't want it) 49269b94acceSBarry Smith 492736851e7fSLois Curfman McInnes Level: advanced 492836851e7fSLois Curfman McInnes 4929f6dfbefdSBarry Smith Note: 4930f6dfbefdSBarry Smith The vector r DOES NOT, in general, contain the current value of the `SNES` nonlinear function 493104edfde5SBarry Smith 4932f6dfbefdSBarry Smith .seealso: `SNES, `SNESSolve()`, `SNESSetFunction()`, `SNESGetSolution()`, `SNESFunction` 49339b94acceSBarry Smith @*/ 4934d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunction(SNES snes, Vec *r, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) 4935d71ae5a4SJacob Faibussowitsch { 49366cab3a1bSJed Brown DM dm; 4937a63bb30eSJed Brown 49383a40ed3dSBarry Smith PetscFunctionBegin; 49390700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4940a63bb30eSJed Brown if (r) { 4941a63bb30eSJed Brown if (!snes->vec_func) { 4942a63bb30eSJed Brown if (snes->vec_rhs) { 49439566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_rhs, &snes->vec_func)); 4944a63bb30eSJed Brown } else if (snes->vec_sol) { 49459566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_func)); 4946a63bb30eSJed Brown } else if (snes->dm) { 49479566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(snes->dm, &snes->vec_func)); 4948a63bb30eSJed Brown } 4949a63bb30eSJed Brown } 4950a63bb30eSJed Brown *r = snes->vec_func; 4951a63bb30eSJed Brown } 49529566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 49539566063dSJacob Faibussowitsch PetscCall(DMSNESGetFunction(dm, f, ctx)); 49543a40ed3dSBarry Smith PetscFunctionReturn(0); 49559b94acceSBarry Smith } 49569b94acceSBarry Smith 4957c79ef259SPeter Brune /*@C 4958f6dfbefdSBarry Smith SNESGetNGS - Returns the `SNESNGS` function and context set with `SNESSetNGS()` 4959c79ef259SPeter Brune 4960c79ef259SPeter Brune Input Parameter: 4961f6dfbefdSBarry Smith . snes - the `SNES` context 4962c79ef259SPeter Brune 4963d8d19677SJose E. Roman Output Parameters: 4964f6dfbefdSBarry Smith + f - the function (or NULL) see `SNESNGSFunction` for details 49650298fd71SBarry Smith - ctx - the function context (or NULL) 4966c79ef259SPeter Brune 4967c79ef259SPeter Brune Level: advanced 4968c79ef259SPeter Brune 4969db781477SPatrick Sanan .seealso: `SNESSetNGS()`, `SNESGetFunction()` 4970c79ef259SPeter Brune @*/ 4971c79ef259SPeter Brune 4972d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNGS(SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) 4973d71ae5a4SJacob Faibussowitsch { 49746cab3a1bSJed Brown DM dm; 49756cab3a1bSJed Brown 4976646217ecSPeter Brune PetscFunctionBegin; 4977646217ecSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49789566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 49799566063dSJacob Faibussowitsch PetscCall(DMSNESGetNGS(dm, f, ctx)); 4980646217ecSPeter Brune PetscFunctionReturn(0); 4981646217ecSPeter Brune } 4982646217ecSPeter Brune 49833c7409f5SSatish Balay /*@C 49843c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 4985f6dfbefdSBarry Smith `SNES` options in the database. 49863c7409f5SSatish Balay 4987*c3339decSBarry Smith Logically Collective 4988fee21e36SBarry Smith 4989d8d19677SJose E. Roman Input Parameters: 4990f6dfbefdSBarry Smith + snes - the `SNES` context 4991c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4992c7afd0dbSLois Curfman McInnes 4993f6dfbefdSBarry Smith Note: 4994a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4995c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4996d850072dSLois Curfman McInnes 499736851e7fSLois Curfman McInnes Level: advanced 499836851e7fSLois Curfman McInnes 4999f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFromOptions()`, `SNESAppendOptionsPrefix()` 50003c7409f5SSatish Balay @*/ 5001d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetOptionsPrefix(SNES snes, const char prefix[]) 5002d71ae5a4SJacob Faibussowitsch { 50033a40ed3dSBarry Smith PetscFunctionBegin; 50040700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 50059566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes, prefix)); 50069566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 500735f5d045SPeter Brune if (snes->linesearch) { 50089566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 50099566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch, prefix)); 501035f5d045SPeter Brune } 50119566063dSJacob Faibussowitsch PetscCall(KSPSetOptionsPrefix(snes->ksp, prefix)); 50123a40ed3dSBarry Smith PetscFunctionReturn(0); 50133c7409f5SSatish Balay } 50143c7409f5SSatish Balay 50153c7409f5SSatish Balay /*@C 5016f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 5017f6dfbefdSBarry Smith `SNES` options in the database. 50183c7409f5SSatish Balay 5019*c3339decSBarry Smith Logically Collective 5020fee21e36SBarry Smith 5021c7afd0dbSLois Curfman McInnes Input Parameters: 5022f6dfbefdSBarry Smith + snes - the `SNES` context 5023c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 5024c7afd0dbSLois Curfman McInnes 5025f6dfbefdSBarry Smith Note: 5026a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 5027c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 5028d850072dSLois Curfman McInnes 502936851e7fSLois Curfman McInnes Level: advanced 503036851e7fSLois Curfman McInnes 5031f6dfbefdSBarry Smith .seealso: `SNESGetOptionsPrefix()`, `SNESSetOptionsPrefix()` 50323c7409f5SSatish Balay @*/ 5033d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESAppendOptionsPrefix(SNES snes, const char prefix[]) 5034d71ae5a4SJacob Faibussowitsch { 50353a40ed3dSBarry Smith PetscFunctionBegin; 50360700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 50379566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes, prefix)); 50389566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 503935f5d045SPeter Brune if (snes->linesearch) { 50409566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 50419566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch, prefix)); 504235f5d045SPeter Brune } 50439566063dSJacob Faibussowitsch PetscCall(KSPAppendOptionsPrefix(snes->ksp, prefix)); 50443a40ed3dSBarry Smith PetscFunctionReturn(0); 50453c7409f5SSatish Balay } 50463c7409f5SSatish Balay 50479ab63eb5SSatish Balay /*@C 5048f6dfbefdSBarry Smith SNESGetOptionsPrefix - Gets the prefix used for searching for all 5049f6dfbefdSBarry Smith `SNES` options in the database. 50503c7409f5SSatish Balay 5051c7afd0dbSLois Curfman McInnes Not Collective 5052c7afd0dbSLois Curfman McInnes 50533c7409f5SSatish Balay Input Parameter: 5054f6dfbefdSBarry Smith . snes - the `SNES` context 50553c7409f5SSatish Balay 50563c7409f5SSatish Balay Output Parameter: 50573c7409f5SSatish Balay . prefix - pointer to the prefix string used 50583c7409f5SSatish Balay 5059f6dfbefdSBarry Smith Fortran Note: 506095452b02SPatrick Sanan On the fortran side, the user should pass in a string 'prefix' of 50619ab63eb5SSatish Balay sufficient length to hold the prefix. 50629ab63eb5SSatish Balay 506336851e7fSLois Curfman McInnes Level: advanced 506436851e7fSLois Curfman McInnes 5065f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetOptionsPrefix()`, `SNESAppendOptionsPrefix()` 50663c7409f5SSatish Balay @*/ 5067d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetOptionsPrefix(SNES snes, const char *prefix[]) 5068d71ae5a4SJacob Faibussowitsch { 50693a40ed3dSBarry Smith PetscFunctionBegin; 50700700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 50719566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)snes, prefix)); 50723a40ed3dSBarry Smith PetscFunctionReturn(0); 50733c7409f5SSatish Balay } 50743c7409f5SSatish Balay 50753cea93caSBarry Smith /*@C 50761c84c290SBarry Smith SNESRegister - Adds a method to the nonlinear solver package. 50771c84c290SBarry Smith 50781c84c290SBarry Smith Not collective 50791c84c290SBarry Smith 50801c84c290SBarry Smith Input Parameters: 50811c84c290SBarry Smith + name_solver - name of a new user-defined solver 50821c84c290SBarry Smith - routine_create - routine to create method context 50831c84c290SBarry Smith 5084f6dfbefdSBarry Smith Note: 5085f6dfbefdSBarry Smith `SNESRegister()` may be called multiple times to add several user-defined solvers. 50861c84c290SBarry Smith 50871c84c290SBarry Smith Sample usage: 50881c84c290SBarry Smith .vb 5089bdf89e91SBarry Smith SNESRegister("my_solver",MySolverCreate); 50901c84c290SBarry Smith .ve 50911c84c290SBarry Smith 50921c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 50931c84c290SBarry Smith $ SNESSetType(snes,"my_solver") 50941c84c290SBarry Smith or at runtime via the option 50951c84c290SBarry Smith $ -snes_type my_solver 50961c84c290SBarry Smith 50971c84c290SBarry Smith Level: advanced 50981c84c290SBarry Smith 5099db781477SPatrick Sanan .seealso: `SNESRegisterAll()`, `SNESRegisterDestroy()` 51003cea93caSBarry Smith @*/ 5101d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESRegister(const char sname[], PetscErrorCode (*function)(SNES)) 5102d71ae5a4SJacob Faibussowitsch { 5103b2002411SLois Curfman McInnes PetscFunctionBegin; 51049566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 51059566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&SNESList, sname, function)); 5106b2002411SLois Curfman McInnes PetscFunctionReturn(0); 5107b2002411SLois Curfman McInnes } 5108da9b6338SBarry Smith 5109d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESTestLocalMin(SNES snes) 5110d71ae5a4SJacob Faibussowitsch { 511177431f27SBarry Smith PetscInt N, i, j; 5112da9b6338SBarry Smith Vec u, uh, fh; 5113da9b6338SBarry Smith PetscScalar value; 5114da9b6338SBarry Smith PetscReal norm; 5115da9b6338SBarry Smith 5116da9b6338SBarry Smith PetscFunctionBegin; 51179566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &u)); 51189566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &uh)); 51199566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &fh)); 5120da9b6338SBarry Smith 5121da9b6338SBarry Smith /* currently only works for sequential */ 51229566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Testing FormFunction() for local min\n")); 51239566063dSJacob Faibussowitsch PetscCall(VecGetSize(u, &N)); 5124da9b6338SBarry Smith for (i = 0; i < N; i++) { 51259566063dSJacob Faibussowitsch PetscCall(VecCopy(u, uh)); 512663a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "i = %" PetscInt_FMT "\n", i)); 5127da9b6338SBarry Smith for (j = -10; j < 11; j++) { 51288b49ba18SBarry Smith value = PetscSign(j) * PetscExpReal(PetscAbs(j) - 10.0); 51299566063dSJacob Faibussowitsch PetscCall(VecSetValue(uh, i, value, ADD_VALUES)); 51309566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, uh, fh)); 51319566063dSJacob Faibussowitsch PetscCall(VecNorm(fh, NORM_2, &norm)); 513263a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), " j norm %" PetscInt_FMT " %18.16e\n", j, (double)norm)); 5133da9b6338SBarry Smith value = -value; 51349566063dSJacob Faibussowitsch PetscCall(VecSetValue(uh, i, value, ADD_VALUES)); 5135da9b6338SBarry Smith } 5136da9b6338SBarry Smith } 51379566063dSJacob Faibussowitsch PetscCall(VecDestroy(&uh)); 51389566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fh)); 5139da9b6338SBarry Smith PetscFunctionReturn(0); 5140da9b6338SBarry Smith } 514171f87433Sdalcinl 514271f87433Sdalcinl /*@ 5143f6dfbefdSBarry Smith SNESKSPSetUseEW - Sets `SNES` to the use Eisenstat-Walker method for 514471f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 514571f87433Sdalcinl Newton method. 514671f87433Sdalcinl 5147*c3339decSBarry Smith Logically Collective 514871f87433Sdalcinl 514971f87433Sdalcinl Input Parameters: 5150f6dfbefdSBarry Smith + snes - `SNES` context 5151f6dfbefdSBarry Smith - flag - `PETSC_TRUE` or `PETSC_FALSE` 515271f87433Sdalcinl 5153f6dfbefdSBarry Smith Options Database Keys: 515464ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 515564ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 515664ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 515764ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 515864ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 515964ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 516064ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 516164ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 516264ba62caSBarry Smith 5163f6dfbefdSBarry Smith Note: 5164f6dfbefdSBarry Smith The default is to use a constant relative tolerance for 516571f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 516671f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 516771f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 516871f87433Sdalcinl solver. 516971f87433Sdalcinl 517071f87433Sdalcinl Level: advanced 517171f87433Sdalcinl 517271f87433Sdalcinl Reference: 5173f6dfbefdSBarry Smith . - * S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an inexact Newton method", SISC 17 (1), pp.16-32, 1996. 517471f87433Sdalcinl 5175f6dfbefdSBarry Smith .seealso: `KSP`, `SNES`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 517671f87433Sdalcinl @*/ 5177d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPSetUseEW(SNES snes, PetscBool flag) 5178d71ae5a4SJacob Faibussowitsch { 517971f87433Sdalcinl PetscFunctionBegin; 51800700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5181acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes, flag, 2); 518271f87433Sdalcinl snes->ksp_ewconv = flag; 518371f87433Sdalcinl PetscFunctionReturn(0); 518471f87433Sdalcinl } 518571f87433Sdalcinl 518671f87433Sdalcinl /*@ 5187f6dfbefdSBarry Smith SNESKSPGetUseEW - Gets if `SNES` is using Eisenstat-Walker method 518871f87433Sdalcinl for computing relative tolerance for linear solvers within an 518971f87433Sdalcinl inexact Newton method. 519071f87433Sdalcinl 519171f87433Sdalcinl Not Collective 519271f87433Sdalcinl 519371f87433Sdalcinl Input Parameter: 5194f6dfbefdSBarry Smith . snes - `SNES` context 519571f87433Sdalcinl 519671f87433Sdalcinl Output Parameter: 5197f6dfbefdSBarry Smith . flag - `PETSC_TRUE` or `PETSC_FALSE` 519871f87433Sdalcinl 519971f87433Sdalcinl Level: advanced 520071f87433Sdalcinl 5201db781477SPatrick Sanan .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 520271f87433Sdalcinl @*/ 5203d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 5204d71ae5a4SJacob Faibussowitsch { 520571f87433Sdalcinl PetscFunctionBegin; 52060700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5207534a8f05SLisandro Dalcin PetscValidBoolPointer(flag, 2); 520871f87433Sdalcinl *flag = snes->ksp_ewconv; 520971f87433Sdalcinl PetscFunctionReturn(0); 521071f87433Sdalcinl } 521171f87433Sdalcinl 521271f87433Sdalcinl /*@ 5213fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 521471f87433Sdalcinl convergence criteria for the linear solvers within an inexact 521571f87433Sdalcinl Newton method. 521671f87433Sdalcinl 5217*c3339decSBarry Smith Logically Collective 521871f87433Sdalcinl 521971f87433Sdalcinl Input Parameters: 5220f6dfbefdSBarry Smith + snes - `SNES` context 52210f0abf79SStefano Zampini . version - version 1, 2 (default is 2), 3 or 4 522271f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 522371f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 522471f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 522571f87433Sdalcinl (0 <= gamma2 <= 1) 522671f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 522771f87433Sdalcinl . alpha2 - power for safeguard 522871f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 522971f87433Sdalcinl 5230f6dfbefdSBarry Smith Notes: 523171f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 523271f87433Sdalcinl 5233f6dfbefdSBarry Smith Use `PETSC_DEFAULT` to retain the default for any of the parameters. 523471f87433Sdalcinl 523571f87433Sdalcinl Level: advanced 523671f87433Sdalcinl 5237f6dfbefdSBarry Smith .seealso: `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()` 523871f87433Sdalcinl @*/ 5239d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPSetParametersEW(SNES snes, PetscInt version, PetscReal rtol_0, PetscReal rtol_max, PetscReal gamma, PetscReal alpha, PetscReal alpha2, PetscReal threshold) 5240d71ae5a4SJacob Faibussowitsch { 5241fa9f3622SBarry Smith SNESKSPEW *kctx; 52425fd66863SKarl Rupp 524371f87433Sdalcinl PetscFunctionBegin; 52440700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5245fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 52465f80ce2aSJacob Faibussowitsch PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing"); 5247c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, version, 2); 5248c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol_0, 3); 5249c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol_max, 4); 5250c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, gamma, 5); 5251c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, alpha, 6); 5252c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, alpha2, 7); 5253c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, threshold, 8); 525471f87433Sdalcinl 525571f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 525671f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 525771f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 525871f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 525971f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 526071f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 526171f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 526271f87433Sdalcinl 52630f0abf79SStefano 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); 52640b121fc5SBarry 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); 52650b121fc5SBarry 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); 52660b121fc5SBarry 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); 52670b121fc5SBarry 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); 52680b121fc5SBarry 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); 526971f87433Sdalcinl PetscFunctionReturn(0); 527071f87433Sdalcinl } 527171f87433Sdalcinl 527271f87433Sdalcinl /*@ 5273fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 527471f87433Sdalcinl convergence criteria for the linear solvers within an inexact 527571f87433Sdalcinl Newton method. 527671f87433Sdalcinl 527771f87433Sdalcinl Not Collective 527871f87433Sdalcinl 527997bb3fdcSJose E. Roman Input Parameter: 5280f6dfbefdSBarry Smith . snes - `SNES` context 528171f87433Sdalcinl 528271f87433Sdalcinl Output Parameters: 52830f0abf79SStefano Zampini + version - version 1, 2 (default is 2), 3 or 4 528471f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 528571f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 5286bf388a1fSBarry Smith . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 528771f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 528871f87433Sdalcinl . alpha2 - power for safeguard 528971f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 529071f87433Sdalcinl 529171f87433Sdalcinl Level: advanced 529271f87433Sdalcinl 5293f6dfbefdSBarry Smith .seealso: `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPSetParametersEW()` 529471f87433Sdalcinl @*/ 5295d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPGetParametersEW(SNES snes, PetscInt *version, PetscReal *rtol_0, PetscReal *rtol_max, PetscReal *gamma, PetscReal *alpha, PetscReal *alpha2, PetscReal *threshold) 5296d71ae5a4SJacob Faibussowitsch { 5297fa9f3622SBarry Smith SNESKSPEW *kctx; 52985fd66863SKarl Rupp 529971f87433Sdalcinl PetscFunctionBegin; 53000700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5301fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 53025f80ce2aSJacob Faibussowitsch PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing"); 530371f87433Sdalcinl if (version) *version = kctx->version; 530471f87433Sdalcinl if (rtol_0) *rtol_0 = kctx->rtol_0; 530571f87433Sdalcinl if (rtol_max) *rtol_max = kctx->rtol_max; 530671f87433Sdalcinl if (gamma) *gamma = kctx->gamma; 530771f87433Sdalcinl if (alpha) *alpha = kctx->alpha; 530871f87433Sdalcinl if (alpha2) *alpha2 = kctx->alpha2; 530971f87433Sdalcinl if (threshold) *threshold = kctx->threshold; 531071f87433Sdalcinl PetscFunctionReturn(0); 531171f87433Sdalcinl } 531271f87433Sdalcinl 5313d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 5314d71ae5a4SJacob Faibussowitsch { 5315fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx; 531671f87433Sdalcinl PetscReal rtol = PETSC_DEFAULT, stol; 531771f87433Sdalcinl 531871f87433Sdalcinl PetscFunctionBegin; 5319d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 532030058271SDmitry Karpeev if (!snes->iter) { 532130058271SDmitry Karpeev rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 53229566063dSJacob Faibussowitsch PetscCall(VecNorm(snes->vec_func, NORM_2, &kctx->norm_first)); 53230f0abf79SStefano Zampini } else { 532471f87433Sdalcinl if (kctx->version == 1) { 53250f0abf79SStefano Zampini rtol = PetscAbsReal(snes->norm - kctx->lresid_last) / kctx->norm_last; 532685ec1a3cSBarry Smith stol = PetscPowReal(kctx->rtol_last, kctx->alpha2); 532771f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol, stol); 532871f87433Sdalcinl } else if (kctx->version == 2) { 532985ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha); 533085ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha); 533171f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol, stol); 533271f87433Sdalcinl } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 533385ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha); 533471f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 533585ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha); 533671f87433Sdalcinl stol = PetscMax(rtol, stol); 533771f87433Sdalcinl rtol = PetscMin(kctx->rtol_0, stol); 533871f87433Sdalcinl /* safeguard: avoid oversolving */ 533930058271SDmitry Karpeev stol = kctx->gamma * (kctx->norm_first * snes->rtol) / snes->norm; 534071f87433Sdalcinl stol = PetscMax(rtol, stol); 534171f87433Sdalcinl rtol = PetscMin(kctx->rtol_0, stol); 53420f0abf79SStefano Zampini } else if (kctx->version == 4) { /* H.-B. An et al. Journal of Computational and Applied Mathematics 200 (2007) 47-60 */ 53430f0abf79SStefano Zampini PetscReal ared = PetscAbsReal(kctx->norm_last - snes->norm); 53440f0abf79SStefano Zampini PetscReal pred = PetscAbsReal(kctx->norm_last - kctx->lresid_last); 53450f0abf79SStefano Zampini PetscReal rk = ared / pred; 53460f0abf79SStefano Zampini if (rk < kctx->v4_p1) rtol = 1. - 2. * kctx->v4_p1; 53470f0abf79SStefano Zampini else if (rk < kctx->v4_p2) rtol = kctx->rtol_last; 53480f0abf79SStefano Zampini else if (rk < kctx->v4_p3) rtol = kctx->v4_m1 * kctx->rtol_last; 53490f0abf79SStefano Zampini else rtol = kctx->v4_m2 * kctx->rtol_last; 53500f0abf79SStefano Zampini 53519371c9d4SSatish Balay 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) { 53520f0abf79SStefano Zampini rtol = kctx->v4_m4 * kctx->rtol_last; 53530f0abf79SStefano Zampini //printf("iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g (rk %g ps %g %g %g) (AD)\n",snes->iter,kctx->version,(double)rtol,rk,kctx->v4_p1,kctx->v4_p2,kctx->v4_p3); 53540f0abf79SStefano Zampini } else { 53550f0abf79SStefano Zampini //printf("iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g (rk %g ps %g %g %g)\n",snes->iter,kctx->version,(double)rtol,rk,kctx->v4_p1,kctx->v4_p2,kctx->v4_p3); 535671f87433Sdalcinl } 53570f0abf79SStefano Zampini kctx->rtol_last_2 = kctx->rtol_last; 53580f0abf79SStefano Zampini kctx->rk_last_2 = kctx->rk_last; 53590f0abf79SStefano Zampini kctx->rk_last = rk; 53600f0abf79SStefano Zampini } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Only versions 1-4 are supported: %" PetscInt_FMT, kctx->version); 53610f0abf79SStefano Zampini } 53620f0abf79SStefano Zampini /* safeguard: avoid rtol greater than rtol_max */ 536371f87433Sdalcinl rtol = PetscMin(rtol, kctx->rtol_max); 53649566063dSJacob Faibussowitsch PetscCall(KSPSetTolerances(ksp, rtol, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT)); 536563a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g\n", snes->iter, kctx->version, (double)rtol)); 536671f87433Sdalcinl PetscFunctionReturn(0); 536771f87433Sdalcinl } 536871f87433Sdalcinl 5369d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 5370d71ae5a4SJacob Faibussowitsch { 5371fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx; 537271f87433Sdalcinl PCSide pcside; 537371f87433Sdalcinl Vec lres; 537471f87433Sdalcinl 537571f87433Sdalcinl PetscFunctionBegin; 5376d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 53779566063dSJacob Faibussowitsch PetscCall(KSPGetTolerances(ksp, &kctx->rtol_last, NULL, NULL, NULL)); 537871dbe336SPeter Brune kctx->norm_last = snes->norm; 53790f0abf79SStefano Zampini if (kctx->version == 1 || kctx->version == 4) { 53804f00ce20SMatthew G. Knepley PC pc; 53810f0abf79SStefano Zampini PetscBool getRes; 53824f00ce20SMatthew G. Knepley 53839566063dSJacob Faibussowitsch PetscCall(KSPGetPC(ksp, &pc)); 53840f0abf79SStefano Zampini PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &getRes)); 53850f0abf79SStefano Zampini if (!getRes) { 53860f0abf79SStefano Zampini KSPNormType normtype; 53870f0abf79SStefano Zampini 53880f0abf79SStefano Zampini PetscCall(KSPGetNormType(ksp, &normtype)); 53890f0abf79SStefano Zampini getRes = (PetscBool)(normtype == KSP_NORM_UNPRECONDITIONED); 53900f0abf79SStefano Zampini } 53919566063dSJacob Faibussowitsch PetscCall(KSPGetPCSide(ksp, &pcside)); 53920f0abf79SStefano Zampini if (pcside == PC_RIGHT || getRes) { /* KSP residual is true linear residual */ 53939566063dSJacob Faibussowitsch PetscCall(KSPGetResidualNorm(ksp, &kctx->lresid_last)); 539471f87433Sdalcinl } else { 539571f87433Sdalcinl /* KSP residual is preconditioned residual */ 539671f87433Sdalcinl /* compute true linear residual norm */ 53970f0abf79SStefano Zampini Mat J; 53980f0abf79SStefano Zampini PetscCall(KSPGetOperators(ksp, &J, NULL)); 53999566063dSJacob Faibussowitsch PetscCall(VecDuplicate(b, &lres)); 54000f0abf79SStefano Zampini PetscCall(MatMult(J, x, lres)); 54019566063dSJacob Faibussowitsch PetscCall(VecAYPX(lres, -1.0, b)); 54029566063dSJacob Faibussowitsch PetscCall(VecNorm(lres, NORM_2, &kctx->lresid_last)); 54039566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lres)); 540471f87433Sdalcinl } 540571f87433Sdalcinl } 540671f87433Sdalcinl PetscFunctionReturn(0); 540771f87433Sdalcinl } 540871f87433Sdalcinl 5409d4211eb9SBarry Smith /*@ 5410f6dfbefdSBarry Smith SNESGetKSP - Returns the `KSP` context for a `SNES` solver. 5411d4211eb9SBarry Smith 5412f6dfbefdSBarry Smith Not Collective, but if snes is parallel, then ksp is parallel 5413d4211eb9SBarry Smith 5414d4211eb9SBarry Smith Input Parameter: 5415f6dfbefdSBarry Smith . snes - the `SNES` context 5416d4211eb9SBarry Smith 5417d4211eb9SBarry Smith Output Parameter: 5418f6dfbefdSBarry Smith . ksp - the `KSP` context 5419d4211eb9SBarry Smith 5420d4211eb9SBarry Smith Notes: 5421f6dfbefdSBarry Smith The user can then directly manipulate the `KSP` context to set various 5422d4211eb9SBarry Smith options, etc. Likewise, the user can then extract and manipulate the 5423f6dfbefdSBarry Smith `PC` contexts as well. 5424f6dfbefdSBarry Smith 5425f6dfbefdSBarry Smith Some `SNESType`s do not use a `KSP` but a `KSP` is still returned by this function 5426d4211eb9SBarry Smith 5427d4211eb9SBarry Smith Level: beginner 5428d4211eb9SBarry Smith 5429f6dfbefdSBarry Smith .seealso: `SNES`, `KSP`, `PC`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()` 5430d4211eb9SBarry Smith @*/ 5431d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetKSP(SNES snes, KSP *ksp) 5432d71ae5a4SJacob Faibussowitsch { 543371f87433Sdalcinl PetscFunctionBegin; 5434d4211eb9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5435d4211eb9SBarry Smith PetscValidPointer(ksp, 2); 5436d4211eb9SBarry Smith 5437d4211eb9SBarry Smith if (!snes->ksp) { 54389566063dSJacob Faibussowitsch PetscCall(KSPCreate(PetscObjectComm((PetscObject)snes), &snes->ksp)); 54399566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->ksp, (PetscObject)snes, 1)); 5440d4211eb9SBarry Smith 54419566063dSJacob Faibussowitsch PetscCall(KSPSetPreSolve(snes->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPreSolve_SNESEW, snes)); 54429566063dSJacob Faibussowitsch PetscCall(KSPSetPostSolve(snes->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPostSolve_SNESEW, snes)); 5443a5c2985bSBarry Smith 54449566063dSJacob Faibussowitsch PetscCall(KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes)); 54459566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptions((PetscObject)snes->ksp, ((PetscObject)snes)->options)); 5446d4211eb9SBarry Smith } 5447d4211eb9SBarry Smith *ksp = snes->ksp; 544871f87433Sdalcinl PetscFunctionReturn(0); 544971f87433Sdalcinl } 54506c699258SBarry Smith 5451af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 54526c699258SBarry Smith /*@ 5453f6dfbefdSBarry Smith SNESSetDM - Sets the `DM` that may be used by some nonlinear solvers or their underlying preconditioners 54546c699258SBarry Smith 5455*c3339decSBarry Smith Logically Collective 54566c699258SBarry Smith 54576c699258SBarry Smith Input Parameters: 54582a808120SBarry Smith + snes - the nonlinear solver context 54592a808120SBarry Smith - dm - the dm, cannot be NULL 54606c699258SBarry Smith 5461f6dfbefdSBarry Smith Note: 5462f6dfbefdSBarry Smith A `DM` can only be used for solving one problem at a time because information about the problem is stored on the `DM`, 5463f6dfbefdSBarry Smith even when not using interfaces like `DMSNESSetFunction()`. Use `DMClone()` to get a distinct `DM` when solving different 5464e03a659cSJed Brown problems using the same function space. 5465e03a659cSJed Brown 54666c699258SBarry Smith Level: intermediate 54676c699258SBarry Smith 5468f6dfbefdSBarry Smith .seealso: `DM`, `SNESGetDM()`, `KSPSetDM()`, `KSPGetDM()` 54696c699258SBarry Smith @*/ 5470d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetDM(SNES snes, DM dm) 5471d71ae5a4SJacob Faibussowitsch { 5472345fed2cSBarry Smith KSP ksp; 5473942e3340SBarry Smith DMSNES sdm; 54746c699258SBarry Smith 54756c699258SBarry Smith PetscFunctionBegin; 54760700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 54772a808120SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 54789566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)dm)); 5479942e3340SBarry Smith if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 548051f4b3c7SToby Isaac if (snes->dm->dmsnes && !dm->dmsnes) { 54819566063dSJacob Faibussowitsch PetscCall(DMCopyDMSNES(snes->dm, dm)); 54829566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &sdm)); 5483f5af7f23SKarl Rupp if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 54846cab3a1bSJed Brown } 54859566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookRemove(snes->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, snes)); 54869566063dSJacob Faibussowitsch PetscCall(DMDestroy(&snes->dm)); 54876cab3a1bSJed Brown } 54886c699258SBarry Smith snes->dm = dm; 5489116d1032SJed Brown snes->dmAuto = PETSC_FALSE; 5490f5af7f23SKarl Rupp 54919566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 54929566063dSJacob Faibussowitsch PetscCall(KSPSetDM(ksp, dm)); 54939566063dSJacob Faibussowitsch PetscCall(KSPSetDMActive(ksp, PETSC_FALSE)); 5494efd4aadfSBarry Smith if (snes->npc) { 54959566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes->npc, snes->dm)); 54969566063dSJacob Faibussowitsch PetscCall(SNESSetNPCSide(snes, snes->npcside)); 54972c155ee1SBarry Smith } 54986c699258SBarry Smith PetscFunctionReturn(0); 54996c699258SBarry Smith } 55006c699258SBarry Smith 55016c699258SBarry Smith /*@ 5502f6dfbefdSBarry Smith SNESGetDM - Gets the `DM` that may be used by some preconditioners 55036c699258SBarry Smith 5504f6dfbefdSBarry Smith Not Collective but dm obtained is parallel on snes 55056c699258SBarry Smith 55066c699258SBarry Smith Input Parameter: 55076c699258SBarry Smith . snes - the preconditioner context 55086c699258SBarry Smith 55096c699258SBarry Smith Output Parameter: 55106c699258SBarry Smith . dm - the dm 55116c699258SBarry Smith 55126c699258SBarry Smith Level: intermediate 55136c699258SBarry Smith 5514f6dfbefdSBarry Smith .seealso: `DM`, `SNESSetDM()`, `KSPSetDM()`, `KSPGetDM()` 55156c699258SBarry Smith @*/ 5516d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetDM(SNES snes, DM *dm) 5517d71ae5a4SJacob Faibussowitsch { 55186c699258SBarry Smith PetscFunctionBegin; 55190700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 55206cab3a1bSJed Brown if (!snes->dm) { 55219566063dSJacob Faibussowitsch PetscCall(DMShellCreate(PetscObjectComm((PetscObject)snes), &snes->dm)); 5522116d1032SJed Brown snes->dmAuto = PETSC_TRUE; 55236cab3a1bSJed Brown } 55246c699258SBarry Smith *dm = snes->dm; 55256c699258SBarry Smith PetscFunctionReturn(0); 55266c699258SBarry Smith } 55270807856dSBarry Smith 552831823bd8SMatthew G Knepley /*@ 5529be95d8f1SBarry Smith SNESSetNPC - Sets the nonlinear preconditioner to be used. 553031823bd8SMatthew G Knepley 5531*c3339decSBarry Smith Collective 553231823bd8SMatthew G Knepley 553331823bd8SMatthew G Knepley Input Parameters: 5534f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 5535f6dfbefdSBarry Smith - npc - the preconditioner object 553631823bd8SMatthew G Knepley 553731823bd8SMatthew G Knepley Notes: 5538f6dfbefdSBarry Smith Use `SNESGetNPC()` to retrieve the preconditioner context (for example, 553931823bd8SMatthew G Knepley to configure it using the API). 554031823bd8SMatthew G Knepley 5541f6dfbefdSBarry Smith Only some `SNESType` can use a nonlinear preconditioner 5542f6dfbefdSBarry Smith 554331823bd8SMatthew G Knepley Level: developer 554431823bd8SMatthew G Knepley 5545f6dfbefdSBarry Smith .seealso: `SNESNGS`, `SNESFAS`, `SNESGetNPC()`, `SNESHasNPC()` 554631823bd8SMatthew G Knepley @*/ 5547d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNPC(SNES snes, SNES npc) 5548d71ae5a4SJacob Faibussowitsch { 554931823bd8SMatthew G Knepley PetscFunctionBegin; 555031823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5551f6dfbefdSBarry Smith PetscValidHeaderSpecific(npc, SNES_CLASSID, 2); 5552f6dfbefdSBarry Smith PetscCheckSameComm(snes, 1, npc, 2); 5553f6dfbefdSBarry Smith PetscCall(PetscObjectReference((PetscObject)npc)); 55549566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&snes->npc)); 5555f6dfbefdSBarry Smith snes->npc = npc; 555631823bd8SMatthew G Knepley PetscFunctionReturn(0); 555731823bd8SMatthew G Knepley } 555831823bd8SMatthew G Knepley 555931823bd8SMatthew G Knepley /*@ 5560f6dfbefdSBarry Smith SNESGetNPC - Gets a nonlinear preconditioning solver SNES` to be used to precondition the original nonlinear solver. 556131823bd8SMatthew G Knepley 5562f6dfbefdSBarry Smith Not Collective; but any changes to the obtained the npc object must be applied collectively 556331823bd8SMatthew G Knepley 556431823bd8SMatthew G Knepley Input Parameter: 5565f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 556631823bd8SMatthew G Knepley 556731823bd8SMatthew G Knepley Output Parameter: 5568f6dfbefdSBarry Smith . npc - preconditioner context 556931823bd8SMatthew G Knepley 5570f6dfbefdSBarry Smith Options Database Key: 5571f6dfbefdSBarry Smith . -npc_snes_type <type> - set the type of the `SNES` to use as the nonlinear preconditioner 5572b5badacbSBarry Smith 557395452b02SPatrick Sanan Notes: 5574f6dfbefdSBarry Smith If a `SNES` was previously set with `SNESSetNPC()` then that value is returned, otherwise a new `SNES` object is created. 5575be95d8f1SBarry Smith 5576f6dfbefdSBarry Smith The (preconditioner) `SNES` returned automatically inherits the same nonlinear function and Jacobian supplied to the original 5577f6dfbefdSBarry Smith `SNES` 5578951fe5abSBarry Smith 557931823bd8SMatthew G Knepley Level: developer 558031823bd8SMatthew G Knepley 5581db781477SPatrick Sanan .seealso: `SNESSetNPC()`, `SNESHasNPC()`, `SNES`, `SNESCreate()` 558231823bd8SMatthew G Knepley @*/ 5583d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) 5584d71ae5a4SJacob Faibussowitsch { 5585a64e098fSPeter Brune const char *optionsprefix; 558631823bd8SMatthew G Knepley 558731823bd8SMatthew G Knepley PetscFunctionBegin; 558831823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 558931823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 5590efd4aadfSBarry Smith if (!snes->npc) { 55919566063dSJacob Faibussowitsch PetscCall(SNESCreate(PetscObjectComm((PetscObject)snes), &snes->npc)); 55929566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->npc, (PetscObject)snes, 1)); 55939566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 55949566063dSJacob Faibussowitsch PetscCall(SNESSetOptionsPrefix(snes->npc, optionsprefix)); 55959566063dSJacob Faibussowitsch PetscCall(SNESAppendOptionsPrefix(snes->npc, "npc_")); 55969566063dSJacob Faibussowitsch PetscCall(SNESSetCountersReset(snes->npc, PETSC_FALSE)); 559731823bd8SMatthew G Knepley } 5598efd4aadfSBarry Smith *pc = snes->npc; 559931823bd8SMatthew G Knepley PetscFunctionReturn(0); 560031823bd8SMatthew G Knepley } 560131823bd8SMatthew G Knepley 56023ad1a0b9SPatrick Farrell /*@ 56033ad1a0b9SPatrick Farrell SNESHasNPC - Returns whether a nonlinear preconditioner exists 56043ad1a0b9SPatrick Farrell 56053ad1a0b9SPatrick Farrell Not Collective 56063ad1a0b9SPatrick Farrell 56073ad1a0b9SPatrick Farrell Input Parameter: 5608f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 56093ad1a0b9SPatrick Farrell 56103ad1a0b9SPatrick Farrell Output Parameter: 5611f6dfbefdSBarry Smith . has_npc - whether the `SNES` has an NPC or not 56123ad1a0b9SPatrick Farrell 56133ad1a0b9SPatrick Farrell Level: developer 56143ad1a0b9SPatrick Farrell 5615db781477SPatrick Sanan .seealso: `SNESSetNPC()`, `SNESGetNPC()` 56163ad1a0b9SPatrick Farrell @*/ 5617d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 5618d71ae5a4SJacob Faibussowitsch { 56193ad1a0b9SPatrick Farrell PetscFunctionBegin; 56203ad1a0b9SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5621efd4aadfSBarry Smith *has_npc = (PetscBool)(snes->npc ? PETSC_TRUE : PETSC_FALSE); 56223ad1a0b9SPatrick Farrell PetscFunctionReturn(0); 56233ad1a0b9SPatrick Farrell } 56243ad1a0b9SPatrick Farrell 5625c40d0f55SPeter Brune /*@ 5626be95d8f1SBarry Smith SNESSetNPCSide - Sets the preconditioning side. 5627c40d0f55SPeter Brune 5628*c3339decSBarry Smith Logically Collective 5629c40d0f55SPeter Brune 5630c40d0f55SPeter Brune Input Parameter: 5631f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 5632c40d0f55SPeter Brune 5633c40d0f55SPeter Brune Output Parameter: 5634c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5635c40d0f55SPeter Brune .vb 56362d547940SBarry Smith PC_LEFT - left preconditioning 56372d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5638c40d0f55SPeter Brune .ve 5639c40d0f55SPeter Brune 5640f6dfbefdSBarry Smith Options Database Key: 564167b8a455SSatish Balay . -snes_npc_side <right,left> - nonlinear preconditioner side 5642c40d0f55SPeter Brune 5643f6dfbefdSBarry Smith Note: 5644f6dfbefdSBarry Smith `SNESNRICHARDSON` and `SNESNCG` only support left preconditioning. 56452d547940SBarry Smith 5646c40d0f55SPeter Brune Level: intermediate 5647c40d0f55SPeter Brune 5648f6dfbefdSBarry Smith .seealso: `SNESType`, `SNESGetNPCSide()`, `KSPSetPCSide()` 5649c40d0f55SPeter Brune @*/ 5650d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNPCSide(SNES snes, PCSide side) 5651d71ae5a4SJacob Faibussowitsch { 5652c40d0f55SPeter Brune PetscFunctionBegin; 5653c40d0f55SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5654c40d0f55SPeter Brune PetscValidLogicalCollectiveEnum(snes, side, 2); 5655b552625fSStefano Zampini if (side == PC_SIDE_DEFAULT) side = PC_RIGHT; 565654c59aa7SJacob Faibussowitsch PetscCheck((side == PC_LEFT) || (side == PC_RIGHT), PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONG, "Only PC_LEFT and PC_RIGHT are supported"); 5657efd4aadfSBarry Smith snes->npcside = side; 5658c40d0f55SPeter Brune PetscFunctionReturn(0); 5659c40d0f55SPeter Brune } 5660c40d0f55SPeter Brune 5661c40d0f55SPeter Brune /*@ 5662be95d8f1SBarry Smith SNESGetNPCSide - Gets the preconditioning side. 5663c40d0f55SPeter Brune 5664c40d0f55SPeter Brune Not Collective 5665c40d0f55SPeter Brune 5666c40d0f55SPeter Brune Input Parameter: 5667f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 5668c40d0f55SPeter Brune 5669c40d0f55SPeter Brune Output Parameter: 5670c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5671c40d0f55SPeter Brune .vb 5672f6dfbefdSBarry Smith `PC_LEFT` - left preconditioning 5673f6dfbefdSBarry Smith `PC_RIGHT` - right preconditioning (default for most nonlinear solvers) 5674c40d0f55SPeter Brune .ve 5675c40d0f55SPeter Brune 5676c40d0f55SPeter Brune Level: intermediate 5677c40d0f55SPeter Brune 5678f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetNPCSide()`, `KSPGetPCSide()` 5679c40d0f55SPeter Brune @*/ 5680d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNPCSide(SNES snes, PCSide *side) 5681d71ae5a4SJacob Faibussowitsch { 5682c40d0f55SPeter Brune PetscFunctionBegin; 5683c40d0f55SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5684c40d0f55SPeter Brune PetscValidPointer(side, 2); 5685efd4aadfSBarry Smith *side = snes->npcside; 5686c40d0f55SPeter Brune PetscFunctionReturn(0); 5687c40d0f55SPeter Brune } 5688c40d0f55SPeter Brune 56899e764e56SPeter Brune /*@ 5690f6dfbefdSBarry Smith SNESSetLineSearch - Sets the linesearch on the `SNES` instance. 56919e764e56SPeter Brune 5692*c3339decSBarry Smith Collective 56939e764e56SPeter Brune 56949e764e56SPeter Brune Input Parameters: 5695f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 56969e764e56SPeter Brune - linesearch - the linesearch object 56979e764e56SPeter Brune 5698f6dfbefdSBarry Smith Note: 5699f6dfbefdSBarry Smith Use `SNESGetLineSearch()` to retrieve the preconditioner context (for example, 57009e764e56SPeter Brune to configure it using the API). 57019e764e56SPeter Brune 57029e764e56SPeter Brune Level: developer 57039e764e56SPeter Brune 5704db781477SPatrick Sanan .seealso: `SNESGetLineSearch()` 57059e764e56SPeter Brune @*/ 5706d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 5707d71ae5a4SJacob Faibussowitsch { 57089e764e56SPeter Brune PetscFunctionBegin; 57099e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5710f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 57119e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 57129566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)linesearch)); 57139566063dSJacob Faibussowitsch PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 5714f5af7f23SKarl Rupp 57159e764e56SPeter Brune snes->linesearch = linesearch; 5716f5af7f23SKarl Rupp 57179e764e56SPeter Brune PetscFunctionReturn(0); 57189e764e56SPeter Brune } 57199e764e56SPeter Brune 5720a34ceb2aSJed Brown /*@ 5721f6dfbefdSBarry Smith SNESGetLineSearch - Returns a pointer to the line search context set with `SNESSetLineSearch()` 5722f6dfbefdSBarry Smith or creates a default line search instance associated with the `SNES` and returns it. 57239e764e56SPeter Brune 57249e764e56SPeter Brune Not Collective 57259e764e56SPeter Brune 57269e764e56SPeter Brune Input Parameter: 5727f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 57289e764e56SPeter Brune 57299e764e56SPeter Brune Output Parameter: 57309e764e56SPeter Brune . linesearch - linesearch context 57319e764e56SPeter Brune 5732162e0bf5SPeter Brune Level: beginner 57339e764e56SPeter Brune 5734f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESSetLineSearch()`, `SNESLineSearchCreate()` 57359e764e56SPeter Brune @*/ 5736d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 5737d71ae5a4SJacob Faibussowitsch { 57389e764e56SPeter Brune const char *optionsprefix; 57399e764e56SPeter Brune 57409e764e56SPeter Brune PetscFunctionBegin; 57419e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 57429e764e56SPeter Brune PetscValidPointer(linesearch, 2); 57439e764e56SPeter Brune if (!snes->linesearch) { 57449566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 57459566063dSJacob Faibussowitsch PetscCall(SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch)); 57469566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetSNES(snes->linesearch, snes)); 57479566063dSJacob Faibussowitsch PetscCall(SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix)); 57489566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->linesearch, (PetscObject)snes, 1)); 57499e764e56SPeter Brune } 57509e764e56SPeter Brune *linesearch = snes->linesearch; 57519e764e56SPeter Brune PetscFunctionReturn(0); 57529e764e56SPeter Brune } 5753