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 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 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 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 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 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 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 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 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 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*/ 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