xref: /petsc/src/tao/snes/taosnes.c (revision 4936d80934666c0fe36796ce94b63b57bfb10049)
1f4f59681SStefano Zampini #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/
2f4f59681SStefano Zampini 
3f4f59681SStefano Zampini typedef struct {
4f4f59681SStefano Zampini   SNES snes;
5f4f59681SStefano Zampini } Tao_SNES;
6f4f59681SStefano Zampini 
7f4f59681SStefano Zampini static PetscErrorCode TaoSolve_SNES(Tao tao)
8f4f59681SStefano Zampini {
9f4f59681SStefano Zampini   Tao_SNES *taosnes = (Tao_SNES *)tao->data;
10*4936d809SStefano Zampini   PetscInt  its;
11f4f59681SStefano Zampini 
12f4f59681SStefano Zampini   PetscFunctionBegin;
13*4936d809SStefano Zampini   /* TODO SNES fails if KSP reaches max_it, while TAO accepts whatever we got */
14f4f59681SStefano Zampini   PetscCall(SNESSolve(taosnes->snes, NULL, tao->solution));
15f4f59681SStefano Zampini   /* TODO REASONS */
16f4f59681SStefano Zampini   tao->reason = TAO_CONVERGED_USER;
17*4936d809SStefano Zampini   PetscCall(SNESGetIterationNumber(taosnes->snes, &its));
18*4936d809SStefano Zampini   PetscCall(TaoSetIterationNumber(tao, its));
19f4f59681SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
20f4f59681SStefano Zampini }
21f4f59681SStefano Zampini 
22f4f59681SStefano Zampini static PetscErrorCode TaoDestroy_SNES(Tao tao)
23f4f59681SStefano Zampini {
24f4f59681SStefano Zampini   Tao_SNES *taosnes = (Tao_SNES *)tao->data;
25f4f59681SStefano Zampini 
26f4f59681SStefano Zampini   PetscFunctionBegin;
27f4f59681SStefano Zampini   PetscCall(SNESDestroy(&taosnes->snes));
28f4f59681SStefano Zampini   PetscCall(PetscFree(tao->data));
29f4f59681SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
30f4f59681SStefano Zampini }
31f4f59681SStefano Zampini 
32f4f59681SStefano Zampini static PetscErrorCode TAOSNESObj(SNES snes, Vec X, PetscReal *f, void *ctx)
33f4f59681SStefano Zampini {
34f4f59681SStefano Zampini   Tao tao = (Tao)ctx;
35f4f59681SStefano Zampini 
36f4f59681SStefano Zampini   PetscFunctionBegin;
37f4f59681SStefano Zampini   PetscCall(TaoComputeObjective(tao, X, f));
38f4f59681SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
39f4f59681SStefano Zampini }
40f4f59681SStefano Zampini 
41f4f59681SStefano Zampini static PetscErrorCode TAOSNESFunc(SNES snes, Vec X, Vec F, void *ctx)
42f4f59681SStefano Zampini {
43f4f59681SStefano Zampini   Tao tao = (Tao)ctx;
44f4f59681SStefano Zampini 
45f4f59681SStefano Zampini   PetscFunctionBegin;
46f4f59681SStefano Zampini   PetscCall(TaoComputeGradient(tao, X, F));
47f4f59681SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
48f4f59681SStefano Zampini }
49f4f59681SStefano Zampini 
50f4f59681SStefano Zampini static PetscErrorCode TAOSNESJac(SNES snes, Vec X, Mat A, Mat P, void *ctx)
51f4f59681SStefano Zampini {
52f4f59681SStefano Zampini   Tao tao = (Tao)ctx;
53f4f59681SStefano Zampini 
54f4f59681SStefano Zampini   PetscFunctionBegin;
55f4f59681SStefano Zampini   PetscCall(TaoComputeHessian(tao, X, A, P));
56f4f59681SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
57f4f59681SStefano Zampini }
58f4f59681SStefano Zampini 
59*4936d809SStefano Zampini static PetscErrorCode TAOSNESMonitor(SNES snes, PetscInt its, PetscReal fnorm, void *ctx)
60*4936d809SStefano Zampini {
61*4936d809SStefano Zampini   Tao       tao = (Tao)ctx;
62*4936d809SStefano Zampini   PetscReal obj;
63*4936d809SStefano Zampini   Vec       X;
64*4936d809SStefano Zampini 
65*4936d809SStefano Zampini   PetscFunctionBegin;
66*4936d809SStefano Zampini   PetscCall(SNESGetSolution(snes, &X));
67*4936d809SStefano Zampini   PetscCall(TaoComputeObjective(tao, X, &obj));
68*4936d809SStefano Zampini   PetscCall(TaoSetIterationNumber(tao, its));
69*4936d809SStefano Zampini   PetscCall(TaoMonitor(tao, its, obj, fnorm, 0.0, 0.0));
70*4936d809SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
71*4936d809SStefano Zampini }
72*4936d809SStefano Zampini 
73f4f59681SStefano Zampini static PetscErrorCode TaoSetUp_SNES(Tao tao)
74f4f59681SStefano Zampini {
75f4f59681SStefano Zampini   Tao_SNES *taosnes = (Tao_SNES *)tao->data;
76f4f59681SStefano Zampini   Mat       A, P;
77f4f59681SStefano Zampini 
78f4f59681SStefano Zampini   PetscFunctionBegin;
79f4f59681SStefano Zampini   PetscCall(SNESSetSolution(taosnes->snes, tao->solution));
80f4f59681SStefano Zampini   PetscCall(SNESSetObjective(taosnes->snes, TAOSNESObj, tao));
81f4f59681SStefano Zampini   PetscCall(SNESSetFunction(taosnes->snes, NULL, TAOSNESFunc, tao));
82*4936d809SStefano Zampini   PetscCall(SNESMonitorSet(taosnes->snes, TAOSNESMonitor, tao, NULL));
83f4f59681SStefano Zampini   PetscCall(TaoGetHessian(tao, &A, &P, NULL, NULL));
84f4f59681SStefano Zampini   if (A) PetscCall(SNESSetJacobian(taosnes->snes, A, P, TAOSNESJac, tao));
85f4f59681SStefano Zampini   /* TODO TYPES */
86f4f59681SStefano Zampini   PetscCall(SNESSetUp(taosnes->snes));
87f4f59681SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
88f4f59681SStefano Zampini }
89f4f59681SStefano Zampini 
90f4f59681SStefano Zampini static PetscErrorCode TaoSetFromOptions_SNES(Tao tao, PetscOptionItems *PetscOptionsObject)
91f4f59681SStefano Zampini {
92f4f59681SStefano Zampini   Tao_SNES *taosnes = (Tao_SNES *)tao->data;
93f4f59681SStefano Zampini 
94f4f59681SStefano Zampini   PetscFunctionBegin;
95f4f59681SStefano Zampini   PetscCall(SNESSetFromOptions(taosnes->snes));
96f4f59681SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
97f4f59681SStefano Zampini }
98f4f59681SStefano Zampini 
9966976f2fSJacob Faibussowitsch static PetscErrorCode TaoView_SNES(Tao tao, PetscViewer viewer)
100f4f59681SStefano Zampini {
101f4f59681SStefano Zampini   Tao_SNES *taosnes = (Tao_SNES *)tao->data;
102f4f59681SStefano Zampini 
103f4f59681SStefano Zampini   PetscFunctionBegin;
104f4f59681SStefano Zampini   PetscCall(SNESView(taosnes->snes, viewer));
105f4f59681SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
106f4f59681SStefano Zampini }
107f4f59681SStefano Zampini 
108f4f59681SStefano Zampini /*MC
109f4f59681SStefano Zampini   TAOSNES - nonlinear solver using SNES
110f4f59681SStefano Zampini 
111f4f59681SStefano Zampini    Level: advanced
112f4f59681SStefano Zampini 
113f4f59681SStefano Zampini .seealso: `TaoCreate()`, `Tao`, `TaoSetType()`, `TaoType`
114f4f59681SStefano Zampini M*/
115f4f59681SStefano Zampini PETSC_EXTERN PetscErrorCode TaoCreate_SNES(Tao tao)
116f4f59681SStefano Zampini {
117f4f59681SStefano Zampini   Tao_SNES *taosnes;
118f4f59681SStefano Zampini 
119f4f59681SStefano Zampini   PetscFunctionBegin;
120f4f59681SStefano Zampini   tao->ops->destroy        = TaoDestroy_SNES;
121f4f59681SStefano Zampini   tao->ops->setup          = TaoSetUp_SNES;
122f4f59681SStefano Zampini   tao->ops->setfromoptions = TaoSetFromOptions_SNES;
123f4f59681SStefano Zampini   tao->ops->view           = TaoView_SNES;
124f4f59681SStefano Zampini   tao->ops->solve          = TaoSolve_SNES;
125f4f59681SStefano Zampini 
126f4f59681SStefano Zampini   PetscCall(PetscNew(&taosnes));
127f4f59681SStefano Zampini   tao->data = (void *)taosnes;
128f4f59681SStefano Zampini   PetscCall(SNESCreate(PetscObjectComm((PetscObject)tao), &taosnes->snes));
129f4f59681SStefano Zampini   PetscCall(PetscObjectIncrementTabLevel((PetscObject)taosnes->snes, (PetscObject)tao, 1));
130f4f59681SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
131f4f59681SStefano Zampini }
132