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 . 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 .seealso: `Tao`, `TAOSHELL`, `TaoShellSetContext()` 53 @*/ 54 PetscErrorCode TaoShellGetContext(Tao tao, void *ctx) 55 { 56 PetscBool flg; 57 58 PetscFunctionBegin; 59 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 60 PetscAssertPointer(ctx, 2); 61 PetscCall(PetscObjectTypeCompare((PetscObject)tao, TAOSHELL, &flg)); 62 if (!flg) *(void **)ctx = NULL; 63 else *(void **)ctx = ((Tao_Shell *)tao->data)->ctx; 64 PetscFunctionReturn(PETSC_SUCCESS); 65 } 66 67 /*@ 68 TaoShellSetContext - sets the context for a `TAOSHELL` 69 70 Logically Collective 71 72 Input Parameters: 73 + tao - the shell Tao 74 - ctx - the context 75 76 Level: advanced 77 78 .seealso: `Tao`, `TAOSHELL`, `TaoShellGetContext()` 79 @*/ 80 PetscErrorCode TaoShellSetContext(Tao tao, void *ctx) 81 { 82 Tao_Shell *shell = (Tao_Shell *)tao->data; 83 PetscBool flg; 84 85 PetscFunctionBegin; 86 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 87 PetscCall(PetscObjectTypeCompare((PetscObject)tao, TAOSHELL, &flg)); 88 if (flg) shell->ctx = ctx; 89 PetscFunctionReturn(PETSC_SUCCESS); 90 } 91 92 static PetscErrorCode TaoSolve_Shell(Tao tao) 93 { 94 Tao_Shell *shell = (Tao_Shell *)tao->data; 95 96 PetscFunctionBegin; 97 PetscCheck(shell->solve, PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "Must call TaoShellSetSolve() first"); 98 tao->reason = TAO_CONVERGED_USER; 99 PetscCall((*shell->solve)(tao)); 100 PetscFunctionReturn(PETSC_SUCCESS); 101 } 102 103 static PetscErrorCode TaoDestroy_Shell(Tao tao) 104 { 105 PetscFunctionBegin; 106 PetscCall(PetscFree(tao->data)); 107 PetscFunctionReturn(PETSC_SUCCESS); 108 } 109 110 static PetscErrorCode TaoSetUp_Shell(Tao tao) 111 { 112 PetscFunctionBegin; 113 PetscFunctionReturn(PETSC_SUCCESS); 114 } 115 116 static PetscErrorCode TaoSetFromOptions_Shell(Tao tao, PetscOptionItems PetscOptionsObject) 117 { 118 PetscFunctionBegin; 119 PetscFunctionReturn(PETSC_SUCCESS); 120 } 121 122 static PetscErrorCode TaoView_Shell(Tao tao, PetscViewer viewer) 123 { 124 PetscFunctionBegin; 125 PetscFunctionReturn(PETSC_SUCCESS); 126 } 127 128 /*MC 129 TAOSHELL - a user provided optimizer 130 131 Level: advanced 132 133 .seealso: `TaoCreate()`, `Tao`, `TaoSetType()`, `TaoType` 134 M*/ 135 PETSC_EXTERN PetscErrorCode TaoCreate_Shell(Tao tao) 136 { 137 Tao_Shell *shell; 138 139 PetscFunctionBegin; 140 tao->ops->destroy = TaoDestroy_Shell; 141 tao->ops->setup = TaoSetUp_Shell; 142 tao->ops->setfromoptions = TaoSetFromOptions_Shell; 143 tao->ops->view = TaoView_Shell; 144 tao->ops->solve = TaoSolve_Shell; 145 146 PetscCall(TaoParametersInitialize(tao)); 147 148 PetscCall(PetscNew(&shell)); 149 tao->data = (void *)shell; 150 PetscFunctionReturn(PETSC_SUCCESS); 151 } 152