1af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/ 2074cc835SBarry Smith 39371c9d4SSatish Balay typedef struct { 49371c9d4SSatish Balay PetscErrorCode (*solve)(SNES, Vec); 59371c9d4SSatish Balay void *ctx; 69371c9d4SSatish Balay } SNES_Shell; 7074cc835SBarry Smith 8074cc835SBarry Smith /*@C 9*ceaaa498SBarry Smith SNESShellSetSolve - Sets routine to apply as solver to a `SNESSHELL` `SNES` object 10074cc835SBarry Smith 11c3339decSBarry Smith Logically Collective 12074cc835SBarry Smith 13074cc835SBarry Smith Input Parameters: 14f6dfbefdSBarry Smith + snes - the `SNES` nonlinear solver context 15*ceaaa498SBarry Smith - solve - the application-provided solver routine 16074cc835SBarry Smith 1720f4b53cSBarry Smith Calling sequence of `apply`: 18f6dfbefdSBarry Smith + snes - the preconditioner, get the application context with `SNESShellGetContext()` provided with `SNESShelletContext()` 19*ceaaa498SBarry Smith - xout - solution vector 20074cc835SBarry Smith 21074cc835SBarry Smith Level: advanced 22074cc835SBarry Smith 23db781477SPatrick Sanan .seealso: `SNESSHELL`, `SNESShellSetContext()`, `SNESShellGetContext()` 24074cc835SBarry Smith @*/ 25*ceaaa498SBarry Smith PetscErrorCode SNESShellSetSolve(SNES snes, PetscErrorCode (*solve)(SNES snes, Vec xout)) 26d71ae5a4SJacob Faibussowitsch { 27074cc835SBarry Smith PetscFunctionBegin; 28074cc835SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 29cac4c232SBarry Smith PetscTryMethod(snes, "SNESShellSetSolve_C", (SNES, PetscErrorCode(*)(SNES, Vec)), (snes, solve)); 303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 31074cc835SBarry Smith } 32074cc835SBarry Smith 33d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESReset_Shell(SNES snes) 34d71ae5a4SJacob Faibussowitsch { 35074cc835SBarry Smith PetscFunctionBegin; 363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37074cc835SBarry Smith } 38074cc835SBarry Smith 39d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESDestroy_Shell(SNES snes) 40d71ae5a4SJacob Faibussowitsch { 41074cc835SBarry Smith PetscFunctionBegin; 429566063dSJacob Faibussowitsch PetscCall(SNESReset_Shell(snes)); 439566063dSJacob Faibussowitsch PetscCall(PetscFree(snes->data)); 443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 45074cc835SBarry Smith } 46074cc835SBarry Smith 47d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUp_Shell(SNES snes) 48d71ae5a4SJacob Faibussowitsch { 49074cc835SBarry Smith PetscFunctionBegin; 503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 51074cc835SBarry Smith } 52074cc835SBarry Smith 53d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFromOptions_Shell(SNES snes, PetscOptionItems *PetscOptionsObject) 54d71ae5a4SJacob Faibussowitsch { 55074cc835SBarry Smith PetscFunctionBegin; 56d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "SNES Shell options"); 573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 58074cc835SBarry Smith } 59074cc835SBarry Smith 60d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESView_Shell(SNES snes, PetscViewer viewer) 61d71ae5a4SJacob Faibussowitsch { 62074cc835SBarry Smith PetscFunctionBegin; 633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 64074cc835SBarry Smith } 65074cc835SBarry Smith 6690b77ac2SPeter Brune /*@ 67f6dfbefdSBarry Smith SNESShellGetContext - Returns the user-provided context associated with a `SNESSHELL` 68074cc835SBarry Smith 69074cc835SBarry Smith Not Collective 70074cc835SBarry Smith 71074cc835SBarry Smith Input Parameter: 72f6dfbefdSBarry Smith . snes - should have been created with `SNESSetType`(snes,`SNESSHELL`); 73074cc835SBarry Smith 74074cc835SBarry Smith Output Parameter: 75074cc835SBarry Smith . ctx - the user provided context 76074cc835SBarry Smith 77074cc835SBarry Smith Level: advanced 78074cc835SBarry Smith 79f6dfbefdSBarry Smith .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellSetContext()` 80074cc835SBarry Smith @*/ 81d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESShellGetContext(SNES snes, void *ctx) 82d71ae5a4SJacob Faibussowitsch { 83074cc835SBarry Smith PetscBool flg; 84074cc835SBarry Smith 85074cc835SBarry Smith PetscFunctionBegin; 86074cc835SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 874f572ea9SToby Isaac PetscAssertPointer(ctx, 2); 889566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg)); 893ec1f749SStefano Zampini if (!flg) *(void **)ctx = NULL; 903ec1f749SStefano Zampini else *(void **)ctx = ((SNES_Shell *)(snes->data))->ctx; 913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 92074cc835SBarry Smith } 93074cc835SBarry Smith 94074cc835SBarry Smith /*@ 95f6dfbefdSBarry Smith SNESShellSetContext - sets the context for a `SNESSHELL` 96074cc835SBarry Smith 97c3339decSBarry Smith Logically Collective 98074cc835SBarry Smith 99074cc835SBarry Smith Input Parameters: 100f6dfbefdSBarry Smith + snes - the `SNESSHELL` 101074cc835SBarry Smith - ctx - the context 102074cc835SBarry Smith 103074cc835SBarry Smith Level: advanced 104074cc835SBarry Smith 105e4094ef1SJacob Faibussowitsch Fortran Notes: 106f6dfbefdSBarry Smith The context can only be an integer or a `PetscObject` it cannot be a Fortran array or derived type. 107074cc835SBarry Smith 108f6dfbefdSBarry Smith .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellGetContext()` 109074cc835SBarry Smith @*/ 110d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESShellSetContext(SNES snes, void *ctx) 111d71ae5a4SJacob Faibussowitsch { 112074cc835SBarry Smith SNES_Shell *shell = (SNES_Shell *)snes->data; 113074cc835SBarry Smith PetscBool flg; 114074cc835SBarry Smith 115074cc835SBarry Smith PetscFunctionBegin; 116074cc835SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1179566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg)); 1181aa26658SKarl Rupp if (flg) shell->ctx = ctx; 1193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 120074cc835SBarry Smith } 121074cc835SBarry Smith 122d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSolve_Shell(SNES snes) 123d71ae5a4SJacob Faibussowitsch { 124074cc835SBarry Smith SNES_Shell *shell = (SNES_Shell *)snes->data; 125074cc835SBarry Smith 126074cc835SBarry Smith PetscFunctionBegin; 12728b400f6SJacob Faibussowitsch PetscCheck(shell->solve, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONGSTATE, "Must call SNESShellSetSolve() first"); 1281e633543SBarry Smith snes->reason = SNES_CONVERGED_ITS; 1299566063dSJacob Faibussowitsch PetscCall((*shell->solve)(snes, snes->vec_sol)); 1303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 131074cc835SBarry Smith } 132074cc835SBarry Smith 133d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESShellSetSolve_Shell(SNES snes, PetscErrorCode (*solve)(SNES, Vec)) 134d71ae5a4SJacob Faibussowitsch { 135074cc835SBarry Smith SNES_Shell *shell = (SNES_Shell *)snes->data; 136074cc835SBarry Smith 137074cc835SBarry Smith PetscFunctionBegin; 138074cc835SBarry Smith shell->solve = solve; 1393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 140074cc835SBarry Smith } 141074cc835SBarry Smith 142074cc835SBarry Smith /*MC 143074cc835SBarry Smith SNESSHELL - a user provided nonlinear solver 144074cc835SBarry Smith 145074cc835SBarry Smith Level: advanced 146074cc835SBarry Smith 147f6dfbefdSBarry Smith .seealso: `SNESCreate()`, `SNES`, `SNESSetType()`, `SNESType`, `SNESShellGetContext()`, `SNESShellSetContext()`, `SNESShellSetSolve()` 148074cc835SBarry Smith M*/ 149074cc835SBarry Smith 150d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes) 151d71ae5a4SJacob Faibussowitsch { 152074cc835SBarry Smith SNES_Shell *shell; 153074cc835SBarry Smith 154074cc835SBarry Smith PetscFunctionBegin; 155074cc835SBarry Smith snes->ops->destroy = SNESDestroy_Shell; 156074cc835SBarry Smith snes->ops->setup = SNESSetUp_Shell; 157074cc835SBarry Smith snes->ops->setfromoptions = SNESSetFromOptions_Shell; 158074cc835SBarry Smith snes->ops->view = SNESView_Shell; 159074cc835SBarry Smith snes->ops->solve = SNESSolve_Shell; 160074cc835SBarry Smith snes->ops->reset = SNESReset_Shell; 161074cc835SBarry Smith 162074cc835SBarry Smith snes->usesksp = PETSC_FALSE; 163efd4aadfSBarry Smith snes->usesnpc = PETSC_FALSE; 164074cc835SBarry Smith 1654fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 1664fc747eaSLawrence Mitchell 1674dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&shell)); 168074cc835SBarry Smith snes->data = (void *)shell; 1699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)snes, "SNESShellSetSolve_C", SNESShellSetSolve_Shell)); 1703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 171074cc835SBarry Smith } 172