xref: /petsc/src/tao/shell/taoshell.c (revision d5b43468fb8780a8feea140ccd6fa3e6a50411cc)
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 {
35   Tao_Shell *shell = (Tao_Shell *)tao->data;
36 
37   PetscFunctionBegin;
38   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
39   shell->solve = solve;
40   PetscFunctionReturn(0);
41 }
42 
43 /*@
44     TaoShellGetContext - Returns the user-provided context associated with a shell Tao
45 
46     Not Collective
47 
48     Input Parameter:
49 .   tao - should have been created with TaoSetType(tao,TAOSHELL);
50 
51     Output Parameter:
52 .   ctx - the user provided context
53 
54     Level: advanced
55 
56     Notes:
57     This routine is intended for use within various shell routines
58 
59 .seealso: `TaoCreateShell()`, `TaoShellSetContext()`
60 @*/
61 PetscErrorCode TaoShellGetContext(Tao tao, void *ctx)
62 {
63   PetscBool flg;
64 
65   PetscFunctionBegin;
66   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
67   PetscValidPointer(ctx, 2);
68   PetscCall(PetscObjectTypeCompare((PetscObject)tao, TAOSHELL, &flg));
69   if (!flg) *(void **)ctx = NULL;
70   else *(void **)ctx = ((Tao_Shell *)(tao->data))->ctx;
71   PetscFunctionReturn(0);
72 }
73 
74 /*@
75     TaoShellSetContext - sets the context for a shell Tao
76 
77    Logically Collective on Tao
78 
79     Input Parameters:
80 +   tao - the shell Tao
81 -   ctx - the context
82 
83    Level: advanced
84 
85    Fortran Notes:
86     The context can only be an integer or a PetscObject
87       unfortunately it cannot be a Fortran array or derived type.
88 
89 .seealso: `TaoCreateShell()`, `TaoShellGetContext()`
90 @*/
91 PetscErrorCode TaoShellSetContext(Tao tao, void *ctx)
92 {
93   Tao_Shell *shell = (Tao_Shell *)tao->data;
94   PetscBool  flg;
95 
96   PetscFunctionBegin;
97   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
98   PetscCall(PetscObjectTypeCompare((PetscObject)tao, TAOSHELL, &flg));
99   if (flg) shell->ctx = ctx;
100   PetscFunctionReturn(0);
101 }
102 
103 static PetscErrorCode TaoSolve_Shell(Tao tao)
104 {
105   Tao_Shell *shell = (Tao_Shell *)tao->data;
106 
107   PetscFunctionBegin;
108   PetscCheck(shell->solve, PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "Must call TaoShellSetSolve() first");
109   tao->reason = TAO_CONVERGED_USER;
110   PetscCall((*(shell->solve))(tao));
111   PetscFunctionReturn(0);
112 }
113 
114 PetscErrorCode TaoDestroy_Shell(Tao tao)
115 {
116   PetscFunctionBegin;
117   PetscCall(PetscFree(tao->data));
118   PetscFunctionReturn(0);
119 }
120 
121 PetscErrorCode TaoSetUp_Shell(Tao tao)
122 {
123   PetscFunctionBegin;
124   PetscFunctionReturn(0);
125 }
126 
127 PetscErrorCode TaoSetFromOptions_Shell(Tao tao, PetscOptionItems *PetscOptionsObject)
128 {
129   PetscFunctionBegin;
130   PetscFunctionReturn(0);
131 }
132 
133 PetscErrorCode TaoView_Shell(Tao tao, PetscViewer viewer)
134 {
135   PetscFunctionBegin;
136   PetscFunctionReturn(0);
137 }
138 
139 /*MC
140   TAOSHELL - a user provided nonlinear solver
141 
142    Level: advanced
143 
144 .seealso: `TaoCreate()`, `Tao`, `TaoSetType()`, `TaoType`
145 M*/
146 PETSC_EXTERN PetscErrorCode TaoCreate_Shell(Tao tao)
147 {
148   Tao_Shell *shell;
149 
150   PetscFunctionBegin;
151   tao->ops->destroy        = TaoDestroy_Shell;
152   tao->ops->setup          = TaoSetUp_Shell;
153   tao->ops->setfromoptions = TaoSetFromOptions_Shell;
154   tao->ops->view           = TaoView_Shell;
155   tao->ops->solve          = TaoSolve_Shell;
156 
157   PetscCall(PetscNew(&shell));
158   tao->data = (void *)shell;
159   PetscFunctionReturn(0);
160 }
161