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 9ceaaa498SBarry 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`: 21ceaaa498SBarry Smith $ PetscErrorCode func(SNESLinesearch ls, void *ctx) 22ceaaa498SBarry Smith + ls - the linesearch instance 23cd7522eaSPeter Brune - ctx - the above mentioned context 24cd7522eaSPeter Brune 25ceaaa498SBarry 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)); 35ceaaa498SBarry 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 49*420bcc1bSBarry Smith .seealso: [](ch_snes), `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: 75*420bcc1bSBarry Smith + func - the user function; can be `NULL` if it is not needed 76*420bcc1bSBarry Smith - ctx - the user function context; can be `NULL` if it is not needed 774a2f8832SBarry Smith 78f40b411bSPeter Brune Level: advanced 79f40b411bSPeter Brune 80*420bcc1bSBarry Smith .seealso: [](ch_snes), `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 123*420bcc1bSBarry Smith 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 127*420bcc1bSBarry Smith template in the documentation for `SNESLineSearchShellSetUserFunc()`. 128954494b2SJed Brown 129954494b2SJed Brown Level: advanced 130954494b2SJed Brown 131*420bcc1bSBarry Smith .seealso: [](ch_snes), `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()` 132954494b2SJed Brown M*/ 133*420bcc1bSBarry Smith 134d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch) 135d71ae5a4SJacob Faibussowitsch { 136f1c6b773SPeter Brune SNESLineSearch_Shell *shell; 1376a388c36SPeter Brune 1386a388c36SPeter Brune PetscFunctionBegin; 139f1c6b773SPeter Brune linesearch->ops->apply = SNESLineSearchApply_Shell; 140f1c6b773SPeter Brune linesearch->ops->destroy = SNESLineSearchDestroy_Shell; 1410298fd71SBarry Smith linesearch->ops->setfromoptions = NULL; 1420298fd71SBarry Smith linesearch->ops->reset = NULL; 1430298fd71SBarry Smith linesearch->ops->view = NULL; 1440298fd71SBarry Smith linesearch->ops->setup = NULL; 1456a388c36SPeter Brune 1464dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&shell)); 147f5af7f23SKarl Rupp 1486a388c36SPeter Brune linesearch->data = (void *)shell; 1493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1506a388c36SPeter Brune } 151