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); 24f4f49eeaSPierre Jolivet PetscValidHeaderSpecific(*kdm, DMSNES_CLASSID, 1); 25f4f49eeaSPierre Jolivet 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)); 31213acdd3SPierre Jolivet PetscTryTypeMethod(*kdm, destroy); 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 { 628434afd1SBarry Smith SNESFunctionFn *func; 639200755eSBarry Smith } funcstruct; 649200755eSBarry Smith struct { 658434afd1SBarry Smith SNESJacobianFn *jac; 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 143420bcc1bSBarry 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 195420bcc1bSBarry 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 228420bcc1bSBarry 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 2515d83a8b1SBarry Smith /*@ 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 265420bcc1bSBarry 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` 2878434afd1SBarry Smith . f - residual evaluation function; see `SNESFunctionFn` for calling sequence 2886cab3a1bSJed Brown - ctx - context for residual evaluation 2896cab3a1bSJed Brown 2909bcc50f1SBarry Smith Level: developer 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 297420bcc1bSBarry 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 3008434afd1SBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `SNESFunctionFn` 3016cab3a1bSJed Brown @*/ 3028434afd1SBarry Smith PetscErrorCode DMSNESSetFunction(DM dm, SNESFunctionFn *f, 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` 328*49abdd8aSBarry Smith - f - residual evaluation context destroy function, see `PetscCtxDestroyFn` for its calling sequence 329800f99ffSJeremy L Thompson 3309bcc50f1SBarry Smith Level: developer 331800f99ffSJeremy L Thompson 332*49abdd8aSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetFunction()`, `SNESSetFunction()`, `PetscCtxDestroyFn` 333800f99ffSJeremy L Thompson @*/ 334*49abdd8aSBarry Smith PetscErrorCode DMSNESSetFunctionContextDestroy(DM dm, PetscCtxDestroyFn *f) 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)); 341*49abdd8aSBarry Smith if (sdm->functionctxcontainer) PetscCall(PetscContainerSetCtxDestroy(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 3579bcc50f1SBarry 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` 3638434afd1SBarry Smith . func - residual evaluation function; see `SNESFunctionFn` for calling sequence 3640b4db180SJacob Faibussowitsch - ctx - optional function context 3650b4db180SJacob Faibussowitsch 3669bcc50f1SBarry Smith Level: developer 367bbc1464cSBarry Smith 3689bcc50f1SBarry Smith Note: 3699bcc50f1SBarry Smith If not provided then the function provided with `SNESSetFunction()` is used 370bbc1464cSBarry Smith 3718434afd1SBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `SNESFunction`, `DMSNESSetFunction()`, `SNESFunctionFn` 372bbc1464cSBarry Smith @*/ 3738434afd1SBarry Smith PetscErrorCode DMSNESSetMFFunction(DM dm, SNESFunctionFn *func, void *ctx) 374d71ae5a4SJacob Faibussowitsch { 375bbc1464cSBarry Smith DMSNES sdm; 376bbc1464cSBarry Smith 377bbc1464cSBarry Smith PetscFunctionBegin; 378bbc1464cSBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3790b4db180SJacob Faibussowitsch if (func || ctx) PetscCall(DMGetDMSNESWrite(dm, &sdm)); 3800b4db180SJacob Faibussowitsch if (func) sdm->ops->computemffunction = func; 381bbc1464cSBarry Smith if (ctx) sdm->mffunctionctx = ctx; 3823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 383bbc1464cSBarry Smith } 384bbc1464cSBarry Smith 385bbc1464cSBarry Smith /*@C 3869bcc50f1SBarry Smith DMSNESGetFunction - get `SNES` residual evaluation function from a `DMSNES` object 3876cab3a1bSJed Brown 3886cab3a1bSJed Brown Not Collective 3896cab3a1bSJed Brown 3904165533cSJose E. Roman Input Parameter: 391f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES` 3926cab3a1bSJed Brown 3934165533cSJose E. Roman Output Parameters: 3948434afd1SBarry Smith + f - residual evaluation function; see `SNESFunctionFn` for calling sequence 3956cab3a1bSJed Brown - ctx - context for residual evaluation 3966cab3a1bSJed Brown 3979bcc50f1SBarry Smith Level: developer 3986cab3a1bSJed Brown 3996cab3a1bSJed Brown Note: 400f6dfbefdSBarry Smith `SNESGetFunction()` is normally used, but it calls this function internally because the user context is actually 401f6dfbefdSBarry Smith associated with the `DM`. 4026cab3a1bSJed Brown 4038434afd1SBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `DMSNESSetFunction()`, `SNESSetFunction()`, `SNESFunctionFn` 4046cab3a1bSJed Brown @*/ 4058434afd1SBarry Smith PetscErrorCode DMSNESGetFunction(DM dm, SNESFunctionFn **f, void **ctx) 406d71ae5a4SJacob Faibussowitsch { 407942e3340SBarry Smith DMSNES sdm; 4086cab3a1bSJed Brown 4096cab3a1bSJed Brown PetscFunctionBegin; 4106cab3a1bSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4119566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 412f8b49ee9SBarry Smith if (f) *f = sdm->ops->computefunction; 413800f99ffSJeremy L Thompson if (ctx) { 414800f99ffSJeremy L Thompson if (sdm->functionctxcontainer) PetscCall(PetscContainerGetPointer(sdm->functionctxcontainer, ctx)); 415800f99ffSJeremy L Thompson else *ctx = NULL; 416800f99ffSJeremy L Thompson } 4173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4186cab3a1bSJed Brown } 4196cab3a1bSJed Brown 4202a4ee8f2SPeter Brune /*@C 421709e13c7SJeremy L Thompson DMSNESSetObjective - Sets the objective function minimized by some of the `SNES` linesearch methods into a `DMSNES` object, used instead of the 2-norm of the residual 4222a4ee8f2SPeter Brune 4232a4ee8f2SPeter Brune Not Collective 4242a4ee8f2SPeter Brune 4254165533cSJose E. Roman Input Parameters: 426f6dfbefdSBarry Smith + dm - `DM` to be used with `SNES` 427709e13c7SJeremy L Thompson . obj - objective evaluation routine; see `SNESObjectiveFn` for the calling sequence 428709e13c7SJeremy L Thompson - ctx - [optional] user-defined context for private data for the objective evaluation routine (may be `NULL`) 4292a4ee8f2SPeter Brune 4309bcc50f1SBarry Smith Level: developer 4312a4ee8f2SPeter Brune 4328434afd1SBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESGetObjective()`, `DMSNESSetFunction()`, `SNESObjectiveFn` 4332a4ee8f2SPeter Brune @*/ 4348434afd1SBarry Smith PetscErrorCode DMSNESSetObjective(DM dm, SNESObjectiveFn *obj, void *ctx) 435d71ae5a4SJacob Faibussowitsch { 436942e3340SBarry Smith DMSNES sdm; 4372a4ee8f2SPeter Brune 4382a4ee8f2SPeter Brune PetscFunctionBegin; 4392a4ee8f2SPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 44048a46eb9SPierre Jolivet if (obj || ctx) PetscCall(DMGetDMSNESWrite(dm, &sdm)); 441f8b49ee9SBarry Smith if (obj) sdm->ops->computeobjective = obj; 4422a4ee8f2SPeter Brune if (ctx) sdm->objectivectx = ctx; 4433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4442a4ee8f2SPeter Brune } 4452a4ee8f2SPeter Brune 4462a4ee8f2SPeter Brune /*@C 447709e13c7SJeremy L Thompson DMSNESGetObjective - Returns the objective function set with `DMSNESSetObjective()` 4482a4ee8f2SPeter Brune 4492a4ee8f2SPeter Brune Not Collective 4502a4ee8f2SPeter Brune 4514165533cSJose E. Roman Input Parameter: 452f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES` 4532a4ee8f2SPeter Brune 4544165533cSJose E. Roman Output Parameters: 455709e13c7SJeremy L Thompson + obj - objective evaluation routine (or `NULL`); see `SNESObjectiveFn` for the calling sequence 456709e13c7SJeremy L Thompson - ctx - the function context (or `NULL`) 4572a4ee8f2SPeter Brune 4589bcc50f1SBarry Smith Level: developer 4592a4ee8f2SPeter Brune 4602a4ee8f2SPeter Brune Note: 461f6dfbefdSBarry Smith `SNESGetFunction()` is normally used, but it calls this function internally because the user context is actually 462f6dfbefdSBarry Smith associated with the `DM`. 4632a4ee8f2SPeter Brune 4648434afd1SBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `DMSNESSetObjective()`, `SNESSetFunction()`, `SNESObjectiveFn` 4652a4ee8f2SPeter Brune @*/ 4668434afd1SBarry Smith PetscErrorCode DMSNESGetObjective(DM dm, SNESObjectiveFn **obj, void **ctx) 467d71ae5a4SJacob Faibussowitsch { 468942e3340SBarry Smith DMSNES sdm; 4692a4ee8f2SPeter Brune 4702a4ee8f2SPeter Brune PetscFunctionBegin; 4712a4ee8f2SPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4729566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 473f8b49ee9SBarry Smith if (obj) *obj = sdm->ops->computeobjective; 4742a4ee8f2SPeter Brune if (ctx) *ctx = sdm->objectivectx; 4753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4762a4ee8f2SPeter Brune } 4772a4ee8f2SPeter Brune 4786cab3a1bSJed Brown /*@C 4799bcc50f1SBarry Smith DMSNESSetNGS - set `SNES` Gauss-Seidel relaxation function into a `DMSNES` object 4806cab3a1bSJed Brown 4816cab3a1bSJed Brown Not Collective 4826cab3a1bSJed Brown 4834165533cSJose E. Roman Input Parameters: 484f6dfbefdSBarry Smith + dm - `DM` to be used with `SNES` 485f6dfbefdSBarry Smith . f - relaxation function, see `SNESGSFunction` 4866cab3a1bSJed Brown - ctx - context for residual evaluation 4876cab3a1bSJed Brown 4889bcc50f1SBarry Smith Level: developer 4896cab3a1bSJed Brown 4906cab3a1bSJed Brown Note: 491f6dfbefdSBarry Smith `SNESSetNGS()` is normally used, but it calls this function internally because the user context is actually 492f6dfbefdSBarry Smith associated with the `DM`. This makes the interface consistent regardless of whether the user interacts with a `DM` or 493f6dfbefdSBarry Smith not. 494f6dfbefdSBarry Smith 495420bcc1bSBarry Smith Developer Note: 496f6dfbefdSBarry Smith If `DM` took a more central role at some later date, this could become the primary method of supplying the smoother 4976cab3a1bSJed Brown 498420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `DMSNESSetFunction()`, `SNESGSFunction` 4996cab3a1bSJed Brown @*/ 500d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESSetNGS(DM dm, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) 501d71ae5a4SJacob Faibussowitsch { 502942e3340SBarry Smith DMSNES sdm; 5036cab3a1bSJed Brown 5046cab3a1bSJed Brown PetscFunctionBegin; 5056cab3a1bSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 50648a46eb9SPierre Jolivet if (f || ctx) PetscCall(DMGetDMSNESWrite(dm, &sdm)); 507be95d8f1SBarry Smith if (f) sdm->ops->computegs = f; 5086cab3a1bSJed Brown if (ctx) sdm->gsctx = ctx; 5093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5106cab3a1bSJed Brown } 5116cab3a1bSJed Brown 5126cab3a1bSJed Brown /*@C 5139bcc50f1SBarry Smith DMSNESGetNGS - get `SNES` Gauss-Seidel relaxation function from a `DMSNES` object 5146cab3a1bSJed Brown 5156cab3a1bSJed Brown Not Collective 5166cab3a1bSJed Brown 5174165533cSJose E. Roman Input Parameter: 518f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES` 5196cab3a1bSJed Brown 5204165533cSJose E. Roman Output Parameters: 52137fdd005SBarry Smith + f - relaxation function which performs Gauss-Seidel sweeps, see `SNESSetNGS()` 5226cab3a1bSJed Brown - ctx - context for residual evaluation 5236cab3a1bSJed Brown 5249bcc50f1SBarry Smith Level: developer 5256cab3a1bSJed Brown 5266cab3a1bSJed Brown Note: 527f6dfbefdSBarry Smith `SNESGetNGS()` is normally used, but it calls this function internally because the user context is actually 528f6dfbefdSBarry Smith associated with the `DM`. 529f6dfbefdSBarry Smith 530420bcc1bSBarry Smith Developer Note: 531f6dfbefdSBarry Smith This makes the interface consistent regardless of whether the user interacts with a `DM` or 532f6dfbefdSBarry Smith not. If `DM` took a more central role at some later date, this could become the primary method of setting the residual. 5336cab3a1bSJed Brown 534420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESGetNGS()`, `DMSNESGetJacobian()`, `DMSNESGetFunction()` 5356cab3a1bSJed Brown @*/ 536d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESGetNGS(DM dm, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) 537d71ae5a4SJacob Faibussowitsch { 538942e3340SBarry Smith DMSNES sdm; 5396cab3a1bSJed Brown 5406cab3a1bSJed Brown PetscFunctionBegin; 5416cab3a1bSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5429566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 543be95d8f1SBarry Smith if (f) *f = sdm->ops->computegs; 5446cab3a1bSJed Brown if (ctx) *ctx = sdm->gsctx; 5453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5466cab3a1bSJed Brown } 5476cab3a1bSJed Brown 5486cab3a1bSJed Brown /*@C 5499bcc50f1SBarry Smith DMSNESSetJacobian - set `SNES` Jacobian evaluation function into a `DMSNES` object 5506cab3a1bSJed Brown 5516cab3a1bSJed Brown Not Collective 5526cab3a1bSJed Brown 5534165533cSJose E. Roman Input Parameters: 554f6dfbefdSBarry Smith + dm - `DM` to be used with `SNES` 5558434afd1SBarry Smith . J - Jacobian evaluation function, see `SNESJacobianFn` 5569bcc50f1SBarry Smith - ctx - context for Jacobian evaluation 5576cab3a1bSJed Brown 5589bcc50f1SBarry Smith Level: developer 5596cab3a1bSJed Brown 5606cab3a1bSJed Brown Note: 561f6dfbefdSBarry Smith `SNESSetJacobian()` is normally used, but it calls this function internally because the user context is actually 562f6dfbefdSBarry Smith associated with the `DM`. 563f6dfbefdSBarry Smith 564420bcc1bSBarry Smith Developer Note: 565f6dfbefdSBarry Smith This makes the interface consistent regardless of whether the user interacts with a `DM` or 566f6dfbefdSBarry Smith not. If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian. 5676cab3a1bSJed Brown 5688434afd1SBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESGetJacobian()`, `SNESSetJacobian()`, `SNESJacobianFn` 5696cab3a1bSJed Brown @*/ 5708434afd1SBarry Smith PetscErrorCode DMSNESSetJacobian(DM dm, SNESJacobianFn *J, void *ctx) 571d71ae5a4SJacob Faibussowitsch { 572942e3340SBarry Smith DMSNES sdm; 5736cab3a1bSJed Brown 5746cab3a1bSJed Brown PetscFunctionBegin; 5756cab3a1bSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 576800f99ffSJeremy L Thompson if (J || ctx) PetscCall(DMGetDMSNESWrite(dm, &sdm)); 577f8b49ee9SBarry Smith if (J) sdm->ops->computejacobian = J; 578800f99ffSJeremy L Thompson if (ctx) { 579800f99ffSJeremy L Thompson PetscContainer ctxcontainer; 580800f99ffSJeremy L Thompson PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)sdm), &ctxcontainer)); 581800f99ffSJeremy L Thompson PetscCall(PetscContainerSetPointer(ctxcontainer, ctx)); 582800f99ffSJeremy L Thompson PetscCall(PetscObjectCompose((PetscObject)sdm, "jacobian ctx", (PetscObject)ctxcontainer)); 583800f99ffSJeremy L Thompson sdm->jacobianctxcontainer = ctxcontainer; 584800f99ffSJeremy L Thompson PetscCall(PetscContainerDestroy(&ctxcontainer)); 585800f99ffSJeremy L Thompson } 5863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 587800f99ffSJeremy L Thompson } 588800f99ffSJeremy L Thompson 589800f99ffSJeremy L Thompson /*@C 5909bcc50f1SBarry Smith DMSNESSetJacobianContextDestroy - set `SNES` Jacobian evaluation context destroy function into a `DMSNES` object 591800f99ffSJeremy L Thompson 592800f99ffSJeremy L Thompson Not Collective 593800f99ffSJeremy L Thompson 594800f99ffSJeremy L Thompson Input Parameters: 5955cb80ecdSBarry Smith + dm - `DM` to be used with `SNES` 596*49abdd8aSBarry Smith - f - Jacobian evaluation context destroy function, see `PetscCtxDestroyFn` for its calling sequence 597800f99ffSJeremy L Thompson 5989bcc50f1SBarry Smith Level: developer 599800f99ffSJeremy L Thompson 600420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetJacobian()` 601800f99ffSJeremy L Thompson @*/ 602*49abdd8aSBarry Smith PetscErrorCode DMSNESSetJacobianContextDestroy(DM dm, PetscCtxDestroyFn *f) 603d71ae5a4SJacob Faibussowitsch { 604800f99ffSJeremy L Thompson DMSNES sdm; 605800f99ffSJeremy L Thompson 606800f99ffSJeremy L Thompson PetscFunctionBegin; 607800f99ffSJeremy L Thompson PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 608800f99ffSJeremy L Thompson PetscCall(DMGetDMSNESWrite(dm, &sdm)); 609*49abdd8aSBarry Smith if (sdm->jacobianctxcontainer) PetscCall(PetscContainerSetCtxDestroy(sdm->jacobianctxcontainer, f)); 6103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 611800f99ffSJeremy L Thompson } 612800f99ffSJeremy L Thompson 613d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESUnsetJacobianContext_Internal(DM dm) 614d71ae5a4SJacob Faibussowitsch { 615800f99ffSJeremy L Thompson DMSNES sdm; 616800f99ffSJeremy L Thompson 617800f99ffSJeremy L Thompson PetscFunctionBegin; 618800f99ffSJeremy L Thompson PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 619800f99ffSJeremy L Thompson PetscCall(DMGetDMSNESWrite(dm, &sdm)); 620800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetJacobianContext_DMSNES(sdm)); 6213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6226cab3a1bSJed Brown } 6236cab3a1bSJed Brown 6246cab3a1bSJed Brown /*@C 6259bcc50f1SBarry Smith DMSNESGetJacobian - get `SNES` Jacobian evaluation function from a `DMSNES` object 6266cab3a1bSJed Brown 6276cab3a1bSJed Brown Not Collective 6286cab3a1bSJed Brown 6294165533cSJose E. Roman Input Parameter: 630f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES` 6316cab3a1bSJed Brown 6324165533cSJose E. Roman Output Parameters: 6338434afd1SBarry Smith + J - Jacobian evaluation function; for all calling sequence see `SNESJacobianFn` 6346cab3a1bSJed Brown - ctx - context for residual evaluation 6356cab3a1bSJed Brown 6369bcc50f1SBarry Smith Level: developer 6376cab3a1bSJed Brown 6386cab3a1bSJed Brown Note: 639f6dfbefdSBarry Smith `SNESGetJacobian()` is normally used, but it calls this function internally because the user context is actually 640f6dfbefdSBarry Smith associated with the `DM`. This makes the interface consistent regardless of whether the user interacts with a `DM` or 641f6dfbefdSBarry Smith not. 642f6dfbefdSBarry Smith 643420bcc1bSBarry Smith Developer Note: 644f6dfbefdSBarry Smith If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian. 6456cab3a1bSJed Brown 6468434afd1SBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `SNESJacobianFn` 6476cab3a1bSJed Brown @*/ 6488434afd1SBarry Smith PetscErrorCode DMSNESGetJacobian(DM dm, SNESJacobianFn **J, void **ctx) 649d71ae5a4SJacob Faibussowitsch { 650942e3340SBarry Smith DMSNES sdm; 6516cab3a1bSJed Brown 6526cab3a1bSJed Brown PetscFunctionBegin; 6536cab3a1bSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6549566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 655f8b49ee9SBarry Smith if (J) *J = sdm->ops->computejacobian; 656800f99ffSJeremy L Thompson if (ctx) { 657800f99ffSJeremy L Thompson if (sdm->jacobianctxcontainer) PetscCall(PetscContainerGetPointer(sdm->jacobianctxcontainer, ctx)); 658800f99ffSJeremy L Thompson else *ctx = NULL; 659800f99ffSJeremy L Thompson } 6603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6616cab3a1bSJed Brown } 6626cab3a1bSJed Brown 663e03ab78fSPeter Brune /*@C 6649bcc50f1SBarry Smith DMSNESSetPicard - set SNES Picard iteration matrix and RHS evaluation functions into a `DMSNES` object 665e03ab78fSPeter Brune 666e03ab78fSPeter Brune Not Collective 667e03ab78fSPeter Brune 6684165533cSJose E. Roman Input Parameters: 669f6dfbefdSBarry Smith + dm - `DM` to be used with `SNES` 6708434afd1SBarry Smith . b - RHS evaluation function; see `SNESFunctionFn` for calling sequence 6718434afd1SBarry Smith . J - Picard matrix evaluation function; see `SNESJacobianFn` for calling sequence 672420bcc1bSBarry Smith - ctx - context for residual and matrix evaluation 673e03ab78fSPeter Brune 6749bcc50f1SBarry Smith Level: developer 675e03ab78fSPeter Brune 6768434afd1SBarry Smith .seealso: [](ch_snes), `DMSNES`, `SNESSetPicard()`, `DMSNESSetFunction()`, `DMSNESSetJacobian()`, `SNESFunctionFn`, `SNESJacobianFn` 677e03ab78fSPeter Brune @*/ 6788434afd1SBarry Smith PetscErrorCode DMSNESSetPicard(DM dm, SNESFunctionFn *b, SNESJacobianFn *J, void *ctx) 679d71ae5a4SJacob Faibussowitsch { 680942e3340SBarry Smith DMSNES sdm; 681e03ab78fSPeter Brune 682e03ab78fSPeter Brune PetscFunctionBegin; 683e03ab78fSPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6849566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 685f8b49ee9SBarry Smith if (b) sdm->ops->computepfunction = b; 686f8b49ee9SBarry Smith if (J) sdm->ops->computepjacobian = J; 687e03ab78fSPeter Brune if (ctx) sdm->pctx = ctx; 6883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 689e03ab78fSPeter Brune } 690e03ab78fSPeter Brune 6917971a8bfSPeter Brune /*@C 6929bcc50f1SBarry Smith DMSNESGetPicard - get `SNES` Picard iteration evaluation functions from a `DMSNES` object 6937971a8bfSPeter Brune 6947971a8bfSPeter Brune Not Collective 6957971a8bfSPeter Brune 6964165533cSJose E. Roman Input Parameter: 697f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES` 6987971a8bfSPeter Brune 6994165533cSJose E. Roman Output Parameters: 7008434afd1SBarry Smith + b - RHS evaluation function; see `SNESFunctionFn` for calling sequence 7018434afd1SBarry Smith . J - Jacobian evaluation function; see `SNESJacobianFn` for calling sequence 702420bcc1bSBarry Smith - ctx - context for residual and matrix evaluation 7037971a8bfSPeter Brune 7049bcc50f1SBarry Smith Level: developer 7057971a8bfSPeter Brune 7068434afd1SBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `SNESFunctionFn`, `SNESJacobianFn` 7077971a8bfSPeter Brune @*/ 7088434afd1SBarry Smith PetscErrorCode DMSNESGetPicard(DM dm, SNESFunctionFn **b, SNESJacobianFn **J, void **ctx) 709d71ae5a4SJacob Faibussowitsch { 710942e3340SBarry Smith DMSNES sdm; 7117971a8bfSPeter Brune 7127971a8bfSPeter Brune PetscFunctionBegin; 7137971a8bfSPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7149566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 715f8b49ee9SBarry Smith if (b) *b = sdm->ops->computepfunction; 716f8b49ee9SBarry Smith if (J) *J = sdm->ops->computepjacobian; 7177971a8bfSPeter Brune if (ctx) *ctx = sdm->pctx; 7183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7197971a8bfSPeter Brune } 720