xref: /petsc/src/tao/shell/taoshell.c (revision a69119a591a03a9d906b29c0a4e9802e4d7c9795)
1 #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/
2 
3 typedef struct _n_TaoShell Tao_Shell;
4 
5 struct _n_TaoShell {
6   PetscErrorCode (*solve)(Tao);
7   void *ctx;
8 };
9 
10 /*@C
11    TaoShellSetSolve - Sets routine to apply as solver
12 
13    Logically Collective on Tao
14 
15    Input Parameters:
16 +  tao - the nonlinear solver context
17 -  solve - the application-provided solver routine
18 
19    Calling sequence of solve:
20 .vb
21    PetscErrorCode solve (Tao tao)
22 .ve
23 
24 .  tao - the optimizer, get the application context with TaoShellGetContext()
25 
26    Notes:
27     the function MUST return an error code of 0 on success and nonzero on failure.
28 
29    Level: advanced
30 
31 .seealso: `TAOSHELL`, `TaoShellSetContext()`, `TaoShellGetContext()`
32 @*/
33 PetscErrorCode TaoShellSetSolve(Tao tao, PetscErrorCode (*solve)(Tao)) {
34   Tao_Shell *shell = (Tao_Shell *)tao->data;
35 
36   PetscFunctionBegin;
37   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
38   shell->solve = solve;
39   PetscFunctionReturn(0);
40 }
41 
42 /*@
43     TaoShellGetContext - Returns the user-provided context associated with a shell Tao
44 
45     Not Collective
46 
47     Input Parameter:
48 .   tao - should have been created with TaoSetType(tao,TAOSHELL);
49 
50     Output Parameter:
51 .   ctx - the user provided context
52 
53     Level: advanced
54 
55     Notes:
56     This routine is intended for use within various shell routines
57 
58 .seealso: `TaoCreateShell()`, `TaoShellSetContext()`
59 @*/
60 PetscErrorCode TaoShellGetContext(Tao tao, void *ctx) {
61   PetscBool flg;
62 
63   PetscFunctionBegin;
64   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
65   PetscValidPointer(ctx, 2);
66   PetscCall(PetscObjectTypeCompare((PetscObject)tao, TAOSHELL, &flg));
67   if (!flg) *(void **)ctx = NULL;
68   else *(void **)ctx = ((Tao_Shell *)(tao->data))->ctx;
69   PetscFunctionReturn(0);
70 }
71 
72 /*@
73     TaoShellSetContext - sets the context for a shell Tao
74 
75    Logically Collective on Tao
76 
77     Input Parameters:
78 +   tao - the shell Tao
79 -   ctx - the context
80 
81    Level: advanced
82 
83    Fortran Notes:
84     The context can only be an integer or a PetscObject
85       unfortunately it cannot be a Fortran array or derived type.
86 
87 .seealso: `TaoCreateShell()`, `TaoShellGetContext()`
88 @*/
89 PetscErrorCode TaoShellSetContext(Tao tao, void *ctx) {
90   Tao_Shell *shell = (Tao_Shell *)tao->data;
91   PetscBool  flg;
92 
93   PetscFunctionBegin;
94   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
95   PetscCall(PetscObjectTypeCompare((PetscObject)tao, TAOSHELL, &flg));
96   if (flg) shell->ctx = ctx;
97   PetscFunctionReturn(0);
98 }
99 
100 static PetscErrorCode TaoSolve_Shell(Tao tao) {
101   Tao_Shell *shell = (Tao_Shell *)tao->data;
102 
103   PetscFunctionBegin;
104   PetscCheck(shell->solve, PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "Must call TaoShellSetSolve() first");
105   tao->reason = TAO_CONVERGED_USER;
106   PetscCall((*(shell->solve))(tao));
107   PetscFunctionReturn(0);
108 }
109 
110 PetscErrorCode TaoDestroy_Shell(Tao tao) {
111   PetscFunctionBegin;
112   PetscCall(PetscFree(tao->data));
113   PetscFunctionReturn(0);
114 }
115 
116 PetscErrorCode TaoSetUp_Shell(Tao tao) {
117   PetscFunctionBegin;
118   PetscFunctionReturn(0);
119 }
120 
121 PetscErrorCode TaoSetFromOptions_Shell(Tao tao, PetscOptionItems *PetscOptionsObject) {
122   PetscFunctionBegin;
123   PetscFunctionReturn(0);
124 }
125 
126 PetscErrorCode TaoView_Shell(Tao tao, PetscViewer viewer) {
127   PetscFunctionBegin;
128   PetscFunctionReturn(0);
129 }
130 
131 /*MC
132   TAOSHELL - a user provided nonlinear solver
133 
134    Level: advanced
135 
136 .seealso: `TaoCreate()`, `Tao`, `TaoSetType()`, `TaoType`
137 M*/
138 PETSC_EXTERN PetscErrorCode TaoCreate_Shell(Tao tao) {
139   Tao_Shell *shell;
140 
141   PetscFunctionBegin;
142   tao->ops->destroy        = TaoDestroy_Shell;
143   tao->ops->setup          = TaoSetUp_Shell;
144   tao->ops->setfromoptions = TaoSetFromOptions_Shell;
145   tao->ops->view           = TaoView_Shell;
146   tao->ops->solve          = TaoSolve_Shell;
147 
148   PetscCall(PetscNewLog(tao, &shell));
149   tao->data = (void *)shell;
150   PetscFunctionReturn(0);
151 }
152