1af0996ceSBarry Smith #include <petsc/private/linesearchimpl.h> 2af0996ceSBarry Smith #include <petsc/private/snesimpl.h> 36a388c36SPeter Brune 46a388c36SPeter Brune typedef struct { 5*9bcc50f1SBarry Smith SNESLineSearchShellApply_Fn *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 11*9bcc50f1SBarry 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 17*9bcc50f1SBarry Smith . func - function implementing the linesearch shell, see `SNESLineSearchShellApply_Fn` 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; 2620f4b53cSBarry Smith PetscFunctionBegin; 2720f4b53cSBarry Smith PetscCall(SNESLineSearchGetSNES(linesearch,&snes)); 2820f4b53cSBarry Smith PetscCall(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED)); 2920f4b53cSBarry Smith PetscCall(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G)); 30ceaaa498SBarry Smith // determine lambda using W and G as work vecs.. 3120f4b53cSBarry Smith PetscCall(VecAXPY(X,-lambda,Y)); 3220f4b53cSBarry Smith PetscCall(SNESComputeFunction(snes,X,F)); 3320f4b53cSBarry Smith PetscCall(SNESLineSearchComputeNorms(linesearch)); 3420f4b53cSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 3520f4b53cSBarry Smith } 3620f4b53cSBarry Smith 3720f4b53cSBarry Smith PetscCall(SNESGetLineSearch(snes, &linesearch)); 3820f4b53cSBarry Smith PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL)); 39*9bcc50f1SBarry Smith PetscCall(SNESLineSearchShellSetApply(linesearch, shellfunc, NULL)); 4020f4b53cSBarry Smith .ve 41cd7522eaSPeter Brune 42f40b411bSPeter Brune Level: advanced 43f40b411bSPeter Brune 44*9bcc50f1SBarry Smith .seealso: [](ch_snes), `SNESLineSearchShellGetApply()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`, 45*9bcc50f1SBarry Smith `SNESLineSearchShellApply_Fn` 46f40b411bSPeter Brune @*/ 47*9bcc50f1SBarry Smith PetscErrorCode SNESLineSearchShellSetApply(SNESLineSearch linesearch, SNESLineSearchShellApply_Fn *func, void *ctx) 48d71ae5a4SJacob Faibussowitsch { 496a388c36SPeter Brune PetscBool flg; 50f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 510adebc6cSBarry Smith 526a388c36SPeter Brune PetscFunctionBegin; 53f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 549566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg)); 556a388c36SPeter Brune if (flg) { 566a388c36SPeter Brune shell->ctx = ctx; 579e764e56SPeter Brune shell->func = func; 586a388c36SPeter Brune } 593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 606a388c36SPeter Brune } 616a388c36SPeter Brune 62f40b411bSPeter Brune /*@C 63*9bcc50f1SBarry Smith SNESLineSearchShellGetApply - Gets the apply function and context for the `SNESLINESEARCHSHELL` 64f40b411bSPeter Brune 65f40b411bSPeter Brune Not Collective 66f40b411bSPeter Brune 674a2f8832SBarry Smith Input Parameter: 684a2f8832SBarry Smith . linesearch - the line search object 694a2f8832SBarry Smith 704a2f8832SBarry Smith Output Parameters: 71*9bcc50f1SBarry Smith + func - the user function; can be `NULL` if it is not needed, see `SNESLineSearchShellApply_Fn` for calling sequence 72420bcc1bSBarry Smith - ctx - the user function context; can be `NULL` if it is not needed 734a2f8832SBarry Smith 74f40b411bSPeter Brune Level: advanced 75f40b411bSPeter Brune 76*9bcc50f1SBarry Smith .seealso: [](ch_snes), `SNESLineSearchShellSetApply()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`, 77*9bcc50f1SBarry Smith `SNESLineSearchShellApply_Fn` 78f40b411bSPeter Brune @*/ 79*9bcc50f1SBarry Smith PetscErrorCode SNESLineSearchShellGetApply(SNESLineSearch linesearch, SNESLineSearchShellApply_Fn **func, void **ctx) 80d71ae5a4SJacob Faibussowitsch { 816a388c36SPeter Brune PetscBool flg; 82f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 830adebc6cSBarry Smith 846a388c36SPeter Brune PetscFunctionBegin; 85f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 864f572ea9SToby Isaac if (func) PetscAssertPointer(func, 2); 874f572ea9SToby Isaac if (ctx) PetscAssertPointer(ctx, 3); 889566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg)); 896a388c36SPeter Brune if (flg) { 904a2f8832SBarry Smith if (func) *func = shell->func; 914a2f8832SBarry Smith if (ctx) *ctx = shell->ctx; 926a388c36SPeter Brune } 933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 946a388c36SPeter Brune } 956a388c36SPeter Brune 96d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch) 97d71ae5a4SJacob Faibussowitsch { 98f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 996a388c36SPeter Brune 1006a388c36SPeter Brune PetscFunctionBegin; 1016a388c36SPeter Brune /* apply the user function */ 1026a388c36SPeter Brune if (shell->func) { 1039566063dSJacob Faibussowitsch PetscCall((*shell->func)(linesearch, shell->ctx)); 104*9bcc50f1SBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetApply()"); 1053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1066a388c36SPeter Brune } 1076a388c36SPeter Brune 108d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch) 109d71ae5a4SJacob Faibussowitsch { 110f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 1116a388c36SPeter Brune 1126a388c36SPeter Brune PetscFunctionBegin; 1139566063dSJacob Faibussowitsch PetscCall(PetscFree(shell)); 1143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1156a388c36SPeter Brune } 1166a388c36SPeter Brune 117954494b2SJed Brown /*MC 118*9bcc50f1SBarry Smith SNESLINESEARCHSHELL - Provides an API for a user-provided line search routine. 119954494b2SJed Brown 120cd7522eaSPeter Brune Any of the other line searches may serve as a guide to how this is to be done. There is also a basic 121*9bcc50f1SBarry Smith template in the documentation for `SNESLineSearchShellSetApply()`. 122954494b2SJed Brown 123954494b2SJed Brown Level: advanced 124954494b2SJed Brown 125*9bcc50f1SBarry Smith .seealso: [](ch_snes), `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`, `SNESLineSearchShellSetApply()`, 126*9bcc50f1SBarry Smith `SNESLineSearchShellApply_Fn` 127954494b2SJed Brown M*/ 128420bcc1bSBarry Smith 129d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch) 130d71ae5a4SJacob Faibussowitsch { 131f1c6b773SPeter Brune SNESLineSearch_Shell *shell; 1326a388c36SPeter Brune 1336a388c36SPeter Brune PetscFunctionBegin; 134f1c6b773SPeter Brune linesearch->ops->apply = SNESLineSearchApply_Shell; 135f1c6b773SPeter Brune linesearch->ops->destroy = SNESLineSearchDestroy_Shell; 1360298fd71SBarry Smith linesearch->ops->setfromoptions = NULL; 1370298fd71SBarry Smith linesearch->ops->reset = NULL; 1380298fd71SBarry Smith linesearch->ops->view = NULL; 1390298fd71SBarry Smith linesearch->ops->setup = NULL; 1406a388c36SPeter Brune 1414dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&shell)); 142f5af7f23SKarl Rupp 1436a388c36SPeter Brune linesearch->data = (void *)shell; 1443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1456a388c36SPeter Brune } 146