1af0996ceSBarry Smith #include <petsc/private/linesearchimpl.h> 2af0996ceSBarry Smith #include <petsc/private/snesimpl.h> 36a388c36SPeter Brune 46a388c36SPeter Brune typedef struct { 5f1c6b773SPeter Brune SNESLineSearchUserFunc func; 66a388c36SPeter Brune void *ctx; 7f1c6b773SPeter Brune } SNESLineSearch_Shell; 86a388c36SPeter Brune 9*ceaaa498SBarry Smith // PetscClangLinter pragma disable: -fdoc-param-list-func-parameter-documentation 10f40b411bSPeter Brune /*@C 11f6dfbefdSBarry Smith SNESLineSearchShellSetUserFunc - Sets the user function for the `SNESLINESEARCHSHELL` implementation. 12f40b411bSPeter Brune 13f40b411bSPeter Brune Not Collective 14f40b411bSPeter Brune 15cd7522eaSPeter Brune Input Parameters: 16f6dfbefdSBarry Smith + linesearch - `SNESLineSearch` context 17cd7522eaSPeter Brune . func - function implementing the linesearch shell. 18cd7522eaSPeter Brune - ctx - context for func 19cd7522eaSPeter Brune 2020f4b53cSBarry Smith Calling sequence of `func`: 21*ceaaa498SBarry Smith $ PetscErrorCode func(SNESLinesearch ls, void *ctx) 22*ceaaa498SBarry Smith + ls - the linesearch instance 23cd7522eaSPeter Brune - ctx - the above mentioned context 24cd7522eaSPeter Brune 25*ceaaa498SBarry Smith Usage\: 2620f4b53cSBarry Smith .vb 2720f4b53cSBarry Smith PetscErrorCode shellfunc(SNESLineSearch linesearch,void * ctx) 2820f4b53cSBarry Smith { 2920f4b53cSBarry Smith Vec X,Y,F,W,G; 3020f4b53cSBarry Smith SNES snes; 3120f4b53cSBarry Smith PetscFunctionBegin; 3220f4b53cSBarry Smith PetscCall(SNESLineSearchGetSNES(linesearch,&snes)); 3320f4b53cSBarry Smith PetscCall(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED)); 3420f4b53cSBarry Smith PetscCall(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G)); 35*ceaaa498SBarry Smith // determine lambda using W and G as work vecs.. 3620f4b53cSBarry Smith PetscCall(VecAXPY(X,-lambda,Y)); 3720f4b53cSBarry Smith PetscCall(SNESComputeFunction(snes,X,F)); 3820f4b53cSBarry Smith PetscCall(SNESLineSearchComputeNorms(linesearch)); 3920f4b53cSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 4020f4b53cSBarry Smith } 4120f4b53cSBarry Smith 4220f4b53cSBarry Smith PetscCall(SNESGetLineSearch(snes, &linesearch)); 4320f4b53cSBarry Smith PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL)); 4420f4b53cSBarry Smith PetscCall(SNESLineSearchShellSetUserFunc(linesearch, shellfunc, NULL)); 4520f4b53cSBarry Smith .ve 46cd7522eaSPeter Brune 47f40b411bSPeter Brune Level: advanced 48f40b411bSPeter Brune 49f6dfbefdSBarry Smith .seealso: `SNESLineSearchShellGetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch` 50f40b411bSPeter Brune @*/ 51d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx) 52d71ae5a4SJacob Faibussowitsch { 536a388c36SPeter Brune PetscBool flg; 54f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 550adebc6cSBarry Smith 566a388c36SPeter Brune PetscFunctionBegin; 57f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 589566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg)); 596a388c36SPeter Brune if (flg) { 606a388c36SPeter Brune shell->ctx = ctx; 619e764e56SPeter Brune shell->func = func; 626a388c36SPeter Brune } 633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 646a388c36SPeter Brune } 656a388c36SPeter Brune 66f40b411bSPeter Brune /*@C 67f6dfbefdSBarry Smith SNESLineSearchShellGetUserFunc - Gets the user function and context for the `SNESLINESEARCHSHELL` 68f40b411bSPeter Brune 69f40b411bSPeter Brune Not Collective 70f40b411bSPeter Brune 714a2f8832SBarry Smith Input Parameter: 724a2f8832SBarry Smith . linesearch - the line search object 734a2f8832SBarry Smith 744a2f8832SBarry Smith Output Parameters: 754a2f8832SBarry Smith + func - the user function; can be NULL if you do not want it 764a2f8832SBarry Smith - ctx - the user function context; can be NULL if you do not want it 774a2f8832SBarry Smith 78f40b411bSPeter Brune Level: advanced 79f40b411bSPeter Brune 80f6dfbefdSBarry Smith .seealso: `SNESLineSearchShellSetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch` 81f40b411bSPeter Brune @*/ 82d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx) 83d71ae5a4SJacob Faibussowitsch { 846a388c36SPeter Brune PetscBool flg; 85f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 860adebc6cSBarry Smith 876a388c36SPeter Brune PetscFunctionBegin; 88f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 894f572ea9SToby Isaac if (func) PetscAssertPointer(func, 2); 904f572ea9SToby Isaac if (ctx) PetscAssertPointer(ctx, 3); 919566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg)); 926a388c36SPeter Brune if (flg) { 934a2f8832SBarry Smith if (func) *func = shell->func; 944a2f8832SBarry Smith if (ctx) *ctx = shell->ctx; 956a388c36SPeter Brune } 963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 976a388c36SPeter Brune } 986a388c36SPeter Brune 99d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch) 100d71ae5a4SJacob Faibussowitsch { 101f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 1026a388c36SPeter Brune 1036a388c36SPeter Brune PetscFunctionBegin; 1046a388c36SPeter Brune /* apply the user function */ 1056a388c36SPeter Brune if (shell->func) { 1069566063dSJacob Faibussowitsch PetscCall((*shell->func)(linesearch, shell->ctx)); 107ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc"); 1083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1096a388c36SPeter Brune } 1106a388c36SPeter Brune 111d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch) 112d71ae5a4SJacob Faibussowitsch { 113f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 1146a388c36SPeter Brune 1156a388c36SPeter Brune PetscFunctionBegin; 1169566063dSJacob Faibussowitsch PetscCall(PetscFree(shell)); 1173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1186a388c36SPeter Brune } 1196a388c36SPeter Brune 120954494b2SJed Brown /*MC 1211a4f838cSPeter Brune SNESLINESEARCHSHELL - Provides context for a user-provided line search routine. 122954494b2SJed Brown 123f1c6b773SPeter Brune The user routine has one argument, the SNESLineSearch context. The user uses the interface to 124954494b2SJed Brown extract line search parameters and set them accordingly when the computation is finished. 125954494b2SJed Brown 126cd7522eaSPeter Brune Any of the other line searches may serve as a guide to how this is to be done. There is also a basic 127cd7522eaSPeter Brune template in the documentation for SNESLineSearchShellSetUserFunc(). 128954494b2SJed Brown 129954494b2SJed Brown Level: advanced 130954494b2SJed Brown 131f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()` 132954494b2SJed Brown M*/ 133d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch) 134d71ae5a4SJacob Faibussowitsch { 135f1c6b773SPeter Brune SNESLineSearch_Shell *shell; 1366a388c36SPeter Brune 1376a388c36SPeter Brune PetscFunctionBegin; 138f1c6b773SPeter Brune linesearch->ops->apply = SNESLineSearchApply_Shell; 139f1c6b773SPeter Brune linesearch->ops->destroy = SNESLineSearchDestroy_Shell; 1400298fd71SBarry Smith linesearch->ops->setfromoptions = NULL; 1410298fd71SBarry Smith linesearch->ops->reset = NULL; 1420298fd71SBarry Smith linesearch->ops->view = NULL; 1430298fd71SBarry Smith linesearch->ops->setup = NULL; 1446a388c36SPeter Brune 1454dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&shell)); 146f5af7f23SKarl Rupp 1476a388c36SPeter Brune linesearch->data = (void *)shell; 1483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1496a388c36SPeter Brune } 150