#include /*I "petsctao.h" I*/ typedef struct _n_TaoShell Tao_Shell; struct _n_TaoShell { PetscErrorCode (*solve)(Tao); void *ctx; }; /*@C TaoShellSetSolve - Sets routine to apply as solver Logically Collective on Tao Input Parameters: + tao - the nonlinear solver context - solve - the application-provided solver routine Calling sequence of solve: .vb PetscErrorCode solve (Tao tao) .ve . tao - the optimizer, get the application context with TaoShellGetContext() Notes: the function MUST return an error code of 0 on success and nonzero on failure. Level: advanced .seealso: TAOSHELL, TaoShellSetContext(), TaoShellGetContext() @*/ PetscErrorCode TaoShellSetSolve(Tao tao, PetscErrorCode (*solve) (Tao)) { Tao_Shell *shell = (Tao_Shell*)tao->data; PetscFunctionBegin; PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); shell->solve = solve; PetscFunctionReturn(0); } /*@ TaoShellGetContext - Returns the user-provided context associated with a shell Tao Not Collective Input Parameter: . tao - should have been created with TaoSetType(tao,TAOSHELL); Output Parameter: . ctx - the user provided context Level: advanced Notes: This routine is intended for use within various shell routines .seealso: TaoCreateShell(), TaoShellSetContext() @*/ PetscErrorCode TaoShellGetContext(Tao tao,void *ctx) { PetscErrorCode ierr; PetscBool flg; PetscFunctionBegin; PetscValidHeaderSpecific(tao,TAO_CLASSID,1); PetscValidPointer(ctx,2); ierr = PetscObjectTypeCompare((PetscObject)tao,TAOSHELL,&flg);CHKERRQ(ierr); if (!flg) *(void**)ctx = NULL; else *(void**)ctx = ((Tao_Shell*)(tao->data))->ctx; PetscFunctionReturn(0); } /*@ TaoShellSetContext - sets the context for a shell Tao Logically Collective on Tao Input Parameters: + tao - the shell Tao - ctx - the context Level: advanced Fortran Notes: The context can only be an integer or a PetscObject unfortunately it cannot be a Fortran array or derived type. .seealso: TaoCreateShell(), TaoShellGetContext() @*/ PetscErrorCode TaoShellSetContext(Tao tao,void *ctx) { Tao_Shell *shell = (Tao_Shell*)tao->data; PetscErrorCode ierr; PetscBool flg; PetscFunctionBegin; PetscValidHeaderSpecific(tao,TAO_CLASSID,1); ierr = PetscObjectTypeCompare((PetscObject)tao,TAOSHELL,&flg);CHKERRQ(ierr); if (flg) shell->ctx = ctx; PetscFunctionReturn(0); } static PetscErrorCode TaoSolve_Shell(Tao tao) { Tao_Shell *shell = (Tao_Shell*)tao->data; PetscErrorCode ierr; PetscFunctionBegin; if (!shell->solve) SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"Must call TaoShellSetSolve() first"); tao->reason = TAO_CONVERGED_USER; ierr = (*(shell->solve)) (tao);CHKERRQ(ierr); PetscFunctionReturn(0); } PetscErrorCode TaoDestroy_Shell(Tao tao) { PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscFree(tao->data);CHKERRQ(ierr); PetscFunctionReturn(0); } PetscErrorCode TaoSetUp_Shell(Tao tao) { PetscFunctionBegin; PetscFunctionReturn(0); } PetscErrorCode TaoSetFromOptions_Shell(PetscOptionItems *PetscOptionsObject,Tao tao) { PetscFunctionBegin; PetscFunctionReturn(0); } PetscErrorCode TaoView_Shell(Tao tao, PetscViewer viewer) { PetscFunctionBegin; PetscFunctionReturn(0); } /*MC TAOSHELL - a user provided nonlinear solver Level: advanced .seealso: TaoCreate(), Tao, TaoSetType(), TaoType (for list of available types) M*/ PETSC_EXTERN PetscErrorCode TaoCreate_Shell(Tao tao) { Tao_Shell *shell; PetscErrorCode ierr; PetscFunctionBegin; tao->ops->destroy = TaoDestroy_Shell; tao->ops->setup = TaoSetUp_Shell; tao->ops->setfromoptions = TaoSetFromOptions_Shell; tao->ops->view = TaoView_Shell; tao->ops->solve = TaoSolve_Shell; ierr = PetscNewLog(tao,&shell);CHKERRQ(ierr); tao->data = (void*)shell; PetscFunctionReturn(0); }