xref: /petsc/src/snes/utils/dmsnes.c (revision e3c0b8a24a85bc8676c36689a324b9c5a5b53cc5)
1b45d2f2cSJed Brown #include <petsc-private/snesimpl.h>   /*I "petscsnes.h" I*/
2679f678eSPeter Brune #include <petsc-private/dmimpl.h>     /*I "petscdm.h" I*/
36cab3a1bSJed Brown 
46cab3a1bSJed Brown #undef __FUNCT__
598120457SMatthew G Knepley #define __FUNCT__ "SNESDMComputeFunction"
698120457SMatthew G Knepley /*@C
798120457SMatthew G Knepley   SNESDMComputeFunction - This is a universal function evaluation routine that
898120457SMatthew G Knepley   may be used with SNESSetFunction() as long as the user context has a DM
998120457SMatthew G Knepley   as its first record and the user has called DMSetLocalFunction().
1098120457SMatthew G Knepley 
1198120457SMatthew G Knepley   Collective on SNES
1298120457SMatthew G Knepley 
1398120457SMatthew G Knepley   Input Parameters:
1498120457SMatthew G Knepley + snes - the SNES context
1598120457SMatthew G Knepley . X - input vector
1698120457SMatthew G Knepley . F - function vector
1798120457SMatthew G Knepley - ptr - pointer to a structure that must have a DM as its first entry.
1898120457SMatthew G Knepley         This ptr must have been passed into SNESDMComputeFunction() as the context.
1998120457SMatthew G Knepley 
2098120457SMatthew G Knepley   Level: intermediate
2198120457SMatthew G Knepley 
2298120457SMatthew G Knepley .seealso: DMSetLocalFunction(), DMSetLocalJacobian(), SNESSetFunction(), SNESSetJacobian()
2398120457SMatthew G Knepley @*/
2498120457SMatthew G Knepley PetscErrorCode SNESDMComputeFunction(SNES snes, Vec X, Vec F, void *ptr)
2598120457SMatthew G Knepley {
2698120457SMatthew G Knepley   DM               dm = *(DM*) ptr;
2798120457SMatthew G Knepley   PetscErrorCode (*lf)(DM, Vec, Vec, void *);
2898120457SMatthew G Knepley   Vec              localX, localF;
2998120457SMatthew G Knepley   PetscInt         N, n;
3098120457SMatthew G Knepley   PetscErrorCode   ierr;
3198120457SMatthew G Knepley 
3298120457SMatthew G Knepley   PetscFunctionBegin;
3398120457SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3498120457SMatthew G Knepley   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
3598120457SMatthew G Knepley   PetscValidHeaderSpecific(F, VEC_CLASSID, 3);
3698120457SMatthew G Knepley   if (!dm) SETERRQ(((PetscObject)snes)->comm, PETSC_ERR_ARG_WRONGSTATE, "Looks like you called SNESSetFromFuntion(snes,SNESDMComputeFunction,) without the DM context");
3798120457SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 4);
3898120457SMatthew G Knepley 
3998120457SMatthew G Knepley   /* determine whether X = localX */
4098120457SMatthew G Knepley   ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr);
4198120457SMatthew G Knepley   ierr = DMGetLocalVector(dm, &localF);CHKERRQ(ierr);
4298120457SMatthew G Knepley   ierr = VecGetSize(X, &N);CHKERRQ(ierr);
4398120457SMatthew G Knepley   ierr = VecGetSize(localX, &n);CHKERRQ(ierr);
4498120457SMatthew G Knepley 
4598120457SMatthew G Knepley   if (n != N){ /* X != localX */
4698120457SMatthew G Knepley     /* Scatter ghost points to local vector, using the 2-step process
4798120457SMatthew G Knepley         DMGlobalToLocalBegin(), DMGlobalToLocalEnd().
4898120457SMatthew G Knepley     */
4998120457SMatthew G Knepley     ierr = DMGlobalToLocalBegin(dm, X, INSERT_VALUES, localX);CHKERRQ(ierr);
5098120457SMatthew G Knepley     ierr = DMGlobalToLocalEnd(dm, X, INSERT_VALUES, localX);CHKERRQ(ierr);
5198120457SMatthew G Knepley   } else {
5298120457SMatthew G Knepley     ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr);
5398120457SMatthew G Knepley     localX = X;
5498120457SMatthew G Knepley   }
5598120457SMatthew G Knepley   ierr = DMGetLocalFunction(dm, &lf);CHKERRQ(ierr);
5698120457SMatthew G Knepley   ierr = (*lf)(dm, localX, localF, ptr);CHKERRQ(ierr);
5798120457SMatthew G Knepley   if (n != N){
5898120457SMatthew G Knepley     ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr);
5998120457SMatthew G Knepley   }
6098120457SMatthew G Knepley   ierr = DMLocalToGlobalBegin(dm, localF, ADD_VALUES, F);CHKERRQ(ierr);
6198120457SMatthew G Knepley   ierr = DMLocalToGlobalEnd(dm, localF, ADD_VALUES, F);CHKERRQ(ierr);
6298120457SMatthew G Knepley   ierr = DMRestoreLocalVector(dm, &localF);CHKERRQ(ierr);
6398120457SMatthew G Knepley   PetscFunctionReturn(0);
6498120457SMatthew G Knepley }
6598120457SMatthew G Knepley 
6698120457SMatthew G Knepley #undef __FUNCT__
6798120457SMatthew G Knepley #define __FUNCT__ "SNESDMComputeJacobian"
6898120457SMatthew G Knepley /*
6998120457SMatthew G Knepley   SNESDMComputeJacobian - This is a universal Jacobian evaluation routine that
7098120457SMatthew G Knepley   may be used with SNESSetJacobian() as long as the user context has a DM
7198120457SMatthew G Knepley   as its first record and the user has called DMSetLocalJacobian().
7298120457SMatthew G Knepley 
7398120457SMatthew G Knepley   Collective on SNES
7498120457SMatthew G Knepley 
7598120457SMatthew G Knepley   Input Parameters:
7698120457SMatthew G Knepley + snes - the SNES context
7798120457SMatthew G Knepley . X - input vector
7898120457SMatthew G Knepley . J - Jacobian
7998120457SMatthew G Knepley . B - Jacobian used in preconditioner (usally same as J)
8098120457SMatthew G Knepley . flag - indicates if the matrix changed its structure
8198120457SMatthew G Knepley - ptr - pointer to a structure that must have a DM as its first entry.
8298120457SMatthew G Knepley         This ptr must have been passed into SNESDMComputeFunction() as the context.
8398120457SMatthew G Knepley 
8498120457SMatthew G Knepley   Level: intermediate
8598120457SMatthew G Knepley 
8698120457SMatthew G Knepley .seealso: DMSetLocalFunction(), DMSetLocalJacobian(), SNESSetFunction(), SNESSetJacobian()
8798120457SMatthew G Knepley */
8898120457SMatthew G Knepley PetscErrorCode SNESDMComputeJacobian(SNES snes, Vec X, Mat *J, Mat *B, MatStructure *flag, void *ptr)
8998120457SMatthew G Knepley {
9098120457SMatthew G Knepley   DM               dm = *(DM*) ptr;
9198120457SMatthew G Knepley   PetscErrorCode (*lj)(DM, Vec, Mat, Mat, void *);
9298120457SMatthew G Knepley   Vec              localX;
9398120457SMatthew G Knepley   PetscErrorCode   ierr;
9498120457SMatthew G Knepley 
9598120457SMatthew G Knepley   PetscFunctionBegin;
9698120457SMatthew G Knepley   ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr);
9798120457SMatthew G Knepley   ierr = DMGlobalToLocalBegin(dm, X, INSERT_VALUES, localX);CHKERRQ(ierr);
9898120457SMatthew G Knepley   ierr = DMGlobalToLocalEnd(dm, X, INSERT_VALUES, localX);CHKERRQ(ierr);
9998120457SMatthew G Knepley   ierr = DMGetLocalJacobian(dm, &lj);CHKERRQ(ierr);
10098120457SMatthew G Knepley   ierr = (*lj)(dm, localX, *J, *B, ptr);CHKERRQ(ierr);
10198120457SMatthew G Knepley   ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr);
10298120457SMatthew G Knepley   /* Assemble true Jacobian; if it is different */
10398120457SMatthew G Knepley   if (*J != *B) {
10498120457SMatthew G Knepley     ierr  = MatAssemblyBegin(*J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10598120457SMatthew G Knepley     ierr  = MatAssemblyEnd(*J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10698120457SMatthew G Knepley   }
10798120457SMatthew G Knepley   ierr  = MatSetOption(*B, MAT_NEW_NONZERO_LOCATION_ERR, PETSC_TRUE);CHKERRQ(ierr);
10898120457SMatthew G Knepley   *flag = SAME_NONZERO_PATTERN;
10998120457SMatthew G Knepley   PetscFunctionReturn(0);
11098120457SMatthew G Knepley }
11198120457SMatthew G Knepley 
11298120457SMatthew G Knepley #undef __FUNCT__
1136cab3a1bSJed Brown #define __FUNCT__ "PetscContainerDestroy_SNESDM"
1146cab3a1bSJed Brown static PetscErrorCode PetscContainerDestroy_SNESDM(void *ctx)
1156cab3a1bSJed Brown {
1166cab3a1bSJed Brown   PetscErrorCode ierr;
1176cab3a1bSJed Brown   SNESDM sdm = (SNESDM)ctx;
1186cab3a1bSJed Brown 
1196cab3a1bSJed Brown   PetscFunctionBegin;
1206cab3a1bSJed Brown   if (sdm->destroy) {ierr = (*sdm->destroy)(sdm);CHKERRQ(ierr);}
1216cab3a1bSJed Brown   ierr = PetscFree(sdm);CHKERRQ(ierr);
1226cab3a1bSJed Brown   PetscFunctionReturn(0);
1236cab3a1bSJed Brown }
1246cab3a1bSJed Brown 
1256cab3a1bSJed Brown #undef __FUNCT__
1266cab3a1bSJed Brown #define __FUNCT__ "DMCoarsenHook_SNESDM"
1276cab3a1bSJed Brown /* Attaches the SNESDM to the coarse level.
1286cab3a1bSJed Brown  * Under what conditions should we copy versus duplicate?
1296cab3a1bSJed Brown  */
1306cab3a1bSJed Brown static PetscErrorCode DMCoarsenHook_SNESDM(DM dm,DM dmc,void *ctx)
1316cab3a1bSJed Brown {
1326cab3a1bSJed Brown   PetscErrorCode ierr;
1336cab3a1bSJed Brown 
1346cab3a1bSJed Brown   PetscFunctionBegin;
1356cab3a1bSJed Brown   ierr = DMSNESCopyContext(dm,dmc);CHKERRQ(ierr);
1366cab3a1bSJed Brown   PetscFunctionReturn(0);
1376cab3a1bSJed Brown }
1386cab3a1bSJed Brown 
1396cab3a1bSJed Brown #undef __FUNCT__
140caa4e7f2SJed Brown #define __FUNCT__ "DMRestrictHook_SNESDM"
141dfe15315SJed Brown /* This could restrict auxiliary information to the coarse level.
142caa4e7f2SJed Brown  */
143caa4e7f2SJed Brown static PetscErrorCode DMRestrictHook_SNESDM(DM dm,Mat Restrict,Vec rscale,Mat Inject,DM dmc,void *ctx)
144caa4e7f2SJed Brown {
145caa4e7f2SJed Brown 
146caa4e7f2SJed Brown   PetscFunctionBegin;
147caa4e7f2SJed Brown   PetscFunctionReturn(0);
148caa4e7f2SJed Brown }
149caa4e7f2SJed Brown 
150caa4e7f2SJed Brown #undef __FUNCT__
1516cab3a1bSJed Brown #define __FUNCT__ "DMSNESGetContext"
1526cab3a1bSJed Brown /*@C
1536cab3a1bSJed Brown    DMSNESGetContext - get read-only private SNESDM context from a DM
1546cab3a1bSJed Brown 
1556cab3a1bSJed Brown    Not Collective
1566cab3a1bSJed Brown 
1576cab3a1bSJed Brown    Input Argument:
1586cab3a1bSJed Brown .  dm - DM to be used with SNES
1596cab3a1bSJed Brown 
1606cab3a1bSJed Brown    Output Argument:
1616cab3a1bSJed Brown .  snesdm - private SNESDM context
1626cab3a1bSJed Brown 
1636cab3a1bSJed Brown    Level: developer
1646cab3a1bSJed Brown 
1656cab3a1bSJed Brown    Notes:
1666cab3a1bSJed Brown    Use DMSNESGetContextWrite() if write access is needed. The DMSNESSetXXX API should be used wherever possible.
1676cab3a1bSJed Brown 
1686cab3a1bSJed Brown .seealso: DMSNESGetContextWrite()
1696cab3a1bSJed Brown @*/
1706cab3a1bSJed Brown PetscErrorCode DMSNESGetContext(DM dm,SNESDM *snesdm)
1716cab3a1bSJed Brown {
1726cab3a1bSJed Brown   PetscErrorCode ierr;
1736cab3a1bSJed Brown   PetscContainer container;
1746cab3a1bSJed Brown   SNESDM         sdm;
1756cab3a1bSJed Brown 
1766cab3a1bSJed Brown   PetscFunctionBegin;
1776cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1786cab3a1bSJed Brown   ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
1796cab3a1bSJed Brown   if (container) {
1806cab3a1bSJed Brown     ierr = PetscContainerGetPointer(container,(void**)snesdm);CHKERRQ(ierr);
1816cab3a1bSJed Brown   } else {
1826cab3a1bSJed Brown     ierr = PetscInfo(dm,"Creating new SNESDM\n");CHKERRQ(ierr);
1836cab3a1bSJed Brown     ierr = PetscContainerCreate(((PetscObject)dm)->comm,&container);CHKERRQ(ierr);
1846cab3a1bSJed Brown     ierr = PetscNewLog(dm,struct _n_SNESDM,&sdm);CHKERRQ(ierr);
1856cab3a1bSJed Brown     ierr = PetscContainerSetPointer(container,sdm);CHKERRQ(ierr);
1866cab3a1bSJed Brown     ierr = PetscContainerSetUserDestroy(container,PetscContainerDestroy_SNESDM);CHKERRQ(ierr);
1876cab3a1bSJed Brown     ierr = PetscObjectCompose((PetscObject)dm,"SNESDM",(PetscObject)container);CHKERRQ(ierr);
188caa4e7f2SJed Brown     ierr = DMCoarsenHookAdd(dm,DMCoarsenHook_SNESDM,DMRestrictHook_SNESDM,PETSC_NULL);CHKERRQ(ierr);
1896cab3a1bSJed Brown     ierr = PetscContainerGetPointer(container,(void**)snesdm);CHKERRQ(ierr);
1906cab3a1bSJed Brown     ierr = PetscContainerDestroy(&container);CHKERRQ(ierr);
1916cab3a1bSJed Brown   }
1926cab3a1bSJed Brown   PetscFunctionReturn(0);
1936cab3a1bSJed Brown }
1946cab3a1bSJed Brown 
1956cab3a1bSJed Brown #undef __FUNCT__
1966cab3a1bSJed Brown #define __FUNCT__ "DMSNESGetContextWrite"
1976cab3a1bSJed Brown /*@C
1986cab3a1bSJed Brown    DMSNESGetContextWrite - get write access to private SNESDM context from a DM
1996cab3a1bSJed Brown 
2006cab3a1bSJed Brown    Not Collective
2016cab3a1bSJed Brown 
2026cab3a1bSJed Brown    Input Argument:
2036cab3a1bSJed Brown .  dm - DM to be used with SNES
2046cab3a1bSJed Brown 
2056cab3a1bSJed Brown    Output Argument:
2066cab3a1bSJed Brown .  snesdm - private SNESDM context
2076cab3a1bSJed Brown 
2086cab3a1bSJed Brown    Level: developer
2096cab3a1bSJed Brown 
2106cab3a1bSJed Brown .seealso: DMSNESGetContext()
2116cab3a1bSJed Brown @*/
2126cab3a1bSJed Brown PetscErrorCode DMSNESGetContextWrite(DM dm,SNESDM *snesdm)
2136cab3a1bSJed Brown {
2146cab3a1bSJed Brown   PetscErrorCode ierr;
2156cab3a1bSJed Brown   SNESDM         sdm;
2166cab3a1bSJed Brown 
2176cab3a1bSJed Brown   PetscFunctionBegin;
2186cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2196cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
2206cab3a1bSJed Brown   if (!sdm->originaldm) sdm->originaldm = dm;
2216cab3a1bSJed Brown   if (sdm->originaldm != dm) {  /* Copy on write */
2226cab3a1bSJed Brown     PetscContainer container;
2236cab3a1bSJed Brown     SNESDM         oldsdm = sdm;
2246cab3a1bSJed Brown     ierr = PetscInfo(dm,"Copying SNESDM due to write\n");CHKERRQ(ierr);
2256cab3a1bSJed Brown     ierr = PetscContainerCreate(((PetscObject)dm)->comm,&container);CHKERRQ(ierr);
2266cab3a1bSJed Brown     ierr = PetscNewLog(dm,struct _n_SNESDM,&sdm);CHKERRQ(ierr);
2278caf3d72SBarry Smith     ierr = PetscMemcpy(sdm,oldsdm,sizeof(*sdm));CHKERRQ(ierr);
2286cab3a1bSJed Brown     ierr = PetscContainerSetPointer(container,sdm);CHKERRQ(ierr);
2296cab3a1bSJed Brown     ierr = PetscContainerSetUserDestroy(container,PetscContainerDestroy_SNESDM);CHKERRQ(ierr);
2306cab3a1bSJed Brown     ierr = PetscObjectCompose((PetscObject)dm,"SNESDM",(PetscObject)container);CHKERRQ(ierr);
2316cab3a1bSJed Brown     ierr = PetscContainerDestroy(&container);CHKERRQ(ierr);
232*e3c0b8a2SPeter Brune     /* implementation specific copy hooks */
233*e3c0b8a2SPeter Brune     ierr = (sdm->duplicate)(oldsdm,dm);CHKERRQ(ierr);
2346cab3a1bSJed Brown   }
2356cab3a1bSJed Brown   *snesdm = sdm;
2366cab3a1bSJed Brown   PetscFunctionReturn(0);
2376cab3a1bSJed Brown }
2386cab3a1bSJed Brown 
2396cab3a1bSJed Brown #undef __FUNCT__
2406cab3a1bSJed Brown #define __FUNCT__ "DMSNESCopyContext"
2416cab3a1bSJed Brown /*@C
2426cab3a1bSJed Brown    DMSNESCopyContext - copies a DM context to a new DM
2436cab3a1bSJed Brown 
2446cab3a1bSJed Brown    Logically Collective
2456cab3a1bSJed Brown 
2466cab3a1bSJed Brown    Input Arguments:
2476cab3a1bSJed Brown +  dmsrc - DM to obtain context from
2486cab3a1bSJed Brown -  dmdest - DM to add context to
2496cab3a1bSJed Brown 
2506cab3a1bSJed Brown    Level: developer
2516cab3a1bSJed Brown 
2526cab3a1bSJed Brown    Note:
2536cab3a1bSJed Brown    The context is copied by reference. This function does not ensure that a context exists.
2546cab3a1bSJed Brown 
2556cab3a1bSJed Brown .seealso: DMSNESGetContext(), SNESSetDM()
2566cab3a1bSJed Brown @*/
2576cab3a1bSJed Brown PetscErrorCode DMSNESCopyContext(DM dmsrc,DM dmdest)
2586cab3a1bSJed Brown {
2596cab3a1bSJed Brown   PetscErrorCode ierr;
2606cab3a1bSJed Brown   PetscContainer container;
2616cab3a1bSJed Brown 
2626cab3a1bSJed Brown   PetscFunctionBegin;
2636cab3a1bSJed Brown   PetscValidHeaderSpecific(dmsrc,DM_CLASSID,1);
2646cab3a1bSJed Brown   PetscValidHeaderSpecific(dmdest,DM_CLASSID,2);
2656cab3a1bSJed Brown   ierr = PetscObjectQuery((PetscObject)dmsrc,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
2666cab3a1bSJed Brown   if (container) {
2676cab3a1bSJed Brown     ierr = PetscObjectCompose((PetscObject)dmdest,"SNESDM",(PetscObject)container);CHKERRQ(ierr);
268caa4e7f2SJed Brown     ierr = DMCoarsenHookAdd(dmdest,DMCoarsenHook_SNESDM,DMRestrictHook_SNESDM,PETSC_NULL);CHKERRQ(ierr);
2696cab3a1bSJed Brown   }
2706cab3a1bSJed Brown   PetscFunctionReturn(0);
2716cab3a1bSJed Brown }
2726cab3a1bSJed Brown 
2736cab3a1bSJed Brown #undef __FUNCT__
2746cab3a1bSJed Brown #define __FUNCT__ "DMSNESSetFunction"
2756cab3a1bSJed Brown /*@C
2766cab3a1bSJed Brown    DMSNESSetFunction - set SNES residual evaluation function
2776cab3a1bSJed Brown 
2786cab3a1bSJed Brown    Not Collective
2796cab3a1bSJed Brown 
2806cab3a1bSJed Brown    Input Arguments:
2816cab3a1bSJed Brown +  dm - DM to be used with SNES
2826cab3a1bSJed Brown .  func - residual evaluation function, see SNESSetFunction() for calling sequence
2836cab3a1bSJed Brown -  ctx - context for residual evaluation
2846cab3a1bSJed Brown 
2856cab3a1bSJed Brown    Level: advanced
2866cab3a1bSJed Brown 
2876cab3a1bSJed Brown    Note:
2886cab3a1bSJed Brown    SNESSetFunction() is normally used, but it calls this function internally because the user context is actually
2896cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
2906cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
2916cab3a1bSJed Brown 
2926cab3a1bSJed Brown .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian()
2936cab3a1bSJed Brown @*/
2946cab3a1bSJed Brown PetscErrorCode DMSNESSetFunction(DM dm,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
2956cab3a1bSJed Brown {
2966cab3a1bSJed Brown   PetscErrorCode ierr;
2976cab3a1bSJed Brown   SNESDM sdm;
2986cab3a1bSJed Brown 
2996cab3a1bSJed Brown   PetscFunctionBegin;
3006cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3016cab3a1bSJed Brown   ierr = DMSNESGetContextWrite(dm,&sdm);CHKERRQ(ierr);
3026cab3a1bSJed Brown   if (func) sdm->computefunction = func;
3036cab3a1bSJed Brown   if (ctx)  sdm->functionctx = ctx;
3046cab3a1bSJed Brown   PetscFunctionReturn(0);
3056cab3a1bSJed Brown }
3066cab3a1bSJed Brown 
3076cab3a1bSJed Brown #undef __FUNCT__
3086cab3a1bSJed Brown #define __FUNCT__ "DMSNESGetFunction"
3096cab3a1bSJed Brown /*@C
3106cab3a1bSJed Brown    DMSNESGetFunction - get SNES residual evaluation function
3116cab3a1bSJed Brown 
3126cab3a1bSJed Brown    Not Collective
3136cab3a1bSJed Brown 
3146cab3a1bSJed Brown    Input Argument:
3156cab3a1bSJed Brown .  dm - DM to be used with SNES
3166cab3a1bSJed Brown 
3176cab3a1bSJed Brown    Output Arguments:
3186cab3a1bSJed Brown +  func - residual evaluation function, see SNESSetFunction() for calling sequence
3196cab3a1bSJed Brown -  ctx - context for residual evaluation
3206cab3a1bSJed Brown 
3216cab3a1bSJed Brown    Level: advanced
3226cab3a1bSJed Brown 
3236cab3a1bSJed Brown    Note:
3246cab3a1bSJed Brown    SNESGetFunction() is normally used, but it calls this function internally because the user context is actually
3256cab3a1bSJed Brown    associated with the DM.
3266cab3a1bSJed Brown 
3276cab3a1bSJed Brown .seealso: DMSNESSetContext(), DMSNESSetFunction(), SNESSetFunction()
3286cab3a1bSJed Brown @*/
3296cab3a1bSJed Brown PetscErrorCode DMSNESGetFunction(DM dm,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
3306cab3a1bSJed Brown {
3316cab3a1bSJed Brown   PetscErrorCode ierr;
3326cab3a1bSJed Brown   SNESDM sdm;
3336cab3a1bSJed Brown 
3346cab3a1bSJed Brown   PetscFunctionBegin;
3356cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3366cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
3376cab3a1bSJed Brown   if (func) *func = sdm->computefunction;
3386cab3a1bSJed Brown   if (ctx)  *ctx = sdm->functionctx;
3396cab3a1bSJed Brown   PetscFunctionReturn(0);
3406cab3a1bSJed Brown }
3416cab3a1bSJed Brown 
3426cab3a1bSJed Brown #undef __FUNCT__
3436cab3a1bSJed Brown #define __FUNCT__ "DMSNESSetGS"
3446cab3a1bSJed Brown /*@C
3456cab3a1bSJed Brown    DMSNESSetGS - set SNES Gauss-Seidel relaxation function
3466cab3a1bSJed Brown 
3476cab3a1bSJed Brown    Not Collective
3486cab3a1bSJed Brown 
3496cab3a1bSJed Brown    Input Argument:
3506cab3a1bSJed Brown +  dm - DM to be used with SNES
3516cab3a1bSJed Brown .  func - relaxation function, see SNESSetGS() for calling sequence
3526cab3a1bSJed Brown -  ctx - context for residual evaluation
3536cab3a1bSJed Brown 
3546cab3a1bSJed Brown    Level: advanced
3556cab3a1bSJed Brown 
3566cab3a1bSJed Brown    Note:
3576cab3a1bSJed Brown    SNESSetGS() is normally used, but it calls this function internally because the user context is actually
3586cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
3596cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
3606cab3a1bSJed Brown 
3616cab3a1bSJed Brown .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian(), DMSNESSetFunction()
3626cab3a1bSJed Brown @*/
3636cab3a1bSJed Brown PetscErrorCode DMSNESSetGS(DM dm,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
3646cab3a1bSJed Brown {
3656cab3a1bSJed Brown   PetscErrorCode ierr;
3666cab3a1bSJed Brown   SNESDM sdm;
3676cab3a1bSJed Brown 
3686cab3a1bSJed Brown   PetscFunctionBegin;
3696cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3706cab3a1bSJed Brown   ierr = DMSNESGetContextWrite(dm,&sdm);CHKERRQ(ierr);
3716cab3a1bSJed Brown   if (func) sdm->computegs = func;
3726cab3a1bSJed Brown   if (ctx)  sdm->gsctx = ctx;
3736cab3a1bSJed Brown   PetscFunctionReturn(0);
3746cab3a1bSJed Brown }
3756cab3a1bSJed Brown 
3766cab3a1bSJed Brown #undef __FUNCT__
3776cab3a1bSJed Brown #define __FUNCT__ "DMSNESGetGS"
3786cab3a1bSJed Brown /*@C
3796cab3a1bSJed Brown    DMSNESGetGS - get SNES Gauss-Seidel relaxation function
3806cab3a1bSJed Brown 
3816cab3a1bSJed Brown    Not Collective
3826cab3a1bSJed Brown 
3836cab3a1bSJed Brown    Input Argument:
3846cab3a1bSJed Brown .  dm - DM to be used with SNES
3856cab3a1bSJed Brown 
3866cab3a1bSJed Brown    Output Arguments:
3876cab3a1bSJed Brown +  func - relaxation function, see SNESSetGS() for calling sequence
3886cab3a1bSJed Brown -  ctx - context for residual evaluation
3896cab3a1bSJed Brown 
3906cab3a1bSJed Brown    Level: advanced
3916cab3a1bSJed Brown 
3926cab3a1bSJed Brown    Note:
3936cab3a1bSJed Brown    SNESGetGS() is normally used, but it calls this function internally because the user context is actually
3946cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
3956cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
3966cab3a1bSJed Brown 
3976cab3a1bSJed Brown .seealso: DMSNESSetContext(), SNESGetGS(), DMSNESGetJacobian(), DMSNESGetFunction()
3986cab3a1bSJed Brown @*/
3996cab3a1bSJed Brown PetscErrorCode DMSNESGetGS(DM dm,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
4006cab3a1bSJed Brown {
4016cab3a1bSJed Brown   PetscErrorCode ierr;
4026cab3a1bSJed Brown   SNESDM sdm;
4036cab3a1bSJed Brown 
4046cab3a1bSJed Brown   PetscFunctionBegin;
4056cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4066cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
4076cab3a1bSJed Brown   if (func) *func = sdm->computegs;
4086cab3a1bSJed Brown   if (ctx)  *ctx = sdm->gsctx;
4096cab3a1bSJed Brown   PetscFunctionReturn(0);
4106cab3a1bSJed Brown }
4116cab3a1bSJed Brown 
4126cab3a1bSJed Brown #undef __FUNCT__
4136cab3a1bSJed Brown #define __FUNCT__ "DMSNESSetJacobian"
4146cab3a1bSJed Brown /*@C
415ecfdb398SPeter Brune    DMSNESSetJacobian - set SNES Jacobian evaluation function
4166cab3a1bSJed Brown 
4176cab3a1bSJed Brown    Not Collective
4186cab3a1bSJed Brown 
4196cab3a1bSJed Brown    Input Argument:
4206cab3a1bSJed Brown +  dm - DM to be used with SNES
4216cab3a1bSJed Brown .  func - Jacobian evaluation function, see SNESSetJacobian() for calling sequence
4226cab3a1bSJed Brown -  ctx - context for residual evaluation
4236cab3a1bSJed Brown 
4246cab3a1bSJed Brown    Level: advanced
4256cab3a1bSJed Brown 
4266cab3a1bSJed Brown    Note:
4276cab3a1bSJed Brown    SNESSetJacobian() is normally used, but it calls this function internally because the user context is actually
4286cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
4296cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
4306cab3a1bSJed Brown 
4316cab3a1bSJed Brown .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESGetJacobian(), SNESSetJacobian()
4326cab3a1bSJed Brown @*/
4336cab3a1bSJed Brown PetscErrorCode DMSNESSetJacobian(DM dm,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
4346cab3a1bSJed Brown {
4356cab3a1bSJed Brown   PetscErrorCode ierr;
4366cab3a1bSJed Brown   SNESDM sdm;
4376cab3a1bSJed Brown 
4386cab3a1bSJed Brown   PetscFunctionBegin;
4396cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4406cab3a1bSJed Brown   ierr = DMSNESGetContextWrite(dm,&sdm);CHKERRQ(ierr);
4416cab3a1bSJed Brown   if (func) sdm->computejacobian = func;
4426cab3a1bSJed Brown   if (ctx)  sdm->jacobianctx = ctx;
4436cab3a1bSJed Brown   PetscFunctionReturn(0);
4446cab3a1bSJed Brown }
4456cab3a1bSJed Brown 
4466cab3a1bSJed Brown #undef __FUNCT__
4476cab3a1bSJed Brown #define __FUNCT__ "DMSNESGetJacobian"
4486cab3a1bSJed Brown /*@C
449ecfdb398SPeter Brune    DMSNESGetJacobian - get SNES Jacobian evaluation function
4506cab3a1bSJed Brown 
4516cab3a1bSJed Brown    Not Collective
4526cab3a1bSJed Brown 
4536cab3a1bSJed Brown    Input Argument:
4546cab3a1bSJed Brown .  dm - DM to be used with SNES
4556cab3a1bSJed Brown 
4566cab3a1bSJed Brown    Output Arguments:
4576cab3a1bSJed Brown +  func - Jacobian evaluation function, see SNESSetJacobian() for calling sequence
4586cab3a1bSJed Brown -  ctx - context for residual evaluation
4596cab3a1bSJed Brown 
4606cab3a1bSJed Brown    Level: advanced
4616cab3a1bSJed Brown 
4626cab3a1bSJed Brown    Note:
4636cab3a1bSJed Brown    SNESGetJacobian() is normally used, but it calls this function internally because the user context is actually
4646cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
4656cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
4666cab3a1bSJed Brown 
4676cab3a1bSJed Brown .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian()
4686cab3a1bSJed Brown @*/
4696cab3a1bSJed Brown PetscErrorCode DMSNESGetJacobian(DM dm,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
4706cab3a1bSJed Brown {
4716cab3a1bSJed Brown   PetscErrorCode ierr;
4726cab3a1bSJed Brown   SNESDM sdm;
4736cab3a1bSJed Brown 
4746cab3a1bSJed Brown   PetscFunctionBegin;
4756cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4766cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
4776cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
4786cab3a1bSJed Brown   if (ctx)  *ctx = sdm->jacobianctx;
4796cab3a1bSJed Brown   PetscFunctionReturn(0);
4806cab3a1bSJed Brown }
4816cab3a1bSJed Brown 
4826cab3a1bSJed Brown #undef __FUNCT__
483e03ab78fSPeter Brune #define __FUNCT__ "DMSNESSetPicard"
484e03ab78fSPeter Brune /*@C
485e03ab78fSPeter Brune    DMSNESSetPicard - set SNES Picard iteration matrix and RHS evaluation functions.
486e03ab78fSPeter Brune 
487e03ab78fSPeter Brune    Not Collective
488e03ab78fSPeter Brune 
489e03ab78fSPeter Brune    Input Argument:
490e03ab78fSPeter Brune +  dm - DM to be used with SNES
491e03ab78fSPeter Brune .  func - RHS evaluation function, see SNESSetFunction() for calling sequence
492e03ab78fSPeter Brune .  pjac - Picard matrix evaluation function, see SNESSetJacobian() for calling sequence
493e03ab78fSPeter Brune -  ctx - context for residual evaluation
494e03ab78fSPeter Brune 
495e03ab78fSPeter Brune    Level: advanced
496e03ab78fSPeter Brune 
497e03ab78fSPeter Brune .seealso: SNESSetPicard(), DMSNESSetFunction(), DMSNESSetJacobian()
498e03ab78fSPeter Brune @*/
499e03ab78fSPeter Brune PetscErrorCode DMSNESSetPicard(DM dm,PetscErrorCode (*pfunc)(SNES,Vec,Vec,void*),PetscErrorCode (*pjac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
500e03ab78fSPeter Brune {
501e03ab78fSPeter Brune   PetscErrorCode ierr;
502e03ab78fSPeter Brune   SNESDM sdm;
503e03ab78fSPeter Brune 
504e03ab78fSPeter Brune   PetscFunctionBegin;
505e03ab78fSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
506e03ab78fSPeter Brune   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
507e03ab78fSPeter Brune   if (pfunc) sdm->computepfunction = pfunc;
508e03ab78fSPeter Brune   if (pjac)  sdm->computepjacobian = pjac;
509e03ab78fSPeter Brune   if (ctx)   sdm->pctx             = ctx;
510e03ab78fSPeter Brune   PetscFunctionReturn(0);
511e03ab78fSPeter Brune }
512e03ab78fSPeter Brune 
5137971a8bfSPeter Brune 
5147971a8bfSPeter Brune #undef __FUNCT__
5157971a8bfSPeter Brune #define __FUNCT__ "DMSNESGetPicard"
5167971a8bfSPeter Brune /*@C
5177971a8bfSPeter Brune    DMSNESGetPicard - get SNES Picard iteration evaluation functions
5187971a8bfSPeter Brune 
5197971a8bfSPeter Brune    Not Collective
5207971a8bfSPeter Brune 
5217971a8bfSPeter Brune    Input Argument:
5227971a8bfSPeter Brune .  dm - DM to be used with SNES
5237971a8bfSPeter Brune 
5247971a8bfSPeter Brune    Output Arguments:
5257971a8bfSPeter Brune +  pfunc - Jacobian evaluation function, see SNESSetJacobian() for calling sequence
5267971a8bfSPeter Brune .  pjac  - RHS evaluation function, see SNESSetFunction() for calling sequence
5277971a8bfSPeter Brune -  ctx - context for residual evaluation
5287971a8bfSPeter Brune 
5297971a8bfSPeter Brune    Level: advanced
5307971a8bfSPeter Brune 
5317971a8bfSPeter Brune .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian()
5327971a8bfSPeter Brune @*/
5337971a8bfSPeter Brune PetscErrorCode DMSNESGetPicard(DM dm,PetscErrorCode (**pfunc)(SNES,Vec,Vec,void*),PetscErrorCode (**pjac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
5347971a8bfSPeter Brune {
5357971a8bfSPeter Brune   PetscErrorCode ierr;
5367971a8bfSPeter Brune   SNESDM sdm;
5377971a8bfSPeter Brune 
5387971a8bfSPeter Brune   PetscFunctionBegin;
5397971a8bfSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5407971a8bfSPeter Brune   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
5417971a8bfSPeter Brune   if (pfunc) *pfunc = sdm->computepfunction;
5427971a8bfSPeter Brune   if (pjac) *pjac   = sdm->computepjacobian;
5437971a8bfSPeter Brune   if (ctx)  *ctx    = sdm->pctx;
5447971a8bfSPeter Brune   PetscFunctionReturn(0);
5457971a8bfSPeter Brune }
5467971a8bfSPeter Brune 
5477971a8bfSPeter Brune 
548e03ab78fSPeter Brune #undef __FUNCT__
5496cab3a1bSJed Brown #define __FUNCT__ "SNESDefaultComputeFunction_DMLegacy"
5506cab3a1bSJed Brown static PetscErrorCode SNESDefaultComputeFunction_DMLegacy(SNES snes,Vec X,Vec F,void *ctx)
5516cab3a1bSJed Brown {
5526cab3a1bSJed Brown   PetscErrorCode ierr;
5536cab3a1bSJed Brown   DM             dm;
5546cab3a1bSJed Brown 
5556cab3a1bSJed Brown   PetscFunctionBegin;
5566cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
5576cab3a1bSJed Brown   ierr = DMComputeFunction(dm,X,F);CHKERRQ(ierr);
5586cab3a1bSJed Brown   PetscFunctionReturn(0);
5596cab3a1bSJed Brown }
5606cab3a1bSJed Brown 
5616cab3a1bSJed Brown #undef __FUNCT__
5626cab3a1bSJed Brown #define __FUNCT__ "SNESDefaultComputeJacobian_DMLegacy"
5636cab3a1bSJed Brown static PetscErrorCode SNESDefaultComputeJacobian_DMLegacy(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *mstr,void *ctx)
5646cab3a1bSJed Brown {
5656cab3a1bSJed Brown   PetscErrorCode ierr;
5666cab3a1bSJed Brown   DM             dm;
5676cab3a1bSJed Brown 
5686cab3a1bSJed Brown   PetscFunctionBegin;
5696cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
5706cab3a1bSJed Brown   ierr = DMComputeJacobian(dm,X,*A,*B,mstr);CHKERRQ(ierr);
5716cab3a1bSJed Brown   PetscFunctionReturn(0);
5726cab3a1bSJed Brown }
5736cab3a1bSJed Brown 
5746cab3a1bSJed Brown #undef __FUNCT__
5756cab3a1bSJed Brown #define __FUNCT__ "DMSNESSetUpLegacy"
5766cab3a1bSJed Brown /* Sets up calling of legacy DM routines */
5776cab3a1bSJed Brown PetscErrorCode DMSNESSetUpLegacy(DM dm)
5786cab3a1bSJed Brown {
5796cab3a1bSJed Brown   PetscErrorCode ierr;
5806cab3a1bSJed Brown   SNESDM         sdm;
5816cab3a1bSJed Brown 
5826cab3a1bSJed Brown   PetscFunctionBegin;
5836cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
5846cab3a1bSJed Brown   if (!sdm->computefunction) {ierr = DMSNESSetFunction(dm,SNESDefaultComputeFunction_DMLegacy,PETSC_NULL);CHKERRQ(ierr);}
5856cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
586679f678eSPeter Brune   if (!sdm->computejacobian) {
587679f678eSPeter Brune     if (dm->ops->functionj) {
588679f678eSPeter Brune       ierr = DMSNESSetJacobian(dm,SNESDefaultComputeJacobian_DMLegacy,PETSC_NULL);CHKERRQ(ierr);
589679f678eSPeter Brune     } else {
590679f678eSPeter Brune       ierr = DMSNESSetJacobian(dm,SNESDefaultComputeJacobianColor,PETSC_NULL);CHKERRQ(ierr);
591679f678eSPeter Brune     }
592679f678eSPeter Brune   }
5936cab3a1bSJed Brown   PetscFunctionReturn(0);
5946cab3a1bSJed Brown }
5956427ad5bSPeter Brune 
5966427ad5bSPeter Brune /* block functions */
5976427ad5bSPeter Brune 
5986427ad5bSPeter Brune #undef __FUNCT__
5996427ad5bSPeter Brune #define __FUNCT__ "DMSNESSetBlockFunction"
6006427ad5bSPeter Brune /*@C
6016427ad5bSPeter Brune    DMSNESSetBlockFunction - set SNES residual evaluation function
6026427ad5bSPeter Brune 
6036427ad5bSPeter Brune    Not Collective
6046427ad5bSPeter Brune 
6056427ad5bSPeter Brune    Input Arguments:
6066427ad5bSPeter Brune +  dm - DM to be used with SNES
6076427ad5bSPeter Brune .  func - residual evaluation function, see SNESSetFunction() for calling sequence
6086427ad5bSPeter Brune -  ctx - context for residual evaluation
6096427ad5bSPeter Brune 
6106427ad5bSPeter Brune    Level: developer
6116427ad5bSPeter Brune 
6126427ad5bSPeter Brune    Note:
6136427ad5bSPeter Brune    Mostly for use in DM implementations and transferred to a block function rather than being called from here.
6146427ad5bSPeter Brune 
6156427ad5bSPeter Brune .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian()
6166427ad5bSPeter Brune @*/
6176427ad5bSPeter Brune PetscErrorCode DMSNESSetBlockFunction(DM dm,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
6186427ad5bSPeter Brune {
6196427ad5bSPeter Brune   PetscErrorCode ierr;
6206427ad5bSPeter Brune   SNESDM sdm;
6216427ad5bSPeter Brune 
6226427ad5bSPeter Brune   PetscFunctionBegin;
6236427ad5bSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6246427ad5bSPeter Brune   ierr = DMSNESGetContextWrite(dm,&sdm);CHKERRQ(ierr);
6256427ad5bSPeter Brune   if (func) sdm->computeblockfunction = func;
6266427ad5bSPeter Brune   if (ctx)  sdm->blockfunctionctx = ctx;
6276427ad5bSPeter Brune   PetscFunctionReturn(0);
6286427ad5bSPeter Brune }
6296427ad5bSPeter Brune 
6306427ad5bSPeter Brune #undef __FUNCT__
6316427ad5bSPeter Brune #define __FUNCT__ "DMSNESGetBlockFunction"
6326427ad5bSPeter Brune /*@C
6336427ad5bSPeter Brune    DMSNESGetBlockFunction - get SNES residual evaluation function
6346427ad5bSPeter Brune 
6356427ad5bSPeter Brune    Not Collective
6366427ad5bSPeter Brune 
6376427ad5bSPeter Brune    Input Argument:
6386427ad5bSPeter Brune .  dm - DM to be used with SNES
6396427ad5bSPeter Brune 
6406427ad5bSPeter Brune    Output Arguments:
6416427ad5bSPeter Brune +  func - residual evaluation function, see SNESSetFunction() for calling sequence
6426427ad5bSPeter Brune -  ctx - context for residual evaluation
6436427ad5bSPeter Brune 
6446427ad5bSPeter Brune    Level: developer
6456427ad5bSPeter Brune 
6466427ad5bSPeter Brune .seealso: DMSNESSetContext(), DMSNESSetFunction(), SNESSetFunction()
6476427ad5bSPeter Brune @*/
6486427ad5bSPeter Brune PetscErrorCode DMSNESGetBlockFunction(DM dm,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
6496427ad5bSPeter Brune {
6506427ad5bSPeter Brune   PetscErrorCode ierr;
6516427ad5bSPeter Brune   SNESDM sdm;
6526427ad5bSPeter Brune 
6536427ad5bSPeter Brune   PetscFunctionBegin;
6546427ad5bSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6556427ad5bSPeter Brune   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
6566427ad5bSPeter Brune   if (func) *func = sdm->computeblockfunction;
6576427ad5bSPeter Brune   if (ctx)  *ctx = sdm->blockfunctionctx;
6586427ad5bSPeter Brune   PetscFunctionReturn(0);
6596427ad5bSPeter Brune }
6606427ad5bSPeter Brune 
6616427ad5bSPeter Brune 
6626427ad5bSPeter Brune #undef __FUNCT__
6636427ad5bSPeter Brune #define __FUNCT__ "DMSNESSetBlockJacobian"
6646427ad5bSPeter Brune /*@C
6656427ad5bSPeter Brune    DMSNESSetJacobian - set SNES Jacobian evaluation function
6666427ad5bSPeter Brune 
6676427ad5bSPeter Brune    Not Collective
6686427ad5bSPeter Brune 
6696427ad5bSPeter Brune    Input Argument:
6706427ad5bSPeter Brune +  dm - DM to be used with SNES
6716427ad5bSPeter Brune .  func - Jacobian evaluation function, see SNESSetJacobian() for calling sequence
6726427ad5bSPeter Brune -  ctx - context for residual evaluation
6736427ad5bSPeter Brune 
6746427ad5bSPeter Brune    Level: advanced
6756427ad5bSPeter Brune 
6766427ad5bSPeter Brune    Note:
6776427ad5bSPeter Brune    Mostly for use in DM implementations and transferred to a block function rather than being called from here.
6786427ad5bSPeter Brune 
6796427ad5bSPeter Brune .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESGetJacobian(), SNESSetJacobian()
6806427ad5bSPeter Brune @*/
6816427ad5bSPeter Brune PetscErrorCode DMSNESSetBlockJacobian(DM dm,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
6826427ad5bSPeter Brune {
6836427ad5bSPeter Brune   PetscErrorCode ierr;
6846427ad5bSPeter Brune   SNESDM sdm;
6856427ad5bSPeter Brune 
6866427ad5bSPeter Brune   PetscFunctionBegin;
6876427ad5bSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6886427ad5bSPeter Brune   ierr = DMSNESGetContextWrite(dm,&sdm);CHKERRQ(ierr);
6896427ad5bSPeter Brune   if (func) sdm->computeblockjacobian = func;
6906427ad5bSPeter Brune   if (ctx)  sdm->blockjacobianctx = ctx;
6916427ad5bSPeter Brune   PetscFunctionReturn(0);
6926427ad5bSPeter Brune }
6936427ad5bSPeter Brune 
6946427ad5bSPeter Brune #undef __FUNCT__
6956427ad5bSPeter Brune #define __FUNCT__ "DMSNESGetBlockJacobian"
6966427ad5bSPeter Brune /*@C
6976427ad5bSPeter Brune    DMSNESGetBlockJacobian - get SNES Jacobian evaluation function
6986427ad5bSPeter Brune 
6996427ad5bSPeter Brune    Not Collective
7006427ad5bSPeter Brune 
7016427ad5bSPeter Brune    Input Argument:
7026427ad5bSPeter Brune .  dm - DM to be used with SNES
7036427ad5bSPeter Brune 
7046427ad5bSPeter Brune    Output Arguments:
7056427ad5bSPeter Brune +  func - Jacobian evaluation function, see SNESSetJacobian() for calling sequence
7066427ad5bSPeter Brune -  ctx - context for residual evaluation
7076427ad5bSPeter Brune 
7086427ad5bSPeter Brune    Level: advanced
7096427ad5bSPeter Brune 
7106427ad5bSPeter Brune .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian()
7116427ad5bSPeter Brune @*/
7126427ad5bSPeter Brune PetscErrorCode DMSNESGetBlockJacobian(DM dm,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
7136427ad5bSPeter Brune {
7146427ad5bSPeter Brune   PetscErrorCode ierr;
7156427ad5bSPeter Brune   SNESDM sdm;
7166427ad5bSPeter Brune 
7176427ad5bSPeter Brune   PetscFunctionBegin;
7186427ad5bSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7196427ad5bSPeter Brune   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
7206427ad5bSPeter Brune   if (func) *func = sdm->computeblockjacobian;
7216427ad5bSPeter Brune   if (ctx)  *ctx = sdm->blockjacobianctx;
7226427ad5bSPeter Brune   PetscFunctionReturn(0);
7236427ad5bSPeter Brune }
724