1 #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/ 2 3 typedef struct _n_TaoShell Tao_Shell; 4 5 struct _n_TaoShell { 6 PetscErrorCode (*solve)(Tao); 7 PetscCtx ctx; 8 }; 9 10 /*@C 11 TaoShellSetSolve - Sets routine to apply as solver 12 13 Logically Collective 14 15 Input Parameters: 16 + tao - the nonlinear solver context 17 - solve - the application-provided solver routine 18 19 Calling sequence of `solve`: 20 . tao - the optimizer, get the application context with `TaoShellGetContext()` 21 22 Level: advanced 23 24 .seealso: `Tao`, `TAOSHELL`, `TaoShellSetContext()`, `TaoShellGetContext()` 25 @*/ 26 PetscErrorCode TaoShellSetSolve(Tao tao, PetscErrorCode (*solve)(Tao)) 27 { 28 Tao_Shell *shell = (Tao_Shell *)tao->data; 29 30 PetscFunctionBegin; 31 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 32 shell->solve = solve; 33 PetscFunctionReturn(PETSC_SUCCESS); 34 } 35 36 /*@ 37 TaoShellGetContext - Returns the user-provided context associated with a `TAOSHELL` 38 39 Not Collective 40 41 Input Parameter: 42 . tao - should have been created with `TaoSetType`(tao,`TAOSHELL`); 43 44 Output Parameter: 45 . ctx - the user provided context 46 47 Level: advanced 48 49 Note: 50 This routine is intended for use within various shell routines 51 52 Fortran Note: 53 This only works when the context is a Fortran derived type or a `PetscObject`. Define `ctx` with 54 .vb 55 type(tUsertype), pointer :: ctx 56 .ve 57 58 .seealso: `Tao`, `TAOSHELL`, `TaoShellSetContext()` 59 @*/ 60 PetscErrorCode TaoShellGetContext(Tao tao, PetscCtxRt ctx) 61 { 62 PetscBool flg; 63 64 PetscFunctionBegin; 65 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 66 PetscAssertPointer(ctx, 2); 67 PetscCall(PetscObjectTypeCompare((PetscObject)tao, TAOSHELL, &flg)); 68 if (!flg) *(void **)ctx = NULL; 69 else *(void **)ctx = ((Tao_Shell *)tao->data)->ctx; 70 PetscFunctionReturn(PETSC_SUCCESS); 71 } 72 73 /*@ 74 TaoShellSetContext - sets the context for a `TAOSHELL` 75 76 Logically Collective 77 78 Input Parameters: 79 + tao - the shell Tao 80 - ctx - the context 81 82 Level: advanced 83 84 .seealso: `Tao`, `TAOSHELL`, `TaoShellGetContext()` 85 @*/ 86 PetscErrorCode TaoShellSetContext(Tao tao, PetscCtx ctx) 87 { 88 Tao_Shell *shell = (Tao_Shell *)tao->data; 89 PetscBool flg; 90 91 PetscFunctionBegin; 92 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 93 PetscCall(PetscObjectTypeCompare((PetscObject)tao, TAOSHELL, &flg)); 94 if (flg) shell->ctx = ctx; 95 PetscFunctionReturn(PETSC_SUCCESS); 96 } 97 98 static PetscErrorCode TaoSolve_Shell(Tao tao) 99 { 100 Tao_Shell *shell = (Tao_Shell *)tao->data; 101 102 PetscFunctionBegin; 103 PetscCheck(shell->solve, PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "Must call TaoShellSetSolve() first"); 104 tao->reason = TAO_CONVERGED_USER; 105 PetscCall((*shell->solve)(tao)); 106 PetscFunctionReturn(PETSC_SUCCESS); 107 } 108 109 static PetscErrorCode TaoDestroy_Shell(Tao tao) 110 { 111 PetscFunctionBegin; 112 PetscCall(PetscFree(tao->data)); 113 PetscFunctionReturn(PETSC_SUCCESS); 114 } 115 116 static PetscErrorCode TaoSetUp_Shell(Tao tao) 117 { 118 PetscFunctionBegin; 119 PetscFunctionReturn(PETSC_SUCCESS); 120 } 121 122 static PetscErrorCode TaoSetFromOptions_Shell(Tao tao, PetscOptionItems PetscOptionsObject) 123 { 124 PetscFunctionBegin; 125 PetscFunctionReturn(PETSC_SUCCESS); 126 } 127 128 static PetscErrorCode TaoView_Shell(Tao tao, PetscViewer viewer) 129 { 130 PetscFunctionBegin; 131 PetscFunctionReturn(PETSC_SUCCESS); 132 } 133 134 /*MC 135 TAOSHELL - a user provided optimizer 136 137 Level: advanced 138 139 .seealso: `TaoCreate()`, `Tao`, `TaoSetType()`, `TaoType` 140 M*/ 141 PETSC_EXTERN PetscErrorCode TaoCreate_Shell(Tao tao) 142 { 143 Tao_Shell *shell; 144 145 PetscFunctionBegin; 146 tao->ops->destroy = TaoDestroy_Shell; 147 tao->ops->setup = TaoSetUp_Shell; 148 tao->ops->setfromoptions = TaoSetFromOptions_Shell; 149 tao->ops->view = TaoView_Shell; 150 tao->ops->solve = TaoSolve_Shell; 151 152 PetscCall(TaoParametersInitialize(tao)); 153 154 PetscCall(PetscNew(&shell)); 155 tao->data = (void *)shell; 156 PetscFunctionReturn(PETSC_SUCCESS); 157 } 158