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`, `TaoCreateShell()`, `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 Fortran Notes: 79 The context can only be an integer or a `PetscObject` 80 81 .seealso: `Tao`, `TAOSHELL`, `TaoCreateShell()`, `TaoShellGetContext()` 82 @*/ 83 PetscErrorCode TaoShellSetContext(Tao tao, void *ctx) 84 { 85 Tao_Shell *shell = (Tao_Shell *)tao->data; 86 PetscBool flg; 87 88 PetscFunctionBegin; 89 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 90 PetscCall(PetscObjectTypeCompare((PetscObject)tao, TAOSHELL, &flg)); 91 if (flg) shell->ctx = ctx; 92 PetscFunctionReturn(PETSC_SUCCESS); 93 } 94 95 static PetscErrorCode TaoSolve_Shell(Tao tao) 96 { 97 Tao_Shell *shell = (Tao_Shell *)tao->data; 98 99 PetscFunctionBegin; 100 PetscCheck(shell->solve, PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "Must call TaoShellSetSolve() first"); 101 tao->reason = TAO_CONVERGED_USER; 102 PetscCall((*shell->solve)(tao)); 103 PetscFunctionReturn(PETSC_SUCCESS); 104 } 105 106 static PetscErrorCode TaoDestroy_Shell(Tao tao) 107 { 108 PetscFunctionBegin; 109 PetscCall(PetscFree(tao->data)); 110 PetscFunctionReturn(PETSC_SUCCESS); 111 } 112 113 static PetscErrorCode TaoSetUp_Shell(Tao tao) 114 { 115 PetscFunctionBegin; 116 PetscFunctionReturn(PETSC_SUCCESS); 117 } 118 119 static PetscErrorCode TaoSetFromOptions_Shell(Tao tao, PetscOptionItems *PetscOptionsObject) 120 { 121 PetscFunctionBegin; 122 PetscFunctionReturn(PETSC_SUCCESS); 123 } 124 125 static PetscErrorCode TaoView_Shell(Tao tao, PetscViewer viewer) 126 { 127 PetscFunctionBegin; 128 PetscFunctionReturn(PETSC_SUCCESS); 129 } 130 131 /*MC 132 TAOSHELL - a user provided optimizer 133 134 Level: advanced 135 136 .seealso: `TaoCreate()`, `Tao`, `TaoSetType()`, `TaoType` 137 M*/ 138 PETSC_EXTERN PetscErrorCode TaoCreate_Shell(Tao tao) 139 { 140 Tao_Shell *shell; 141 142 PetscFunctionBegin; 143 tao->ops->destroy = TaoDestroy_Shell; 144 tao->ops->setup = TaoSetUp_Shell; 145 tao->ops->setfromoptions = TaoSetFromOptions_Shell; 146 tao->ops->view = TaoView_Shell; 147 tao->ops->solve = TaoSolve_Shell; 148 149 PetscCall(PetscNew(&shell)); 150 tao->data = (void *)shell; 151 PetscFunctionReturn(PETSC_SUCCESS); 152 } 153