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; 10f4f59681SStefano Zampini 11f4f59681SStefano Zampini PetscFunctionBegin; 12f4f59681SStefano Zampini PetscCall(SNESSolve(taosnes->snes, NULL, tao->solution)); 13f4f59681SStefano Zampini /* TODO REASONS */ 14f4f59681SStefano Zampini tao->reason = TAO_CONVERGED_USER; 15f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 16f4f59681SStefano Zampini } 17f4f59681SStefano Zampini 18f4f59681SStefano Zampini static PetscErrorCode TaoDestroy_SNES(Tao tao) 19f4f59681SStefano Zampini { 20f4f59681SStefano Zampini Tao_SNES *taosnes = (Tao_SNES *)tao->data; 21f4f59681SStefano Zampini 22f4f59681SStefano Zampini PetscFunctionBegin; 23f4f59681SStefano Zampini PetscCall(SNESDestroy(&taosnes->snes)); 24f4f59681SStefano Zampini PetscCall(PetscFree(tao->data)); 25f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 26f4f59681SStefano Zampini } 27f4f59681SStefano Zampini 28f4f59681SStefano Zampini static PetscErrorCode TAOSNESObj(SNES snes, Vec X, PetscReal *f, void *ctx) 29f4f59681SStefano Zampini { 30f4f59681SStefano Zampini Tao tao = (Tao)ctx; 31f4f59681SStefano Zampini 32f4f59681SStefano Zampini PetscFunctionBegin; 33f4f59681SStefano Zampini PetscCall(TaoComputeObjective(tao, X, f)); 34f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 35f4f59681SStefano Zampini } 36f4f59681SStefano Zampini 37f4f59681SStefano Zampini static PetscErrorCode TAOSNESFunc(SNES snes, Vec X, Vec F, void *ctx) 38f4f59681SStefano Zampini { 39f4f59681SStefano Zampini Tao tao = (Tao)ctx; 40f4f59681SStefano Zampini 41f4f59681SStefano Zampini PetscFunctionBegin; 42f4f59681SStefano Zampini PetscCall(TaoComputeGradient(tao, X, F)); 43f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 44f4f59681SStefano Zampini } 45f4f59681SStefano Zampini 46f4f59681SStefano Zampini static PetscErrorCode TAOSNESJac(SNES snes, Vec X, Mat A, Mat P, void *ctx) 47f4f59681SStefano Zampini { 48f4f59681SStefano Zampini Tao tao = (Tao)ctx; 49f4f59681SStefano Zampini 50f4f59681SStefano Zampini PetscFunctionBegin; 51f4f59681SStefano Zampini PetscCall(TaoComputeHessian(tao, X, A, P)); 52f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 53f4f59681SStefano Zampini } 54f4f59681SStefano Zampini 55f4f59681SStefano Zampini static PetscErrorCode TaoSetUp_SNES(Tao tao) 56f4f59681SStefano Zampini { 57f4f59681SStefano Zampini Tao_SNES *taosnes = (Tao_SNES *)tao->data; 58f4f59681SStefano Zampini Mat A, P; 59f4f59681SStefano Zampini 60f4f59681SStefano Zampini PetscFunctionBegin; 61f4f59681SStefano Zampini PetscCall(SNESSetSolution(taosnes->snes, tao->solution)); 62f4f59681SStefano Zampini PetscCall(SNESSetObjective(taosnes->snes, TAOSNESObj, tao)); 63f4f59681SStefano Zampini PetscCall(SNESSetFunction(taosnes->snes, NULL, TAOSNESFunc, tao)); 64f4f59681SStefano Zampini PetscCall(TaoGetHessian(tao, &A, &P, NULL, NULL)); 65f4f59681SStefano Zampini if (A) PetscCall(SNESSetJacobian(taosnes->snes, A, P, TAOSNESJac, tao)); 66f4f59681SStefano Zampini /* TODO TYPES */ 67f4f59681SStefano Zampini PetscCall(SNESSetUp(taosnes->snes)); 68f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 69f4f59681SStefano Zampini } 70f4f59681SStefano Zampini 71f4f59681SStefano Zampini static PetscErrorCode TaoSetFromOptions_SNES(Tao tao, PetscOptionItems *PetscOptionsObject) 72f4f59681SStefano Zampini { 73f4f59681SStefano Zampini Tao_SNES *taosnes = (Tao_SNES *)tao->data; 74f4f59681SStefano Zampini 75f4f59681SStefano Zampini PetscFunctionBegin; 76f4f59681SStefano Zampini PetscCall(SNESSetFromOptions(taosnes->snes)); 77f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 78f4f59681SStefano Zampini } 79f4f59681SStefano Zampini 80*66976f2fSJacob Faibussowitsch static PetscErrorCode TaoView_SNES(Tao tao, PetscViewer viewer) 81f4f59681SStefano Zampini { 82f4f59681SStefano Zampini Tao_SNES *taosnes = (Tao_SNES *)tao->data; 83f4f59681SStefano Zampini 84f4f59681SStefano Zampini PetscFunctionBegin; 85f4f59681SStefano Zampini PetscCall(SNESView(taosnes->snes, viewer)); 86f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 87f4f59681SStefano Zampini } 88f4f59681SStefano Zampini 89f4f59681SStefano Zampini /*MC 90f4f59681SStefano Zampini TAOSNES - nonlinear solver using SNES 91f4f59681SStefano Zampini 92f4f59681SStefano Zampini Level: advanced 93f4f59681SStefano Zampini 94f4f59681SStefano Zampini .seealso: `TaoCreate()`, `Tao`, `TaoSetType()`, `TaoType` 95f4f59681SStefano Zampini M*/ 96f4f59681SStefano Zampini PETSC_EXTERN PetscErrorCode TaoCreate_SNES(Tao tao) 97f4f59681SStefano Zampini { 98f4f59681SStefano Zampini Tao_SNES *taosnes; 99f4f59681SStefano Zampini 100f4f59681SStefano Zampini PetscFunctionBegin; 101f4f59681SStefano Zampini tao->ops->destroy = TaoDestroy_SNES; 102f4f59681SStefano Zampini tao->ops->setup = TaoSetUp_SNES; 103f4f59681SStefano Zampini tao->ops->setfromoptions = TaoSetFromOptions_SNES; 104f4f59681SStefano Zampini tao->ops->view = TaoView_SNES; 105f4f59681SStefano Zampini tao->ops->solve = TaoSolve_SNES; 106f4f59681SStefano Zampini 107f4f59681SStefano Zampini PetscCall(PetscNew(&taosnes)); 108f4f59681SStefano Zampini tao->data = (void *)taosnes; 109f4f59681SStefano Zampini PetscCall(SNESCreate(PetscObjectComm((PetscObject)tao), &taosnes->snes)); 110f4f59681SStefano Zampini PetscCall(PetscObjectIncrementTabLevel((PetscObject)taosnes->snes, (PetscObject)tao, 1)); 111f4f59681SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 112f4f59681SStefano Zampini } 113