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 void *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 $ PetscErrorCode solve(Tao tao) 21 . tao - the optimizer, get the application context with `TaoShellGetContext()` 22 23 Level: advanced 24 25 .seealso: `Tao`, `TAOSHELL`, `TaoShellSetContext()`, `TaoShellGetContext()` 26 @*/ 27 PetscErrorCode TaoShellSetSolve(Tao tao, PetscErrorCode (*solve)(Tao)) 28 { 29 Tao_Shell *shell = (Tao_Shell *)tao->data; 30 31 PetscFunctionBegin; 32 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 33 shell->solve = solve; 34 PetscFunctionReturn(PETSC_SUCCESS); 35 } 36 37 /*@ 38 TaoShellGetContext - Returns the user-provided context associated with a `TAOSHELL` 39 40 Not Collective 41 42 Input Parameter: 43 . tao - should have been created with `TaoSetType`(tao,`TAOSHELL`); 44 45 Output Parameter: 46 . ctx - the user provided context 47 48 Level: advanced 49 50 Note: 51 This routine is intended for use within various shell routines 52 53 .seealso: `Tao`, `TAOSHELL`, `TaoCreateShell()`, `TaoShellSetContext()` 54 @*/ 55 PetscErrorCode TaoShellGetContext(Tao tao, void *ctx) 56 { 57 PetscBool flg; 58 59 PetscFunctionBegin; 60 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 61 PetscValidPointer(ctx, 2); 62 PetscCall(PetscObjectTypeCompare((PetscObject)tao, TAOSHELL, &flg)); 63 if (!flg) *(void **)ctx = NULL; 64 else *(void **)ctx = ((Tao_Shell *)(tao->data))->ctx; 65 PetscFunctionReturn(PETSC_SUCCESS); 66 } 67 68 /*@ 69 TaoShellSetContext - sets the context for a `TAOSHELL` 70 71 Logically Collective 72 73 Input Parameters: 74 + tao - the shell Tao 75 - ctx - the context 76 77 Level: advanced 78 79 Fortran Note: 80 The context can only be an integer or a `PetscObject` 81 82 .seealso: `Tao`, `TAOSHELL`, `TaoCreateShell()`, `TaoShellGetContext()` 83 @*/ 84 PetscErrorCode TaoShellSetContext(Tao tao, void *ctx) 85 { 86 Tao_Shell *shell = (Tao_Shell *)tao->data; 87 PetscBool flg; 88 89 PetscFunctionBegin; 90 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 91 PetscCall(PetscObjectTypeCompare((PetscObject)tao, TAOSHELL, &flg)); 92 if (flg) shell->ctx = ctx; 93 PetscFunctionReturn(PETSC_SUCCESS); 94 } 95 96 static PetscErrorCode TaoSolve_Shell(Tao tao) 97 { 98 Tao_Shell *shell = (Tao_Shell *)tao->data; 99 100 PetscFunctionBegin; 101 PetscCheck(shell->solve, PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "Must call TaoShellSetSolve() first"); 102 tao->reason = TAO_CONVERGED_USER; 103 PetscCall((*(shell->solve))(tao)); 104 PetscFunctionReturn(PETSC_SUCCESS); 105 } 106 107 PetscErrorCode TaoDestroy_Shell(Tao tao) 108 { 109 PetscFunctionBegin; 110 PetscCall(PetscFree(tao->data)); 111 PetscFunctionReturn(PETSC_SUCCESS); 112 } 113 114 PetscErrorCode TaoSetUp_Shell(Tao tao) 115 { 116 PetscFunctionBegin; 117 PetscFunctionReturn(PETSC_SUCCESS); 118 } 119 120 PetscErrorCode TaoSetFromOptions_Shell(Tao tao, PetscOptionItems *PetscOptionsObject) 121 { 122 PetscFunctionBegin; 123 PetscFunctionReturn(PETSC_SUCCESS); 124 } 125 126 PetscErrorCode TaoView_Shell(Tao tao, PetscViewer viewer) 127 { 128 PetscFunctionBegin; 129 PetscFunctionReturn(PETSC_SUCCESS); 130 } 131 132 /*MC 133 TAOSHELL - a user provided optimizer 134 135 Level: advanced 136 137 .seealso: `TaoCreate()`, `Tao`, `TaoSetType()`, `TaoType` 138 M*/ 139 PETSC_EXTERN PetscErrorCode TaoCreate_Shell(Tao tao) 140 { 141 Tao_Shell *shell; 142 143 PetscFunctionBegin; 144 tao->ops->destroy = TaoDestroy_Shell; 145 tao->ops->setup = TaoSetUp_Shell; 146 tao->ops->setfromoptions = TaoSetFromOptions_Shell; 147 tao->ops->view = TaoView_Shell; 148 tao->ops->solve = TaoSolve_Shell; 149 150 PetscCall(PetscNew(&shell)); 151 tao->data = (void *)shell; 152 PetscFunctionReturn(PETSC_SUCCESS); 153 } 154