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;
264d86920dSPierre 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 @*/
SNESLineSearchShellSetApply(SNESLineSearch linesearch,SNESLineSearchShellApplyFn * func,PetscCtx ctx)48*2a8381b2SBarry Smith PetscErrorCode SNESLineSearchShellSetApply(SNESLineSearch linesearch, SNESLineSearchShellApplyFn *func, PetscCtx 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 @*/
SNESLineSearchShellGetApply(SNESLineSearch linesearch,SNESLineSearchShellApplyFn ** func,PetscCtxRt ctx)80*2a8381b2SBarry Smith PetscErrorCode SNESLineSearchShellGetApply(SNESLineSearch linesearch, SNESLineSearchShellApplyFn **func, PetscCtxRt 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;
92*2a8381b2SBarry Smith if (ctx) *(void **)ctx = shell->ctx;
936a388c36SPeter Brune }
943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
956a388c36SPeter Brune }
966a388c36SPeter Brune
SNESLineSearchApply_Shell(SNESLineSearch linesearch)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 */
103966bd95aSPierre Jolivet PetscCheck(shell->func, PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetApply()");
1049566063dSJacob Faibussowitsch PetscCall((*shell->func)(linesearch, shell->ctx));
1053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1066a388c36SPeter Brune }
1076a388c36SPeter Brune
SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)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
1189bcc50f1SBarry 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
1219bcc50f1SBarry Smith template in the documentation for `SNESLineSearchShellSetApply()`.
122954494b2SJed Brown
123954494b2SJed Brown Level: advanced
124954494b2SJed Brown
1259bcc50f1SBarry Smith .seealso: [](ch_snes), `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`, `SNESLineSearchShellSetApply()`,
1268434afd1SBarry Smith `SNESLineSearchShellApplyFn`
127954494b2SJed Brown M*/
128420bcc1bSBarry Smith
SNESLineSearchCreate_Shell(SNESLineSearch linesearch)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