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