1af0996ceSBarry Smith #include <petsc/private/linesearchimpl.h> 2af0996ceSBarry Smith #include <petsc/private/snesimpl.h> 36a388c36SPeter Brune 46a388c36SPeter Brune typedef struct { 58434afd1SBarry Smith SNESLineSearchShellApplyFn *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 119bcc50f1SBarry Smith SNESLineSearchShellSetApply - Sets the apply function for the `SNESLINESEARCHSHELL` implementation. 12f40b411bSPeter Brune 13f40b411bSPeter Brune Not Collective 14f40b411bSPeter Brune 15cd7522eaSPeter Brune Input Parameters: 16f6dfbefdSBarry Smith + linesearch - `SNESLineSearch` context 178434afd1SBarry Smith . func - function implementing the linesearch shell, see `SNESLineSearchShellApplyFn` for calling sequence 18cd7522eaSPeter Brune - ctx - context for func 19cd7522eaSPeter Brune 20ceaaa498SBarry Smith Usage\: 2120f4b53cSBarry Smith .vb 2220f4b53cSBarry Smith PetscErrorCode shellfunc(SNESLineSearch linesearch,void * ctx) 2320f4b53cSBarry Smith { 2420f4b53cSBarry Smith Vec X,Y,F,W,G; 2520f4b53cSBarry Smith SNES snes; 26*4d86920dSPierre Jolivet 2720f4b53cSBarry Smith PetscFunctionBegin; 2820f4b53cSBarry Smith PetscCall(SNESLineSearchGetSNES(linesearch,&snes)); 2920f4b53cSBarry Smith PetscCall(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED)); 3020f4b53cSBarry Smith PetscCall(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G)); 31ceaaa498SBarry Smith // determine lambda using W and G as work vecs.. 3220f4b53cSBarry Smith PetscCall(VecAXPY(X,-lambda,Y)); 3320f4b53cSBarry Smith PetscCall(SNESComputeFunction(snes,X,F)); 3420f4b53cSBarry Smith PetscCall(SNESLineSearchComputeNorms(linesearch)); 3520f4b53cSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 3620f4b53cSBarry Smith } 3720f4b53cSBarry Smith 3820f4b53cSBarry Smith PetscCall(SNESGetLineSearch(snes, &linesearch)); 3920f4b53cSBarry Smith PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL)); 409bcc50f1SBarry Smith PetscCall(SNESLineSearchShellSetApply(linesearch, shellfunc, NULL)); 4120f4b53cSBarry Smith .ve 42cd7522eaSPeter Brune 43f40b411bSPeter Brune Level: advanced 44f40b411bSPeter Brune 459bcc50f1SBarry Smith .seealso: [](ch_snes), `SNESLineSearchShellGetApply()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`, 468434afd1SBarry Smith `SNESLineSearchShellApplyFn` 47f40b411bSPeter Brune @*/ 488434afd1SBarry Smith PetscErrorCode SNESLineSearchShellSetApply(SNESLineSearch linesearch, SNESLineSearchShellApplyFn *func, void *ctx) 49d71ae5a4SJacob Faibussowitsch { 506a388c36SPeter Brune PetscBool flg; 51f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 520adebc6cSBarry Smith 536a388c36SPeter Brune PetscFunctionBegin; 54f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 559566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg)); 566a388c36SPeter Brune if (flg) { 576a388c36SPeter Brune shell->ctx = ctx; 589e764e56SPeter Brune shell->func = func; 596a388c36SPeter Brune } 603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 616a388c36SPeter Brune } 626a388c36SPeter Brune 63f40b411bSPeter Brune /*@C 649bcc50f1SBarry Smith SNESLineSearchShellGetApply - Gets the apply function and context for the `SNESLINESEARCHSHELL` 65f40b411bSPeter Brune 66f40b411bSPeter Brune Not Collective 67f40b411bSPeter Brune 684a2f8832SBarry Smith Input Parameter: 694a2f8832SBarry Smith . linesearch - the line search object 704a2f8832SBarry Smith 714a2f8832SBarry Smith Output Parameters: 728434afd1SBarry Smith + func - the user function; can be `NULL` if it is not needed, see `SNESLineSearchShellApplyFn` for calling sequence 73420bcc1bSBarry Smith - ctx - the user function context; can be `NULL` if it is not needed 744a2f8832SBarry Smith 75f40b411bSPeter Brune Level: advanced 76f40b411bSPeter Brune 779bcc50f1SBarry Smith .seealso: [](ch_snes), `SNESLineSearchShellSetApply()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`, 788434afd1SBarry Smith `SNESLineSearchShellApplyFn` 79f40b411bSPeter Brune @*/ 808434afd1SBarry Smith PetscErrorCode SNESLineSearchShellGetApply(SNESLineSearch linesearch, SNESLineSearchShellApplyFn **func, void **ctx) 81d71ae5a4SJacob Faibussowitsch { 826a388c36SPeter Brune PetscBool flg; 83f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 840adebc6cSBarry Smith 856a388c36SPeter Brune PetscFunctionBegin; 86f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 874f572ea9SToby Isaac if (func) PetscAssertPointer(func, 2); 884f572ea9SToby Isaac if (ctx) PetscAssertPointer(ctx, 3); 899566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg)); 906a388c36SPeter Brune if (flg) { 914a2f8832SBarry Smith if (func) *func = shell->func; 924a2f8832SBarry Smith if (ctx) *ctx = shell->ctx; 936a388c36SPeter Brune } 943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 956a388c36SPeter Brune } 966a388c36SPeter Brune 97d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch) 98d71ae5a4SJacob Faibussowitsch { 99f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 1006a388c36SPeter Brune 1016a388c36SPeter Brune PetscFunctionBegin; 1026a388c36SPeter Brune /* apply the user function */ 1036a388c36SPeter Brune if (shell->func) { 1049566063dSJacob Faibussowitsch PetscCall((*shell->func)(linesearch, shell->ctx)); 1059bcc50f1SBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetApply()"); 1063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1076a388c36SPeter Brune } 1086a388c36SPeter Brune 109d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch) 110d71ae5a4SJacob Faibussowitsch { 111f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 1126a388c36SPeter Brune 1136a388c36SPeter Brune PetscFunctionBegin; 1149566063dSJacob Faibussowitsch PetscCall(PetscFree(shell)); 1153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1166a388c36SPeter Brune } 1176a388c36SPeter Brune 118954494b2SJed Brown /*MC 1199bcc50f1SBarry Smith SNESLINESEARCHSHELL - Provides an API for a user-provided line search routine. 120954494b2SJed Brown 121cd7522eaSPeter Brune Any of the other line searches may serve as a guide to how this is to be done. There is also a basic 1229bcc50f1SBarry Smith template in the documentation for `SNESLineSearchShellSetApply()`. 123954494b2SJed Brown 124954494b2SJed Brown Level: advanced 125954494b2SJed Brown 1269bcc50f1SBarry Smith .seealso: [](ch_snes), `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`, `SNESLineSearchShellSetApply()`, 1278434afd1SBarry Smith `SNESLineSearchShellApplyFn` 128954494b2SJed Brown M*/ 129420bcc1bSBarry Smith 130d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch) 131d71ae5a4SJacob Faibussowitsch { 132f1c6b773SPeter Brune SNESLineSearch_Shell *shell; 1336a388c36SPeter Brune 1346a388c36SPeter Brune PetscFunctionBegin; 135f1c6b773SPeter Brune linesearch->ops->apply = SNESLineSearchApply_Shell; 136f1c6b773SPeter Brune linesearch->ops->destroy = SNESLineSearchDestroy_Shell; 1370298fd71SBarry Smith linesearch->ops->setfromoptions = NULL; 1380298fd71SBarry Smith linesearch->ops->reset = NULL; 1390298fd71SBarry Smith linesearch->ops->view = NULL; 1400298fd71SBarry Smith linesearch->ops->setup = NULL; 1416a388c36SPeter Brune 1424dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&shell)); 143f5af7f23SKarl Rupp 1446a388c36SPeter Brune linesearch->data = (void *)shell; 1453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1466a388c36SPeter Brune } 147