1af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/ 2af0996ceSBarry Smith #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/ 36cab3a1bSJed Brown 4d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSNESUnsetFunctionContext_DMSNES(DMSNES sdm) 5d71ae5a4SJacob Faibussowitsch { 6800f99ffSJeremy L Thompson PetscFunctionBegin; 7800f99ffSJeremy L Thompson PetscCall(PetscObjectCompose((PetscObject)sdm, "function ctx", NULL)); 8800f99ffSJeremy L Thompson sdm->functionctxcontainer = NULL; 93ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10800f99ffSJeremy L Thompson } 11800f99ffSJeremy L Thompson 12d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSNESUnsetJacobianContext_DMSNES(DMSNES sdm) 13d71ae5a4SJacob Faibussowitsch { 14800f99ffSJeremy L Thompson PetscFunctionBegin; 15800f99ffSJeremy L Thompson PetscCall(PetscObjectCompose((PetscObject)sdm, "jacobian ctx", NULL)); 16800f99ffSJeremy L Thompson sdm->jacobianctxcontainer = NULL; 173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18800f99ffSJeremy L Thompson } 19800f99ffSJeremy L Thompson 20d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSNESDestroy(DMSNES *kdm) 21d71ae5a4SJacob Faibussowitsch { 226cab3a1bSJed Brown PetscFunctionBegin; 233ba16761SJacob Faibussowitsch if (!*kdm) PetscFunctionReturn(PETSC_SUCCESS); 2422c6f798SBarry Smith PetscValidHeaderSpecific((*kdm), DMSNES_CLASSID, 1); 259371c9d4SSatish Balay if (--((PetscObject)(*kdm))->refct > 0) { 269371c9d4SSatish Balay *kdm = NULL; 273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 289371c9d4SSatish Balay } 29800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetFunctionContext_DMSNES(*kdm)); 30800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetJacobianContext_DMSNES(*kdm)); 319566063dSJacob Faibussowitsch if ((*kdm)->ops->destroy) PetscCall(((*kdm)->ops->destroy)(*kdm)); 329566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(kdm)); 333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3422c6f798SBarry Smith } 3522c6f798SBarry Smith 36d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESLoad(DMSNES kdm, PetscViewer viewer) 37d71ae5a4SJacob Faibussowitsch { 382d53ad75SBarry Smith PetscFunctionBegin; 399566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->computefunction, 1, NULL, PETSC_FUNCTION)); 409566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->computejacobian, 1, NULL, PETSC_FUNCTION)); 413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 422d53ad75SBarry Smith } 432d53ad75SBarry Smith 44d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESView(DMSNES kdm, PetscViewer viewer) 45d71ae5a4SJacob Faibussowitsch { 462d53ad75SBarry Smith PetscBool isascii, isbinary; 472d53ad75SBarry Smith 482d53ad75SBarry Smith PetscFunctionBegin; 499566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 509566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 512d53ad75SBarry Smith if (isascii) { 52d5bc873cSPierre Jolivet #if defined(PETSC_SERIALIZE_FUNCTIONS) 532d53ad75SBarry Smith const char *fname; 542d53ad75SBarry Smith 559566063dSJacob Faibussowitsch PetscCall(PetscFPTFind(kdm->ops->computefunction, &fname)); 5648a46eb9SPierre Jolivet if (fname) PetscCall(PetscViewerASCIIPrintf(viewer, "Function used by SNES: %s\n", fname)); 579566063dSJacob Faibussowitsch PetscCall(PetscFPTFind(kdm->ops->computejacobian, &fname)); 5848a46eb9SPierre Jolivet if (fname) PetscCall(PetscViewerASCIIPrintf(viewer, "Jacobian function used by SNES: %s\n", fname)); 59c7a10e08SBarry Smith #endif 602d53ad75SBarry Smith } else if (isbinary) { 613964eb88SJed Brown struct { 623964eb88SJed Brown PetscErrorCode (*func)(SNES, Vec, Vec, void *); 639200755eSBarry Smith } funcstruct; 649200755eSBarry Smith struct { 65d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *); 669200755eSBarry Smith } jacstruct; 679200755eSBarry Smith funcstruct.func = kdm->ops->computefunction; 689200755eSBarry Smith jacstruct.jac = kdm->ops->computejacobian; 699566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(viewer, &funcstruct, 1, PETSC_FUNCTION)); 709566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(viewer, &jacstruct, 1, PETSC_FUNCTION)); 712d53ad75SBarry Smith } 723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 732d53ad75SBarry Smith } 742d53ad75SBarry Smith 75d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSNESCreate(MPI_Comm comm, DMSNES *kdm) 76d71ae5a4SJacob Faibussowitsch { 7722c6f798SBarry Smith PetscFunctionBegin; 789566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 799566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(*kdm, DMSNES_CLASSID, "DMSNES", "DMSNES", "DMSNES", comm, DMSNESDestroy, DMSNESView)); 803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 816cab3a1bSJed Brown } 826cab3a1bSJed Brown 83942e3340SBarry Smith /* Attaches the DMSNES to the coarse level. 846cab3a1bSJed Brown * Under what conditions should we copy versus duplicate? 856cab3a1bSJed Brown */ 86d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCoarsenHook_DMSNES(DM dm, DM dmc, void *ctx) 87d71ae5a4SJacob Faibussowitsch { 886cab3a1bSJed Brown PetscFunctionBegin; 899566063dSJacob Faibussowitsch PetscCall(DMCopyDMSNES(dm, dmc)); 903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 916cab3a1bSJed Brown } 926cab3a1bSJed Brown 93dfe15315SJed Brown /* This could restrict auxiliary information to the coarse level. 94caa4e7f2SJed Brown */ 95d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMRestrictHook_DMSNES(DM dm, Mat Restrict, Vec rscale, Mat Inject, DM dmc, void *ctx) 96d71ae5a4SJacob Faibussowitsch { 97caa4e7f2SJed Brown PetscFunctionBegin; 983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 99caa4e7f2SJed Brown } 100caa4e7f2SJed Brown 101be081cd6SPeter Brune /* Attaches the DMSNES to the subdomain. */ 102d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainHook_DMSNES(DM dm, DM subdm, void *ctx) 103d71ae5a4SJacob Faibussowitsch { 104be081cd6SPeter Brune PetscFunctionBegin; 1059566063dSJacob Faibussowitsch PetscCall(DMCopyDMSNES(dm, subdm)); 1063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 107be081cd6SPeter Brune } 108be081cd6SPeter Brune 109be081cd6SPeter Brune /* This could restrict auxiliary information to the coarse level. 110be081cd6SPeter Brune */ 111d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainRestrictHook_DMSNES(DM dm, VecScatter gscat, VecScatter lscat, DM subdm, void *ctx) 112d71ae5a4SJacob Faibussowitsch { 113be081cd6SPeter Brune PetscFunctionBegin; 1143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 115be081cd6SPeter Brune } 116be081cd6SPeter Brune 117d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMRefineHook_DMSNES(DM dm, DM dmf, void *ctx) 118d71ae5a4SJacob Faibussowitsch { 11903a0fabfSPeter Brune PetscFunctionBegin; 1209566063dSJacob Faibussowitsch PetscCall(DMCopyDMSNES(dm, dmf)); 1213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12203a0fabfSPeter Brune } 12303a0fabfSPeter Brune 12403a0fabfSPeter Brune /* This could restrict auxiliary information to the coarse level. 12503a0fabfSPeter Brune */ 126d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMInterpolateHook_DMSNES(DM dm, Mat Interp, DM dmf, void *ctx) 127d71ae5a4SJacob Faibussowitsch { 12803a0fabfSPeter Brune PetscFunctionBegin; 1293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13003a0fabfSPeter Brune } 13103a0fabfSPeter Brune 13266976f2fSJacob Faibussowitsch /* 133f6dfbefdSBarry Smith DMSNESCopy - copies the information in a `DMSNES` to another `DMSNES` 13422c6f798SBarry Smith 13522c6f798SBarry Smith Not Collective 13622c6f798SBarry Smith 1374165533cSJose E. Roman Input Parameters: 138f6dfbefdSBarry Smith + kdm - Original `DMSNES` 139f6dfbefdSBarry Smith - nkdm - `DMSNES` to receive the data, should have been created with `DMSNESCreate()` 14022c6f798SBarry Smith 14122c6f798SBarry Smith Level: developer 14222c6f798SBarry Smith 143*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESCreate()`, `DMSNESDestroy()` 14466976f2fSJacob Faibussowitsch */ 14566976f2fSJacob Faibussowitsch static PetscErrorCode DMSNESCopy(DMSNES kdm, DMSNES nkdm) 146d71ae5a4SJacob Faibussowitsch { 14722c6f798SBarry Smith PetscFunctionBegin; 14822c6f798SBarry Smith PetscValidHeaderSpecific(kdm, DMSNES_CLASSID, 1); 14922c6f798SBarry Smith PetscValidHeaderSpecific(nkdm, DMSNES_CLASSID, 2); 15022c6f798SBarry Smith nkdm->ops->computefunction = kdm->ops->computefunction; 1512bc4d0c4SPeter Brune nkdm->ops->computejacobian = kdm->ops->computejacobian; 15222c6f798SBarry Smith nkdm->ops->computegs = kdm->ops->computegs; 15322c6f798SBarry Smith nkdm->ops->computeobjective = kdm->ops->computeobjective; 15422c6f798SBarry Smith nkdm->ops->computepjacobian = kdm->ops->computepjacobian; 15522c6f798SBarry Smith nkdm->ops->computepfunction = kdm->ops->computepfunction; 15622c6f798SBarry Smith nkdm->ops->destroy = kdm->ops->destroy; 15722c6f798SBarry Smith nkdm->ops->duplicate = kdm->ops->duplicate; 15822c6f798SBarry Smith 15922c6f798SBarry Smith nkdm->gsctx = kdm->gsctx; 16022c6f798SBarry Smith nkdm->pctx = kdm->pctx; 16122c6f798SBarry Smith nkdm->objectivectx = kdm->objectivectx; 162af903c1dSJunchao Zhang nkdm->originaldm = kdm->originaldm; 163800f99ffSJeremy L Thompson nkdm->functionctxcontainer = kdm->functionctxcontainer; 164800f99ffSJeremy L Thompson nkdm->jacobianctxcontainer = kdm->jacobianctxcontainer; 165800f99ffSJeremy L Thompson if (nkdm->functionctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "function ctx", (PetscObject)nkdm->functionctxcontainer)); 166800f99ffSJeremy L Thompson if (nkdm->jacobianctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "jacobian ctx", (PetscObject)nkdm->jacobianctxcontainer)); 16722c6f798SBarry Smith 16822c6f798SBarry Smith /* 16922c6f798SBarry Smith nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0]; 17022c6f798SBarry Smith nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1]; 17122c6f798SBarry Smith nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2]; 17222c6f798SBarry Smith */ 17322c6f798SBarry Smith 17422c6f798SBarry Smith /* implementation specific copy hooks */ 175dbbe0bcdSBarry Smith PetscTryTypeMethod(kdm, duplicate, nkdm); 1763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17722c6f798SBarry Smith } 17822c6f798SBarry Smith 1796cab3a1bSJed Brown /*@C 180f6dfbefdSBarry Smith DMGetDMSNES - get read-only private `DMSNES` context from a `DM` 1816cab3a1bSJed Brown 1826cab3a1bSJed Brown Not Collective 1836cab3a1bSJed Brown 1844165533cSJose E. Roman Input Parameter: 185f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES` 1866cab3a1bSJed Brown 1874165533cSJose E. Roman Output Parameter: 188f6dfbefdSBarry Smith . snesdm - private `DMSNES` context 1896cab3a1bSJed Brown 1906cab3a1bSJed Brown Level: developer 1916cab3a1bSJed Brown 192f6dfbefdSBarry Smith Note: 193f6dfbefdSBarry Smith Use `DMGetDMSNESWrite()` if write access is needed. The DMSNESSetXXX API should be used wherever possible. 1946cab3a1bSJed Brown 195*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMGetDMSNESWrite()` 1966cab3a1bSJed Brown @*/ 197d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDMSNES(DM dm, DMSNES *snesdm) 198d71ae5a4SJacob Faibussowitsch { 1996cab3a1bSJed Brown PetscFunctionBegin; 2006cab3a1bSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 201b4615a05SBarry Smith *snesdm = (DMSNES)dm->dmsnes; 20222c6f798SBarry Smith if (!*snesdm) { 2039566063dSJacob Faibussowitsch PetscCall(PetscInfo(dm, "Creating new DMSNES\n")); 2049566063dSJacob Faibussowitsch PetscCall(DMSNESCreate(PetscObjectComm((PetscObject)dm), snesdm)); 2051aa26658SKarl Rupp 206b4615a05SBarry Smith dm->dmsnes = (PetscObject)*snesdm; 207af903c1dSJunchao Zhang (*snesdm)->originaldm = dm; 2089566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(dm, DMCoarsenHook_DMSNES, DMRestrictHook_DMSNES, NULL)); 2099566063dSJacob Faibussowitsch PetscCall(DMRefineHookAdd(dm, DMRefineHook_DMSNES, DMInterpolateHook_DMSNES, NULL)); 2109566063dSJacob Faibussowitsch PetscCall(DMSubDomainHookAdd(dm, DMSubDomainHook_DMSNES, DMSubDomainRestrictHook_DMSNES, NULL)); 2116cab3a1bSJed Brown } 2123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2136cab3a1bSJed Brown } 2146cab3a1bSJed Brown 2156cab3a1bSJed Brown /*@C 216f6dfbefdSBarry Smith DMGetDMSNESWrite - get write access to private `DMSNES` context from a `DM` 2176cab3a1bSJed Brown 2186cab3a1bSJed Brown Not Collective 2196cab3a1bSJed Brown 2204165533cSJose E. Roman Input Parameter: 221f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES` 2226cab3a1bSJed Brown 2234165533cSJose E. Roman Output Parameter: 224f6dfbefdSBarry Smith . snesdm - private `DMSNES` context 2256cab3a1bSJed Brown 2266cab3a1bSJed Brown Level: developer 2276cab3a1bSJed Brown 228*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMGetDMSNES()` 2296cab3a1bSJed Brown @*/ 230d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDMSNESWrite(DM dm, DMSNES *snesdm) 231d71ae5a4SJacob Faibussowitsch { 232942e3340SBarry Smith DMSNES sdm; 2336cab3a1bSJed Brown 2346cab3a1bSJed Brown PetscFunctionBegin; 2356cab3a1bSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2369566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 23728b400f6SJacob Faibussowitsch PetscCheck(sdm->originaldm, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DMSNES has a NULL originaldm"); 2386cab3a1bSJed Brown if (sdm->originaldm != dm) { /* Copy on write */ 239b4615a05SBarry Smith DMSNES oldsdm = sdm; 2409566063dSJacob Faibussowitsch PetscCall(PetscInfo(dm, "Copying DMSNES due to write\n")); 2419566063dSJacob Faibussowitsch PetscCall(DMSNESCreate(PetscObjectComm((PetscObject)dm), &sdm)); 2429566063dSJacob Faibussowitsch PetscCall(DMSNESCopy(oldsdm, sdm)); 2439566063dSJacob Faibussowitsch PetscCall(DMSNESDestroy((DMSNES *)&dm->dmsnes)); 244b4615a05SBarry Smith dm->dmsnes = (PetscObject)sdm; 245af903c1dSJunchao Zhang sdm->originaldm = dm; 2466cab3a1bSJed Brown } 2476cab3a1bSJed Brown *snesdm = sdm; 2483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2496cab3a1bSJed Brown } 2506cab3a1bSJed Brown 2516cab3a1bSJed Brown /*@C 252f6dfbefdSBarry Smith DMCopyDMSNES - copies a `DMSNES` context to a new `DM` 2536cab3a1bSJed Brown 2546cab3a1bSJed Brown Logically Collective 2556cab3a1bSJed Brown 2564165533cSJose E. Roman Input Parameters: 257f6dfbefdSBarry Smith + dmsrc - `DM` to obtain context from 258f6dfbefdSBarry Smith - dmdest - `DM` to add context to 2596cab3a1bSJed Brown 2606cab3a1bSJed Brown Level: developer 2616cab3a1bSJed Brown 2626cab3a1bSJed Brown Note: 2636cab3a1bSJed Brown The context is copied by reference. This function does not ensure that a context exists. 2646cab3a1bSJed Brown 265*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMGetDMSNES()`, `SNESSetDM()` 2666cab3a1bSJed Brown @*/ 267d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyDMSNES(DM dmsrc, DM dmdest) 268d71ae5a4SJacob Faibussowitsch { 2696cab3a1bSJed Brown PetscFunctionBegin; 2706cab3a1bSJed Brown PetscValidHeaderSpecific(dmsrc, DM_CLASSID, 1); 2716cab3a1bSJed Brown PetscValidHeaderSpecific(dmdest, DM_CLASSID, 2); 2729566063dSJacob Faibussowitsch if (!dmdest->dmsnes) PetscCall(DMSNESCreate(PetscObjectComm((PetscObject)dmdest), (DMSNES *)&dmdest->dmsnes)); 2739566063dSJacob Faibussowitsch PetscCall(DMSNESCopy((DMSNES)dmsrc->dmsnes, (DMSNES)dmdest->dmsnes)); 2749566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(dmdest, DMCoarsenHook_DMSNES, NULL, NULL)); 2759566063dSJacob Faibussowitsch PetscCall(DMRefineHookAdd(dmdest, DMRefineHook_DMSNES, NULL, NULL)); 2769566063dSJacob Faibussowitsch PetscCall(DMSubDomainHookAdd(dmdest, DMSubDomainHook_DMSNES, DMSubDomainRestrictHook_DMSNES, NULL)); 2773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2786cab3a1bSJed Brown } 2796cab3a1bSJed Brown 2806cab3a1bSJed Brown /*@C 281f6dfbefdSBarry Smith DMSNESSetFunction - set `SNES` residual evaluation function 2826cab3a1bSJed Brown 2836cab3a1bSJed Brown Not Collective 2846cab3a1bSJed Brown 2854165533cSJose E. Roman Input Parameters: 286f6dfbefdSBarry Smith + dm - DM to be used with `SNES` 287f6dfbefdSBarry Smith . f - residual evaluation function; see `SNESFunction` for details 2886cab3a1bSJed Brown - ctx - context for residual evaluation 2896cab3a1bSJed Brown 2906cab3a1bSJed Brown Level: advanced 2916cab3a1bSJed Brown 2926cab3a1bSJed Brown Note: 293f6dfbefdSBarry Smith `SNESSetFunction()` is normally used, but it calls this function internally because the user context is actually 294f6dfbefdSBarry Smith associated with the `DM`. This makes the interface consistent regardless of whether the user interacts with a `DM` or 295f6dfbefdSBarry Smith not. 296f6dfbefdSBarry Smith 297*420bcc1bSBarry Smith Developer Note: 298f6dfbefdSBarry Smith If `DM` took a more central role at some later date, this could become the primary method of setting the residual. 2996cab3a1bSJed Brown 300*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `SNESFunction` 3016cab3a1bSJed Brown @*/ 302d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESSetFunction(DM dm, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) 303d71ae5a4SJacob Faibussowitsch { 304942e3340SBarry Smith DMSNES sdm; 3056cab3a1bSJed Brown 3066cab3a1bSJed Brown PetscFunctionBegin; 3076cab3a1bSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3089566063dSJacob Faibussowitsch PetscCall(DMGetDMSNESWrite(dm, &sdm)); 309f8b49ee9SBarry Smith if (f) sdm->ops->computefunction = f; 310800f99ffSJeremy L Thompson if (ctx) { 311800f99ffSJeremy L Thompson PetscContainer ctxcontainer; 312800f99ffSJeremy L Thompson PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)sdm), &ctxcontainer)); 313800f99ffSJeremy L Thompson PetscCall(PetscContainerSetPointer(ctxcontainer, ctx)); 314800f99ffSJeremy L Thompson PetscCall(PetscObjectCompose((PetscObject)sdm, "function ctx", (PetscObject)ctxcontainer)); 315800f99ffSJeremy L Thompson sdm->functionctxcontainer = ctxcontainer; 316800f99ffSJeremy L Thompson PetscCall(PetscContainerDestroy(&ctxcontainer)); 317800f99ffSJeremy L Thompson } 3183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 319800f99ffSJeremy L Thompson } 320800f99ffSJeremy L Thompson 321800f99ffSJeremy L Thompson /*@C 3225cb80ecdSBarry Smith DMSNESSetFunctionContextDestroy - set `SNES` residual evaluation context destroy function 323800f99ffSJeremy L Thompson 324800f99ffSJeremy L Thompson Not Collective 325800f99ffSJeremy L Thompson 326800f99ffSJeremy L Thompson Input Parameters: 3275cb80ecdSBarry Smith + dm - `DM` to be used with `SNES` 3285cb80ecdSBarry Smith - f - residual evaluation context destroy function 329800f99ffSJeremy L Thompson 330800f99ffSJeremy L Thompson Level: advanced 331800f99ffSJeremy L Thompson 332*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetFunction()`, `SNESSetFunction()` 333800f99ffSJeremy L Thompson @*/ 334d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESSetFunctionContextDestroy(DM dm, PetscErrorCode (*f)(void *)) 335d71ae5a4SJacob Faibussowitsch { 336800f99ffSJeremy L Thompson DMSNES sdm; 337800f99ffSJeremy L Thompson 338800f99ffSJeremy L Thompson PetscFunctionBegin; 339800f99ffSJeremy L Thompson PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 340800f99ffSJeremy L Thompson PetscCall(DMGetDMSNESWrite(dm, &sdm)); 341800f99ffSJeremy L Thompson if (sdm->functionctxcontainer) PetscCall(PetscContainerSetUserDestroy(sdm->functionctxcontainer, f)); 3423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 343800f99ffSJeremy L Thompson } 344800f99ffSJeremy L Thompson 345d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESUnsetFunctionContext_Internal(DM dm) 346d71ae5a4SJacob Faibussowitsch { 347800f99ffSJeremy L Thompson DMSNES sdm; 348800f99ffSJeremy L Thompson 349800f99ffSJeremy L Thompson PetscFunctionBegin; 350800f99ffSJeremy L Thompson PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 351800f99ffSJeremy L Thompson PetscCall(DMGetDMSNESWrite(dm, &sdm)); 352800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetFunctionContext_DMSNES(sdm)); 3533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3546cab3a1bSJed Brown } 3556cab3a1bSJed Brown 3566cab3a1bSJed Brown /*@C 357f6dfbefdSBarry Smith DMSNESSetMFFunction - set `SNES` residual evaluation function used in applying the matrix-free Jacobian with -snes_mf_operator 358bbc1464cSBarry Smith 359c3339decSBarry Smith Logically Collective 360bbc1464cSBarry Smith 3614165533cSJose E. Roman Input Parameters: 362f6dfbefdSBarry Smith + dm - `DM` to be used with `SNES` 3630b4db180SJacob Faibussowitsch . func - residual evaluation function; see `SNESFunction` for details 3640b4db180SJacob Faibussowitsch - ctx - optional function context 3650b4db180SJacob Faibussowitsch 3660b4db180SJacob Faibussowitsch Calling sequence of `func`: 3670b4db180SJacob Faibussowitsch + snes - the solver object 3680b4db180SJacob Faibussowitsch . x - the input vector 3690b4db180SJacob Faibussowitsch . f - the output vector 3700b4db180SJacob Faibussowitsch - ctx - the optional function context 371bbc1464cSBarry Smith 372bbc1464cSBarry Smith Level: advanced 373bbc1464cSBarry Smith 374*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `SNESFunction`, `DMSNESSetFunction()` 375bbc1464cSBarry Smith @*/ 3760b4db180SJacob Faibussowitsch PetscErrorCode DMSNESSetMFFunction(DM dm, PetscErrorCode (*func)(SNES snes, Vec x, Vec f, void *ctx), void *ctx) 377d71ae5a4SJacob Faibussowitsch { 378bbc1464cSBarry Smith DMSNES sdm; 379bbc1464cSBarry Smith 380bbc1464cSBarry Smith PetscFunctionBegin; 381bbc1464cSBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3820b4db180SJacob Faibussowitsch if (func || ctx) PetscCall(DMGetDMSNESWrite(dm, &sdm)); 3830b4db180SJacob Faibussowitsch if (func) sdm->ops->computemffunction = func; 384bbc1464cSBarry Smith if (ctx) sdm->mffunctionctx = ctx; 3853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 386bbc1464cSBarry Smith } 387bbc1464cSBarry Smith 388bbc1464cSBarry Smith /*@C 389f6dfbefdSBarry Smith DMSNESGetFunction - get `SNES` residual evaluation function 3906cab3a1bSJed Brown 3916cab3a1bSJed Brown Not Collective 3926cab3a1bSJed Brown 3934165533cSJose E. Roman Input Parameter: 394f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES` 3956cab3a1bSJed Brown 3964165533cSJose E. Roman Output Parameters: 397f6dfbefdSBarry Smith + f - residual evaluation function; see `SNESFunction` for details 3986cab3a1bSJed Brown - ctx - context for residual evaluation 3996cab3a1bSJed Brown 4006cab3a1bSJed Brown Level: advanced 4016cab3a1bSJed Brown 4026cab3a1bSJed Brown Note: 403f6dfbefdSBarry Smith `SNESGetFunction()` is normally used, but it calls this function internally because the user context is actually 404f6dfbefdSBarry Smith associated with the `DM`. 4056cab3a1bSJed Brown 406*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `DMSNESSetFunction()`, `SNESSetFunction()`, `SNESFunction` 4076cab3a1bSJed Brown @*/ 408d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESGetFunction(DM dm, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) 409d71ae5a4SJacob Faibussowitsch { 410942e3340SBarry Smith DMSNES sdm; 4116cab3a1bSJed Brown 4126cab3a1bSJed Brown PetscFunctionBegin; 4136cab3a1bSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4149566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 415f8b49ee9SBarry Smith if (f) *f = sdm->ops->computefunction; 416800f99ffSJeremy L Thompson if (ctx) { 417800f99ffSJeremy L Thompson if (sdm->functionctxcontainer) PetscCall(PetscContainerGetPointer(sdm->functionctxcontainer, ctx)); 418800f99ffSJeremy L Thompson else *ctx = NULL; 419800f99ffSJeremy L Thompson } 4203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4216cab3a1bSJed Brown } 4226cab3a1bSJed Brown 4232a4ee8f2SPeter Brune /*@C 424f6dfbefdSBarry Smith DMSNESSetObjective - set `SNES` objective evaluation function 4252a4ee8f2SPeter Brune 4262a4ee8f2SPeter Brune Not Collective 4272a4ee8f2SPeter Brune 4284165533cSJose E. Roman Input Parameters: 429f6dfbefdSBarry Smith + dm - `DM` to be used with `SNES` 430f6dfbefdSBarry Smith . obj - objective evaluation function; see `SNESObjectiveFunction` for details 4312a4ee8f2SPeter Brune - ctx - context for residual evaluation 4322a4ee8f2SPeter Brune 4332a4ee8f2SPeter Brune Level: advanced 4342a4ee8f2SPeter Brune 435*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESGetObjective()`, `DMSNESSetFunction()` 4362a4ee8f2SPeter Brune @*/ 437d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESSetObjective(DM dm, PetscErrorCode (*obj)(SNES, Vec, PetscReal *, void *), void *ctx) 438d71ae5a4SJacob Faibussowitsch { 439942e3340SBarry Smith DMSNES sdm; 4402a4ee8f2SPeter Brune 4412a4ee8f2SPeter Brune PetscFunctionBegin; 4422a4ee8f2SPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 44348a46eb9SPierre Jolivet if (obj || ctx) PetscCall(DMGetDMSNESWrite(dm, &sdm)); 444f8b49ee9SBarry Smith if (obj) sdm->ops->computeobjective = obj; 4452a4ee8f2SPeter Brune if (ctx) sdm->objectivectx = ctx; 4463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4472a4ee8f2SPeter Brune } 4482a4ee8f2SPeter Brune 4492a4ee8f2SPeter Brune /*@C 450f6dfbefdSBarry Smith DMSNESGetObjective - get `SNES` objective evaluation function 4512a4ee8f2SPeter Brune 4522a4ee8f2SPeter Brune Not Collective 4532a4ee8f2SPeter Brune 4544165533cSJose E. Roman Input Parameter: 455f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES` 4562a4ee8f2SPeter Brune 4574165533cSJose E. Roman Output Parameters: 458f6dfbefdSBarry Smith + obj - residual evaluation function; see `SNESObjectiveFunction` for details 4592a4ee8f2SPeter Brune - ctx - context for residual evaluation 4602a4ee8f2SPeter Brune 4612a4ee8f2SPeter Brune Level: advanced 4622a4ee8f2SPeter Brune 4632a4ee8f2SPeter Brune Note: 464f6dfbefdSBarry Smith `SNESGetFunction()` is normally used, but it calls this function internally because the user context is actually 465f6dfbefdSBarry Smith associated with the `DM`. 4662a4ee8f2SPeter Brune 467*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `DMSNESSetObjective()`, `SNESSetFunction()` 4682a4ee8f2SPeter Brune @*/ 469d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESGetObjective(DM dm, PetscErrorCode (**obj)(SNES, Vec, PetscReal *, void *), void **ctx) 470d71ae5a4SJacob Faibussowitsch { 471942e3340SBarry Smith DMSNES sdm; 4722a4ee8f2SPeter Brune 4732a4ee8f2SPeter Brune PetscFunctionBegin; 4742a4ee8f2SPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4759566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 476f8b49ee9SBarry Smith if (obj) *obj = sdm->ops->computeobjective; 4772a4ee8f2SPeter Brune if (ctx) *ctx = sdm->objectivectx; 4783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4792a4ee8f2SPeter Brune } 4802a4ee8f2SPeter Brune 4816cab3a1bSJed Brown /*@C 482f6dfbefdSBarry Smith DMSNESSetNGS - set `SNES` Gauss-Seidel relaxation function 4836cab3a1bSJed Brown 4846cab3a1bSJed Brown Not Collective 4856cab3a1bSJed Brown 4864165533cSJose E. Roman Input Parameters: 487f6dfbefdSBarry Smith + dm - `DM` to be used with `SNES` 488f6dfbefdSBarry Smith . f - relaxation function, see `SNESGSFunction` 4896cab3a1bSJed Brown - ctx - context for residual evaluation 4906cab3a1bSJed Brown 4916cab3a1bSJed Brown Level: advanced 4926cab3a1bSJed Brown 4936cab3a1bSJed Brown Note: 494f6dfbefdSBarry Smith `SNESSetNGS()` is normally used, but it calls this function internally because the user context is actually 495f6dfbefdSBarry Smith associated with the `DM`. This makes the interface consistent regardless of whether the user interacts with a `DM` or 496f6dfbefdSBarry Smith not. 497f6dfbefdSBarry Smith 498*420bcc1bSBarry Smith Developer Note: 499f6dfbefdSBarry Smith If `DM` took a more central role at some later date, this could become the primary method of supplying the smoother 5006cab3a1bSJed Brown 501*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `DMSNESSetFunction()`, `SNESGSFunction` 5026cab3a1bSJed Brown @*/ 503d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESSetNGS(DM dm, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) 504d71ae5a4SJacob Faibussowitsch { 505942e3340SBarry Smith DMSNES sdm; 5066cab3a1bSJed Brown 5076cab3a1bSJed Brown PetscFunctionBegin; 5086cab3a1bSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 50948a46eb9SPierre Jolivet if (f || ctx) PetscCall(DMGetDMSNESWrite(dm, &sdm)); 510be95d8f1SBarry Smith if (f) sdm->ops->computegs = f; 5116cab3a1bSJed Brown if (ctx) sdm->gsctx = ctx; 5123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5136cab3a1bSJed Brown } 5146cab3a1bSJed Brown 5156cab3a1bSJed Brown /*@C 516f6dfbefdSBarry Smith DMSNESGetNGS - get `SNES` Gauss-Seidel relaxation function 5176cab3a1bSJed Brown 5186cab3a1bSJed Brown Not Collective 5196cab3a1bSJed Brown 5204165533cSJose E. Roman Input Parameter: 521f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES` 5226cab3a1bSJed Brown 5234165533cSJose E. Roman Output Parameters: 52437fdd005SBarry Smith + f - relaxation function which performs Gauss-Seidel sweeps, see `SNESSetNGS()` 5256cab3a1bSJed Brown - ctx - context for residual evaluation 5266cab3a1bSJed Brown 5276cab3a1bSJed Brown Level: advanced 5286cab3a1bSJed Brown 5296cab3a1bSJed Brown Note: 530f6dfbefdSBarry Smith `SNESGetNGS()` is normally used, but it calls this function internally because the user context is actually 531f6dfbefdSBarry Smith associated with the `DM`. 532f6dfbefdSBarry Smith 533*420bcc1bSBarry Smith Developer Note: 534f6dfbefdSBarry Smith This makes the interface consistent regardless of whether the user interacts with a `DM` or 535f6dfbefdSBarry Smith not. If `DM` took a more central role at some later date, this could become the primary method of setting the residual. 5366cab3a1bSJed Brown 537*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESGetNGS()`, `DMSNESGetJacobian()`, `DMSNESGetFunction()` 5386cab3a1bSJed Brown @*/ 539d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESGetNGS(DM dm, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) 540d71ae5a4SJacob Faibussowitsch { 541942e3340SBarry Smith DMSNES sdm; 5426cab3a1bSJed Brown 5436cab3a1bSJed Brown PetscFunctionBegin; 5446cab3a1bSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5459566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 546be95d8f1SBarry Smith if (f) *f = sdm->ops->computegs; 5476cab3a1bSJed Brown if (ctx) *ctx = sdm->gsctx; 5483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5496cab3a1bSJed Brown } 5506cab3a1bSJed Brown 5516cab3a1bSJed Brown /*@C 552f6dfbefdSBarry Smith DMSNESSetJacobian - set `SNES` Jacobian evaluation function 5536cab3a1bSJed Brown 5546cab3a1bSJed Brown Not Collective 5556cab3a1bSJed Brown 5564165533cSJose E. Roman Input Parameters: 557f6dfbefdSBarry Smith + dm - `DM` to be used with `SNES` 558f8b49ee9SBarry Smith . J - Jacobian evaluation function 5596cab3a1bSJed Brown - ctx - context for residual evaluation 5606cab3a1bSJed Brown 5616cab3a1bSJed Brown Level: advanced 5626cab3a1bSJed Brown 5636cab3a1bSJed Brown Note: 564f6dfbefdSBarry Smith `SNESSetJacobian()` is normally used, but it calls this function internally because the user context is actually 565f6dfbefdSBarry Smith associated with the `DM`. 566f6dfbefdSBarry Smith 567*420bcc1bSBarry Smith Developer Note: 568f6dfbefdSBarry Smith This makes the interface consistent regardless of whether the user interacts with a `DM` or 569f6dfbefdSBarry Smith not. If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian. 5706cab3a1bSJed Brown 571*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESGetJacobian()`, `SNESSetJacobian()`, `SNESJacobianFunction` 5726cab3a1bSJed Brown @*/ 573d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESSetJacobian(DM dm, PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx) 574d71ae5a4SJacob Faibussowitsch { 575942e3340SBarry Smith DMSNES sdm; 5766cab3a1bSJed Brown 5776cab3a1bSJed Brown PetscFunctionBegin; 5786cab3a1bSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 579800f99ffSJeremy L Thompson if (J || ctx) PetscCall(DMGetDMSNESWrite(dm, &sdm)); 580f8b49ee9SBarry Smith if (J) sdm->ops->computejacobian = J; 581800f99ffSJeremy L Thompson if (ctx) { 582800f99ffSJeremy L Thompson PetscContainer ctxcontainer; 583800f99ffSJeremy L Thompson PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)sdm), &ctxcontainer)); 584800f99ffSJeremy L Thompson PetscCall(PetscContainerSetPointer(ctxcontainer, ctx)); 585800f99ffSJeremy L Thompson PetscCall(PetscObjectCompose((PetscObject)sdm, "jacobian ctx", (PetscObject)ctxcontainer)); 586800f99ffSJeremy L Thompson sdm->jacobianctxcontainer = ctxcontainer; 587800f99ffSJeremy L Thompson PetscCall(PetscContainerDestroy(&ctxcontainer)); 588800f99ffSJeremy L Thompson } 5893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 590800f99ffSJeremy L Thompson } 591800f99ffSJeremy L Thompson 592800f99ffSJeremy L Thompson /*@C 5935cb80ecdSBarry Smith DMSNESSetJacobianContextDestroy - set `SNES` Jacobian evaluation context destroy function 594800f99ffSJeremy L Thompson 595800f99ffSJeremy L Thompson Not Collective 596800f99ffSJeremy L Thompson 597800f99ffSJeremy L Thompson Input Parameters: 5985cb80ecdSBarry Smith + dm - `DM` to be used with `SNES` 59935cb6cd3SPierre Jolivet - f - Jacobian evaluation context destroy function 600800f99ffSJeremy L Thompson 601800f99ffSJeremy L Thompson Level: advanced 602800f99ffSJeremy L Thompson 603*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetJacobian()` 604800f99ffSJeremy L Thompson @*/ 605d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESSetJacobianContextDestroy(DM dm, PetscErrorCode (*f)(void *)) 606d71ae5a4SJacob Faibussowitsch { 607800f99ffSJeremy L Thompson DMSNES sdm; 608800f99ffSJeremy L Thompson 609800f99ffSJeremy L Thompson PetscFunctionBegin; 610800f99ffSJeremy L Thompson PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 611800f99ffSJeremy L Thompson PetscCall(DMGetDMSNESWrite(dm, &sdm)); 612800f99ffSJeremy L Thompson if (sdm->jacobianctxcontainer) PetscCall(PetscContainerSetUserDestroy(sdm->jacobianctxcontainer, f)); 6133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 614800f99ffSJeremy L Thompson } 615800f99ffSJeremy L Thompson 616d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESUnsetJacobianContext_Internal(DM dm) 617d71ae5a4SJacob Faibussowitsch { 618800f99ffSJeremy L Thompson DMSNES sdm; 619800f99ffSJeremy L Thompson 620800f99ffSJeremy L Thompson PetscFunctionBegin; 621800f99ffSJeremy L Thompson PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 622800f99ffSJeremy L Thompson PetscCall(DMGetDMSNESWrite(dm, &sdm)); 623800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetJacobianContext_DMSNES(sdm)); 6243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6256cab3a1bSJed Brown } 6266cab3a1bSJed Brown 6276cab3a1bSJed Brown /*@C 628f6dfbefdSBarry Smith DMSNESGetJacobian - get `SNES` Jacobian evaluation function 6296cab3a1bSJed Brown 6306cab3a1bSJed Brown Not Collective 6316cab3a1bSJed Brown 6324165533cSJose E. Roman Input Parameter: 633f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES` 6346cab3a1bSJed Brown 6354165533cSJose E. Roman Output Parameters: 63620f4b53cSBarry Smith + J - Jacobian evaluation function; for all calling sequence see `SNESJacobianFunction` 6376cab3a1bSJed Brown - ctx - context for residual evaluation 6386cab3a1bSJed Brown 6396cab3a1bSJed Brown Level: advanced 6406cab3a1bSJed Brown 6416cab3a1bSJed Brown Note: 642f6dfbefdSBarry Smith `SNESGetJacobian()` is normally used, but it calls this function internally because the user context is actually 643f6dfbefdSBarry Smith associated with the `DM`. This makes the interface consistent regardless of whether the user interacts with a `DM` or 644f6dfbefdSBarry Smith not. 645f6dfbefdSBarry Smith 646*420bcc1bSBarry Smith Developer Note: 647f6dfbefdSBarry Smith If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian. 6486cab3a1bSJed Brown 649*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `SNESJacobianFunction` 6506cab3a1bSJed Brown @*/ 651d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESGetJacobian(DM dm, PetscErrorCode (**J)(SNES, Vec, Mat, Mat, void *), void **ctx) 652d71ae5a4SJacob Faibussowitsch { 653942e3340SBarry Smith DMSNES sdm; 6546cab3a1bSJed Brown 6556cab3a1bSJed Brown PetscFunctionBegin; 6566cab3a1bSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6579566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 658f8b49ee9SBarry Smith if (J) *J = sdm->ops->computejacobian; 659800f99ffSJeremy L Thompson if (ctx) { 660800f99ffSJeremy L Thompson if (sdm->jacobianctxcontainer) PetscCall(PetscContainerGetPointer(sdm->jacobianctxcontainer, ctx)); 661800f99ffSJeremy L Thompson else *ctx = NULL; 662800f99ffSJeremy L Thompson } 6633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6646cab3a1bSJed Brown } 6656cab3a1bSJed Brown 666e03ab78fSPeter Brune /*@C 667e03ab78fSPeter Brune DMSNESSetPicard - set SNES Picard iteration matrix and RHS evaluation functions. 668e03ab78fSPeter Brune 669e03ab78fSPeter Brune Not Collective 670e03ab78fSPeter Brune 6714165533cSJose E. Roman Input Parameters: 672f6dfbefdSBarry Smith + dm - `DM` to be used with `SNES` 673*420bcc1bSBarry Smith . b - RHS evaluation function; see `SNESFunction` for calling sequence 674*420bcc1bSBarry Smith . J - Picard matrix evaluation function; see `SNESJacobianFunction` for calling sequence 675*420bcc1bSBarry Smith - ctx - context for residual and matrix evaluation 676e03ab78fSPeter Brune 677e03ab78fSPeter Brune Level: advanced 678e03ab78fSPeter Brune 679*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `SNESSetPicard()`, `DMSNESSetFunction()`, `DMSNESSetJacobian()` 680e03ab78fSPeter Brune @*/ 681d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESSetPicard(DM dm, PetscErrorCode (*b)(SNES, Vec, Vec, void *), PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx) 682d71ae5a4SJacob Faibussowitsch { 683942e3340SBarry Smith DMSNES sdm; 684e03ab78fSPeter Brune 685e03ab78fSPeter Brune PetscFunctionBegin; 686e03ab78fSPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6879566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 688f8b49ee9SBarry Smith if (b) sdm->ops->computepfunction = b; 689f8b49ee9SBarry Smith if (J) sdm->ops->computepjacobian = J; 690e03ab78fSPeter Brune if (ctx) sdm->pctx = ctx; 6913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 692e03ab78fSPeter Brune } 693e03ab78fSPeter Brune 6947971a8bfSPeter Brune /*@C 695f6dfbefdSBarry Smith DMSNESGetPicard - get `SNES` Picard iteration evaluation functions 6967971a8bfSPeter Brune 6977971a8bfSPeter Brune Not Collective 6987971a8bfSPeter Brune 6994165533cSJose E. Roman Input Parameter: 700f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES` 7017971a8bfSPeter Brune 7024165533cSJose E. Roman Output Parameters: 703*420bcc1bSBarry Smith + b - RHS evaluation function; see `SNESFunction` for calling sequence 704*420bcc1bSBarry Smith . J - Jacobian evaluation function; see `SNESJacobianFunction` for calling sequence 705*420bcc1bSBarry Smith - ctx - context for residual and matrix evaluation 7067971a8bfSPeter Brune 7077971a8bfSPeter Brune Level: advanced 7087971a8bfSPeter Brune 709*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()` 7107971a8bfSPeter Brune @*/ 711d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESGetPicard(DM dm, PetscErrorCode (**b)(SNES, Vec, Vec, void *), PetscErrorCode (**J)(SNES, Vec, Mat, Mat, void *), void **ctx) 712d71ae5a4SJacob Faibussowitsch { 713942e3340SBarry Smith DMSNES sdm; 7147971a8bfSPeter Brune 7157971a8bfSPeter Brune PetscFunctionBegin; 7167971a8bfSPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7179566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 718f8b49ee9SBarry Smith if (b) *b = sdm->ops->computepfunction; 719f8b49ee9SBarry Smith if (J) *J = sdm->ops->computepjacobian; 7207971a8bfSPeter Brune if (ctx) *ctx = sdm->pctx; 7213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7227971a8bfSPeter Brune } 723