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