1af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/ 2074cc835SBarry Smith 3*9371c9d4SSatish Balay typedef struct { 4*9371c9d4SSatish Balay PetscErrorCode (*solve)(SNES, Vec); 5*9371c9d4SSatish Balay void *ctx; 6*9371c9d4SSatish Balay } SNES_Shell; 7074cc835SBarry Smith 8074cc835SBarry Smith /*@C 9074cc835SBarry Smith SNESShellSetSolve - Sets routine to apply as solver 10074cc835SBarry Smith 11074cc835SBarry Smith Logically Collective on SNES 12074cc835SBarry Smith 13074cc835SBarry Smith Input Parameters: 14074cc835SBarry Smith + snes - the nonlinear solver context 15074cc835SBarry Smith - apply - the application-provided solver routine 16074cc835SBarry Smith 17074cc835SBarry Smith Calling sequence of solve: 18074cc835SBarry Smith .vb 19074cc835SBarry Smith PetscErrorCode apply (SNES snes,Vec xout) 20074cc835SBarry Smith .ve 21074cc835SBarry Smith 22074cc835SBarry Smith + snes - the preconditioner, get the application context with SNESShellGetContext() 23074cc835SBarry Smith - xout - solution vector 24074cc835SBarry Smith 2595452b02SPatrick Sanan Notes: 2695452b02SPatrick Sanan the function MUST return an error code of 0 on success and nonzero on failure. 27074cc835SBarry Smith 28074cc835SBarry Smith Level: advanced 29074cc835SBarry Smith 30db781477SPatrick Sanan .seealso: `SNESSHELL`, `SNESShellSetContext()`, `SNESShellGetContext()` 31074cc835SBarry Smith @*/ 32*9371c9d4SSatish Balay PetscErrorCode SNESShellSetSolve(SNES snes, PetscErrorCode (*solve)(SNES, Vec)) { 33074cc835SBarry Smith PetscFunctionBegin; 34074cc835SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 35cac4c232SBarry Smith PetscTryMethod(snes, "SNESShellSetSolve_C", (SNES, PetscErrorCode(*)(SNES, Vec)), (snes, solve)); 36074cc835SBarry Smith PetscFunctionReturn(0); 37074cc835SBarry Smith } 38074cc835SBarry Smith 39*9371c9d4SSatish Balay PetscErrorCode SNESReset_Shell(SNES snes) { 40074cc835SBarry Smith PetscFunctionBegin; 41074cc835SBarry Smith PetscFunctionReturn(0); 42074cc835SBarry Smith } 43074cc835SBarry Smith 44*9371c9d4SSatish Balay PetscErrorCode SNESDestroy_Shell(SNES snes) { 45074cc835SBarry Smith PetscFunctionBegin; 469566063dSJacob Faibussowitsch PetscCall(SNESReset_Shell(snes)); 479566063dSJacob Faibussowitsch PetscCall(PetscFree(snes->data)); 48074cc835SBarry Smith PetscFunctionReturn(0); 49074cc835SBarry Smith } 50074cc835SBarry Smith 51*9371c9d4SSatish Balay PetscErrorCode SNESSetUp_Shell(SNES snes) { 52074cc835SBarry Smith PetscFunctionBegin; 53074cc835SBarry Smith PetscFunctionReturn(0); 54074cc835SBarry Smith } 55074cc835SBarry Smith 56*9371c9d4SSatish Balay PetscErrorCode SNESSetFromOptions_Shell(SNES snes, PetscOptionItems *PetscOptionsObject) { 57074cc835SBarry Smith PetscFunctionBegin; 58d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "SNES Shell options"); 59074cc835SBarry Smith PetscFunctionReturn(0); 60074cc835SBarry Smith } 61074cc835SBarry Smith 62*9371c9d4SSatish Balay PetscErrorCode SNESView_Shell(SNES snes, PetscViewer viewer) { 63074cc835SBarry Smith PetscFunctionBegin; 64074cc835SBarry Smith PetscFunctionReturn(0); 65074cc835SBarry Smith } 66074cc835SBarry Smith 6790b77ac2SPeter Brune /*@ 68074cc835SBarry Smith SNESShellGetContext - Returns the user-provided context associated with a shell SNES 69074cc835SBarry Smith 70074cc835SBarry Smith Not Collective 71074cc835SBarry Smith 72074cc835SBarry Smith Input Parameter: 73074cc835SBarry Smith . snes - should have been created with SNESSetType(snes,SNESSHELL); 74074cc835SBarry Smith 75074cc835SBarry Smith Output Parameter: 76074cc835SBarry Smith . ctx - the user provided context 77074cc835SBarry Smith 78074cc835SBarry Smith Level: advanced 79074cc835SBarry Smith 80074cc835SBarry Smith Notes: 81074cc835SBarry Smith This routine is intended for use within various shell routines 82074cc835SBarry Smith 83db781477SPatrick Sanan .seealso: `SNESCreateShell()`, `SNESShellSetContext()` 84074cc835SBarry Smith @*/ 85*9371c9d4SSatish Balay PetscErrorCode SNESShellGetContext(SNES snes, void *ctx) { 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; 94074cc835SBarry Smith PetscFunctionReturn(0); 95074cc835SBarry Smith } 96074cc835SBarry Smith 97074cc835SBarry Smith /*@ 98074cc835SBarry Smith SNESShellSetContext - sets the context for a shell SNES 99074cc835SBarry Smith 100074cc835SBarry Smith Logically Collective on SNES 101074cc835SBarry Smith 102074cc835SBarry Smith Input Parameters: 103074cc835SBarry Smith + snes - the shell SNES 104074cc835SBarry Smith - ctx - the context 105074cc835SBarry Smith 106074cc835SBarry Smith Level: advanced 107074cc835SBarry Smith 10895452b02SPatrick Sanan Fortran Notes: 10995452b02SPatrick Sanan The context can only be an integer or a PetscObject 110074cc835SBarry Smith unfortunately it cannot be a Fortran array or derived type. 111074cc835SBarry Smith 112db781477SPatrick Sanan .seealso: `SNESCreateShell()`, `SNESShellGetContext()` 113074cc835SBarry Smith @*/ 114*9371c9d4SSatish Balay PetscErrorCode SNESShellSetContext(SNES snes, void *ctx) { 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; 122074cc835SBarry Smith PetscFunctionReturn(0); 123074cc835SBarry Smith } 124074cc835SBarry Smith 125*9371c9d4SSatish Balay PetscErrorCode SNESSolve_Shell(SNES snes) { 126074cc835SBarry Smith SNES_Shell *shell = (SNES_Shell *)snes->data; 127074cc835SBarry Smith 128074cc835SBarry Smith PetscFunctionBegin; 12928b400f6SJacob Faibussowitsch PetscCheck(shell->solve, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONGSTATE, "Must call SNESShellSetSolve() first"); 1301e633543SBarry Smith snes->reason = SNES_CONVERGED_ITS; 1319566063dSJacob Faibussowitsch PetscCall((*shell->solve)(snes, snes->vec_sol)); 132074cc835SBarry Smith PetscFunctionReturn(0); 133074cc835SBarry Smith } 134074cc835SBarry Smith 135*9371c9d4SSatish Balay PetscErrorCode SNESShellSetSolve_Shell(SNES snes, PetscErrorCode (*solve)(SNES, Vec)) { 136074cc835SBarry Smith SNES_Shell *shell = (SNES_Shell *)snes->data; 137074cc835SBarry Smith 138074cc835SBarry Smith PetscFunctionBegin; 139074cc835SBarry Smith shell->solve = solve; 140074cc835SBarry Smith PetscFunctionReturn(0); 141074cc835SBarry Smith } 142074cc835SBarry Smith 143074cc835SBarry Smith /*MC 144074cc835SBarry Smith SNESSHELL - a user provided nonlinear solver 145074cc835SBarry Smith 146074cc835SBarry Smith Level: advanced 147074cc835SBarry Smith 148db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNES`, `SNESSetType()`, `SNESType` 149074cc835SBarry Smith M*/ 150074cc835SBarry Smith 151*9371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes) { 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 1679566063dSJacob Faibussowitsch PetscCall(PetscNewLog(snes, &shell)); 168074cc835SBarry Smith snes->data = (void *)shell; 1699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)snes, "SNESShellSetSolve_C", SNESShellSetSolve_Shell)); 170074cc835SBarry Smith PetscFunctionReturn(0); 171074cc835SBarry Smith } 172