1f4f59681SStefano Zampini #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/
2f4f59681SStefano Zampini
3f4f59681SStefano Zampini typedef struct {
4f4f59681SStefano Zampini SNES snes;
5f8a48b51SStefano Zampini PetscBool setfromoptionscalled;
6f4f59681SStefano Zampini } Tao_SNES;
7f4f59681SStefano Zampini
TaoSolve_SNES(Tao tao)8f4f59681SStefano Zampini static PetscErrorCode TaoSolve_SNES(Tao tao)
9f4f59681SStefano Zampini {
10f4f59681SStefano Zampini Tao_SNES *taosnes = (Tao_SNES *)tao->data;
114936d809SStefano Zampini PetscInt its;
12f4f59681SStefano Zampini
13f4f59681SStefano Zampini PetscFunctionBegin;
144936d809SStefano Zampini /* TODO SNES fails if KSP reaches max_it, while TAO accepts whatever we got */
15f4f59681SStefano Zampini PetscCall(SNESSolve(taosnes->snes, NULL, tao->solution));
16f4f59681SStefano Zampini /* TODO REASONS */
17f4f59681SStefano Zampini tao->reason = TAO_CONVERGED_USER;
184936d809SStefano Zampini PetscCall(SNESGetIterationNumber(taosnes->snes, &its));
194936d809SStefano Zampini PetscCall(TaoSetIterationNumber(tao, its));
20f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS);
21f4f59681SStefano Zampini }
22f4f59681SStefano Zampini
TaoDestroy_SNES(Tao tao)23f4f59681SStefano Zampini static PetscErrorCode TaoDestroy_SNES(Tao tao)
24f4f59681SStefano Zampini {
25f4f59681SStefano Zampini Tao_SNES *taosnes = (Tao_SNES *)tao->data;
26f4f59681SStefano Zampini
27f4f59681SStefano Zampini PetscFunctionBegin;
28f4f59681SStefano Zampini PetscCall(SNESDestroy(&taosnes->snes));
29f4f59681SStefano Zampini PetscCall(PetscFree(tao->data));
30f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS);
31f4f59681SStefano Zampini }
32f4f59681SStefano Zampini
TAOSNESObj(SNES snes,Vec X,PetscReal * f,PetscCtx ctx)33*2a8381b2SBarry Smith static PetscErrorCode TAOSNESObj(SNES snes, Vec X, PetscReal *f, PetscCtx ctx)
34f4f59681SStefano Zampini {
35f4f59681SStefano Zampini Tao tao = (Tao)ctx;
36f4f59681SStefano Zampini
37f4f59681SStefano Zampini PetscFunctionBegin;
38f4f59681SStefano Zampini PetscCall(TaoComputeObjective(tao, X, f));
39f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS);
40f4f59681SStefano Zampini }
41f4f59681SStefano Zampini
TAOSNESFunc(SNES snes,Vec X,Vec F,PetscCtx ctx)42*2a8381b2SBarry Smith static PetscErrorCode TAOSNESFunc(SNES snes, Vec X, Vec F, PetscCtx ctx)
43f4f59681SStefano Zampini {
44f4f59681SStefano Zampini Tao tao = (Tao)ctx;
45f4f59681SStefano Zampini
46f4f59681SStefano Zampini PetscFunctionBegin;
47f4f59681SStefano Zampini PetscCall(TaoComputeGradient(tao, X, F));
48f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS);
49f4f59681SStefano Zampini }
50f4f59681SStefano Zampini
TAOSNESJac(SNES snes,Vec X,Mat A,Mat P,PetscCtx ctx)51*2a8381b2SBarry Smith static PetscErrorCode TAOSNESJac(SNES snes, Vec X, Mat A, Mat P, PetscCtx ctx)
52f4f59681SStefano Zampini {
53f4f59681SStefano Zampini Tao tao = (Tao)ctx;
54f4f59681SStefano Zampini
55f4f59681SStefano Zampini PetscFunctionBegin;
56f4f59681SStefano Zampini PetscCall(TaoComputeHessian(tao, X, A, P));
57f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS);
58f4f59681SStefano Zampini }
59f4f59681SStefano Zampini
TAOSNESMonitor(SNES snes,PetscInt its,PetscReal fnorm,PetscCtx ctx)60*2a8381b2SBarry Smith static PetscErrorCode TAOSNESMonitor(SNES snes, PetscInt its, PetscReal fnorm, PetscCtx ctx)
614936d809SStefano Zampini {
624936d809SStefano Zampini Tao tao = (Tao)ctx;
634936d809SStefano Zampini PetscReal obj;
644936d809SStefano Zampini Vec X;
654936d809SStefano Zampini
664936d809SStefano Zampini PetscFunctionBegin;
674936d809SStefano Zampini PetscCall(SNESGetSolution(snes, &X));
684936d809SStefano Zampini PetscCall(TaoComputeObjective(tao, X, &obj));
694936d809SStefano Zampini PetscCall(TaoSetIterationNumber(tao, its));
704936d809SStefano Zampini PetscCall(TaoMonitor(tao, its, obj, fnorm, 0.0, 0.0));
714936d809SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS);
724936d809SStefano Zampini }
734936d809SStefano Zampini
TaoSetUp_SNES(Tao tao)74f4f59681SStefano Zampini static PetscErrorCode TaoSetUp_SNES(Tao tao)
75f4f59681SStefano Zampini {
76f4f59681SStefano Zampini Tao_SNES *taosnes = (Tao_SNES *)tao->data;
77f4f59681SStefano Zampini Mat A, P;
78f8a48b51SStefano Zampini const char *prefix;
79f4f59681SStefano Zampini
80f4f59681SStefano Zampini PetscFunctionBegin;
81f8a48b51SStefano Zampini PetscCall(TaoGetOptionsPrefix(tao, &prefix));
82f8a48b51SStefano Zampini PetscCall(SNESSetOptionsPrefix(taosnes->snes, prefix));
83f4f59681SStefano Zampini PetscCall(SNESSetSolution(taosnes->snes, tao->solution));
84f4f59681SStefano Zampini PetscCall(SNESSetObjective(taosnes->snes, TAOSNESObj, tao));
85f4f59681SStefano Zampini PetscCall(SNESSetFunction(taosnes->snes, NULL, TAOSNESFunc, tao));
864936d809SStefano Zampini PetscCall(SNESMonitorSet(taosnes->snes, TAOSNESMonitor, tao, NULL));
87f4f59681SStefano Zampini PetscCall(TaoGetHessian(tao, &A, &P, NULL, NULL));
88f4f59681SStefano Zampini if (A) PetscCall(SNESSetJacobian(taosnes->snes, A, P, TAOSNESJac, tao));
89f8a48b51SStefano Zampini if (taosnes->setfromoptionscalled) PetscCall(SNESSetFromOptions(taosnes->snes));
90f8a48b51SStefano Zampini taosnes->setfromoptionscalled = PETSC_FALSE;
91f4f59681SStefano Zampini PetscCall(SNESSetUp(taosnes->snes));
92f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS);
93f4f59681SStefano Zampini }
94f4f59681SStefano Zampini
TaoSetFromOptions_SNES(Tao tao,PetscOptionItems PetscOptionsObject)95ce78bad3SBarry Smith static PetscErrorCode TaoSetFromOptions_SNES(Tao tao, PetscOptionItems PetscOptionsObject)
96f4f59681SStefano Zampini {
97f4f59681SStefano Zampini Tao_SNES *taosnes = (Tao_SNES *)tao->data;
98f4f59681SStefano Zampini
99f4f59681SStefano Zampini PetscFunctionBegin;
100f8a48b51SStefano Zampini taosnes->setfromoptionscalled = PETSC_TRUE;
101f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS);
102f4f59681SStefano Zampini }
103f4f59681SStefano Zampini
TaoView_SNES(Tao tao,PetscViewer viewer)10466976f2fSJacob Faibussowitsch static PetscErrorCode TaoView_SNES(Tao tao, PetscViewer viewer)
105f4f59681SStefano Zampini {
106f4f59681SStefano Zampini Tao_SNES *taosnes = (Tao_SNES *)tao->data;
107f4f59681SStefano Zampini
108f4f59681SStefano Zampini PetscFunctionBegin;
109f4f59681SStefano Zampini PetscCall(SNESView(taosnes->snes, viewer));
110f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS);
111f4f59681SStefano Zampini }
112f4f59681SStefano Zampini
113f4f59681SStefano Zampini /*MC
114f4f59681SStefano Zampini TAOSNES - nonlinear solver using SNES
115f4f59681SStefano Zampini
116f4f59681SStefano Zampini Level: advanced
117f4f59681SStefano Zampini
118f4f59681SStefano Zampini .seealso: `TaoCreate()`, `Tao`, `TaoSetType()`, `TaoType`
119f4f59681SStefano Zampini M*/
TaoCreate_SNES(Tao tao)120f4f59681SStefano Zampini PETSC_EXTERN PetscErrorCode TaoCreate_SNES(Tao tao)
121f4f59681SStefano Zampini {
122f4f59681SStefano Zampini Tao_SNES *taosnes;
123f4f59681SStefano Zampini
124f4f59681SStefano Zampini PetscFunctionBegin;
125f4f59681SStefano Zampini tao->ops->destroy = TaoDestroy_SNES;
126f4f59681SStefano Zampini tao->ops->setup = TaoSetUp_SNES;
127f4f59681SStefano Zampini tao->ops->setfromoptions = TaoSetFromOptions_SNES;
128f4f59681SStefano Zampini tao->ops->view = TaoView_SNES;
129f4f59681SStefano Zampini tao->ops->solve = TaoSolve_SNES;
130f4f59681SStefano Zampini
131606f75f6SBarry Smith PetscCall(TaoParametersInitialize(tao));
132606f75f6SBarry Smith
133f4f59681SStefano Zampini PetscCall(PetscNew(&taosnes));
134f4f59681SStefano Zampini tao->data = (void *)taosnes;
135f4f59681SStefano Zampini PetscCall(SNESCreate(PetscObjectComm((PetscObject)tao), &taosnes->snes));
136f4f59681SStefano Zampini PetscCall(PetscObjectIncrementTabLevel((PetscObject)taosnes->snes, (PetscObject)tao, 1));
137f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS);
138f4f59681SStefano Zampini }
139