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 9074cc835SBarry Smith SNESShellSetSolve - Sets routine to apply as solver 10074cc835SBarry Smith 11c3339decSBarry Smith Logically Collective 12074cc835SBarry Smith 13074cc835SBarry Smith Input Parameters: 14f6dfbefdSBarry Smith + snes - the `SNES` nonlinear solver context 15074cc835SBarry Smith - apply - the application-provided solver routine 16074cc835SBarry Smith 17*20f4b53cSBarry Smith Calling sequence of `apply`: 18074cc835SBarry Smith .vb 19074cc835SBarry Smith PetscErrorCode apply(SNES snes, Vec xout) 20074cc835SBarry Smith .ve 21f6dfbefdSBarry Smith + snes - the preconditioner, get the application context with `SNESShellGetContext()` provided with `SNESShelletContext()` 22074cc835SBarry Smith - xout - solution vector 23074cc835SBarry Smith 24074cc835SBarry Smith Level: advanced 25074cc835SBarry Smith 26db781477SPatrick Sanan .seealso: `SNESSHELL`, `SNESShellSetContext()`, `SNESShellGetContext()` 27074cc835SBarry Smith @*/ 28d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESShellSetSolve(SNES snes, PetscErrorCode (*solve)(SNES, Vec)) 29d71ae5a4SJacob Faibussowitsch { 30074cc835SBarry Smith PetscFunctionBegin; 31074cc835SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 32cac4c232SBarry Smith PetscTryMethod(snes, "SNESShellSetSolve_C", (SNES, PetscErrorCode(*)(SNES, Vec)), (snes, solve)); 333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34074cc835SBarry Smith } 35074cc835SBarry Smith 36d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESReset_Shell(SNES snes) 37d71ae5a4SJacob Faibussowitsch { 38074cc835SBarry Smith PetscFunctionBegin; 393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40074cc835SBarry Smith } 41074cc835SBarry Smith 42d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESDestroy_Shell(SNES snes) 43d71ae5a4SJacob Faibussowitsch { 44074cc835SBarry Smith PetscFunctionBegin; 459566063dSJacob Faibussowitsch PetscCall(SNESReset_Shell(snes)); 469566063dSJacob Faibussowitsch PetscCall(PetscFree(snes->data)); 473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48074cc835SBarry Smith } 49074cc835SBarry Smith 50d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUp_Shell(SNES snes) 51d71ae5a4SJacob Faibussowitsch { 52074cc835SBarry Smith PetscFunctionBegin; 533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 54074cc835SBarry Smith } 55074cc835SBarry Smith 56d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFromOptions_Shell(SNES snes, PetscOptionItems *PetscOptionsObject) 57d71ae5a4SJacob Faibussowitsch { 58074cc835SBarry Smith PetscFunctionBegin; 59d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "SNES Shell options"); 603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 61074cc835SBarry Smith } 62074cc835SBarry Smith 63d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESView_Shell(SNES snes, PetscViewer viewer) 64d71ae5a4SJacob Faibussowitsch { 65074cc835SBarry Smith PetscFunctionBegin; 663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 67074cc835SBarry Smith } 68074cc835SBarry Smith 6990b77ac2SPeter Brune /*@ 70f6dfbefdSBarry Smith SNESShellGetContext - Returns the user-provided context associated with a `SNESSHELL` 71074cc835SBarry Smith 72074cc835SBarry Smith Not Collective 73074cc835SBarry Smith 74074cc835SBarry Smith Input Parameter: 75f6dfbefdSBarry Smith . snes - should have been created with `SNESSetType`(snes,`SNESSHELL`); 76074cc835SBarry Smith 77074cc835SBarry Smith Output Parameter: 78074cc835SBarry Smith . ctx - the user provided context 79074cc835SBarry Smith 80074cc835SBarry Smith Level: advanced 81074cc835SBarry Smith 82f6dfbefdSBarry Smith .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellSetContext()` 83074cc835SBarry Smith @*/ 84d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESShellGetContext(SNES snes, void *ctx) 85d71ae5a4SJacob Faibussowitsch { 86074cc835SBarry Smith PetscBool flg; 87074cc835SBarry Smith 88074cc835SBarry Smith PetscFunctionBegin; 89074cc835SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 90074cc835SBarry Smith PetscValidPointer(ctx, 2); 919566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg)); 923ec1f749SStefano Zampini if (!flg) *(void **)ctx = NULL; 933ec1f749SStefano Zampini else *(void **)ctx = ((SNES_Shell *)(snes->data))->ctx; 943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 95074cc835SBarry Smith } 96074cc835SBarry Smith 97074cc835SBarry Smith /*@ 98f6dfbefdSBarry Smith SNESShellSetContext - sets the context for a `SNESSHELL` 99074cc835SBarry Smith 100c3339decSBarry Smith Logically Collective 101074cc835SBarry Smith 102074cc835SBarry Smith Input Parameters: 103f6dfbefdSBarry Smith + snes - the `SNESSHELL` 104074cc835SBarry Smith - ctx - the context 105074cc835SBarry Smith 106074cc835SBarry Smith Level: advanced 107074cc835SBarry Smith 108f6dfbefdSBarry Smith Fortran Note: 109f6dfbefdSBarry Smith The context can only be an integer or a `PetscObject` it cannot be a Fortran array or derived type. 110074cc835SBarry Smith 111f6dfbefdSBarry Smith .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellGetContext()` 112074cc835SBarry Smith @*/ 113d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESShellSetContext(SNES snes, void *ctx) 114d71ae5a4SJacob Faibussowitsch { 115074cc835SBarry Smith SNES_Shell *shell = (SNES_Shell *)snes->data; 116074cc835SBarry Smith PetscBool flg; 117074cc835SBarry Smith 118074cc835SBarry Smith PetscFunctionBegin; 119074cc835SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1209566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg)); 1211aa26658SKarl Rupp if (flg) shell->ctx = ctx; 1223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 123074cc835SBarry Smith } 124074cc835SBarry Smith 125d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSolve_Shell(SNES snes) 126d71ae5a4SJacob Faibussowitsch { 127074cc835SBarry Smith SNES_Shell *shell = (SNES_Shell *)snes->data; 128074cc835SBarry Smith 129074cc835SBarry Smith PetscFunctionBegin; 13028b400f6SJacob Faibussowitsch PetscCheck(shell->solve, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONGSTATE, "Must call SNESShellSetSolve() first"); 1311e633543SBarry Smith snes->reason = SNES_CONVERGED_ITS; 1329566063dSJacob Faibussowitsch PetscCall((*shell->solve)(snes, snes->vec_sol)); 1333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 134074cc835SBarry Smith } 135074cc835SBarry Smith 136d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESShellSetSolve_Shell(SNES snes, PetscErrorCode (*solve)(SNES, Vec)) 137d71ae5a4SJacob Faibussowitsch { 138074cc835SBarry Smith SNES_Shell *shell = (SNES_Shell *)snes->data; 139074cc835SBarry Smith 140074cc835SBarry Smith PetscFunctionBegin; 141074cc835SBarry Smith shell->solve = solve; 1423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 143074cc835SBarry Smith } 144074cc835SBarry Smith 145074cc835SBarry Smith /*MC 146074cc835SBarry Smith SNESSHELL - a user provided nonlinear solver 147074cc835SBarry Smith 148074cc835SBarry Smith Level: advanced 149074cc835SBarry Smith 150f6dfbefdSBarry Smith .seealso: `SNESCreate()`, `SNES`, `SNESSetType()`, `SNESType`, `SNESShellGetContext()`, `SNESShellSetContext()`, `SNESShellSetSolve()` 151074cc835SBarry Smith M*/ 152074cc835SBarry Smith 153d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes) 154d71ae5a4SJacob Faibussowitsch { 155074cc835SBarry Smith SNES_Shell *shell; 156074cc835SBarry Smith 157074cc835SBarry Smith PetscFunctionBegin; 158074cc835SBarry Smith snes->ops->destroy = SNESDestroy_Shell; 159074cc835SBarry Smith snes->ops->setup = SNESSetUp_Shell; 160074cc835SBarry Smith snes->ops->setfromoptions = SNESSetFromOptions_Shell; 161074cc835SBarry Smith snes->ops->view = SNESView_Shell; 162074cc835SBarry Smith snes->ops->solve = SNESSolve_Shell; 163074cc835SBarry Smith snes->ops->reset = SNESReset_Shell; 164074cc835SBarry Smith 165074cc835SBarry Smith snes->usesksp = PETSC_FALSE; 166efd4aadfSBarry Smith snes->usesnpc = PETSC_FALSE; 167074cc835SBarry Smith 1684fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 1694fc747eaSLawrence Mitchell 1704dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&shell)); 171074cc835SBarry Smith snes->data = (void *)shell; 1729566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)snes, "SNESShellSetSolve_C", SNESShellSetSolve_Shell)); 1733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 174074cc835SBarry Smith } 175