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