xref: /petsc/src/snes/utils/dmsnes.c (revision 03a0fabf4bd3dfd189b0d5f539b470107c938ba0)
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__
151*03a0fabfSPeter Brune #define __FUNCT__ "DMRefineHook_SNESDM"
152*03a0fabfSPeter Brune static PetscErrorCode DMRefineHook_SNESDM(DM dm,DM dmf,void *ctx)
153*03a0fabfSPeter Brune {
154*03a0fabfSPeter Brune   PetscErrorCode ierr;
155*03a0fabfSPeter Brune 
156*03a0fabfSPeter Brune   PetscFunctionBegin;
157*03a0fabfSPeter Brune   ierr = DMSNESCopyContext(dm,dmf);CHKERRQ(ierr);
158*03a0fabfSPeter Brune   PetscFunctionReturn(0);
159*03a0fabfSPeter Brune }
160*03a0fabfSPeter Brune 
161*03a0fabfSPeter Brune #undef __FUNCT__
162*03a0fabfSPeter Brune #define __FUNCT__ "DMInterpolateHook_SNESDM"
163*03a0fabfSPeter Brune /* This could restrict auxiliary information to the coarse level.
164*03a0fabfSPeter Brune  */
165*03a0fabfSPeter Brune static PetscErrorCode DMInterpolateHook_SNESDM(DM dm,Mat Interp,DM dmf,void *ctx)
166*03a0fabfSPeter Brune {
167*03a0fabfSPeter Brune 
168*03a0fabfSPeter Brune   PetscFunctionBegin;
169*03a0fabfSPeter Brune   PetscFunctionReturn(0);
170*03a0fabfSPeter Brune }
171*03a0fabfSPeter Brune 
172*03a0fabfSPeter Brune #undef __FUNCT__
1736cab3a1bSJed Brown #define __FUNCT__ "DMSNESGetContext"
1746cab3a1bSJed Brown /*@C
1756cab3a1bSJed Brown    DMSNESGetContext - get read-only private SNESDM context from a DM
1766cab3a1bSJed Brown 
1776cab3a1bSJed Brown    Not Collective
1786cab3a1bSJed Brown 
1796cab3a1bSJed Brown    Input Argument:
1806cab3a1bSJed Brown .  dm - DM to be used with SNES
1816cab3a1bSJed Brown 
1826cab3a1bSJed Brown    Output Argument:
1836cab3a1bSJed Brown .  snesdm - private SNESDM context
1846cab3a1bSJed Brown 
1856cab3a1bSJed Brown    Level: developer
1866cab3a1bSJed Brown 
1876cab3a1bSJed Brown    Notes:
1886cab3a1bSJed Brown    Use DMSNESGetContextWrite() if write access is needed. The DMSNESSetXXX API should be used wherever possible.
1896cab3a1bSJed Brown 
1906cab3a1bSJed Brown .seealso: DMSNESGetContextWrite()
1916cab3a1bSJed Brown @*/
1926cab3a1bSJed Brown PetscErrorCode DMSNESGetContext(DM dm,SNESDM *snesdm)
1936cab3a1bSJed Brown {
1946cab3a1bSJed Brown   PetscErrorCode ierr;
1956cab3a1bSJed Brown   PetscContainer container;
1966cab3a1bSJed Brown   SNESDM         sdm;
1976cab3a1bSJed Brown 
1986cab3a1bSJed Brown   PetscFunctionBegin;
1996cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2006cab3a1bSJed Brown   ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
2016cab3a1bSJed Brown   if (container) {
2026cab3a1bSJed Brown     ierr = PetscContainerGetPointer(container,(void**)snesdm);CHKERRQ(ierr);
2036cab3a1bSJed Brown   } else {
2046cab3a1bSJed Brown     ierr = PetscInfo(dm,"Creating new SNESDM\n");CHKERRQ(ierr);
2056cab3a1bSJed Brown     ierr = PetscContainerCreate(((PetscObject)dm)->comm,&container);CHKERRQ(ierr);
2066cab3a1bSJed Brown     ierr = PetscNewLog(dm,struct _n_SNESDM,&sdm);CHKERRQ(ierr);
2076cab3a1bSJed Brown     ierr = PetscContainerSetPointer(container,sdm);CHKERRQ(ierr);
2086cab3a1bSJed Brown     ierr = PetscContainerSetUserDestroy(container,PetscContainerDestroy_SNESDM);CHKERRQ(ierr);
2096cab3a1bSJed Brown     ierr = PetscObjectCompose((PetscObject)dm,"SNESDM",(PetscObject)container);CHKERRQ(ierr);
210caa4e7f2SJed Brown     ierr = DMCoarsenHookAdd(dm,DMCoarsenHook_SNESDM,DMRestrictHook_SNESDM,PETSC_NULL);CHKERRQ(ierr);
2116cab3a1bSJed Brown     ierr = PetscContainerGetPointer(container,(void**)snesdm);CHKERRQ(ierr);
2126cab3a1bSJed Brown     ierr = PetscContainerDestroy(&container);CHKERRQ(ierr);
2136cab3a1bSJed Brown   }
2146cab3a1bSJed Brown   PetscFunctionReturn(0);
2156cab3a1bSJed Brown }
2166cab3a1bSJed Brown 
2176cab3a1bSJed Brown #undef __FUNCT__
2186cab3a1bSJed Brown #define __FUNCT__ "DMSNESGetContextWrite"
2196cab3a1bSJed Brown /*@C
2206cab3a1bSJed Brown    DMSNESGetContextWrite - get write access to private SNESDM context from a DM
2216cab3a1bSJed Brown 
2226cab3a1bSJed Brown    Not Collective
2236cab3a1bSJed Brown 
2246cab3a1bSJed Brown    Input Argument:
2256cab3a1bSJed Brown .  dm - DM to be used with SNES
2266cab3a1bSJed Brown 
2276cab3a1bSJed Brown    Output Argument:
2286cab3a1bSJed Brown .  snesdm - private SNESDM context
2296cab3a1bSJed Brown 
2306cab3a1bSJed Brown    Level: developer
2316cab3a1bSJed Brown 
2326cab3a1bSJed Brown .seealso: DMSNESGetContext()
2336cab3a1bSJed Brown @*/
2346cab3a1bSJed Brown PetscErrorCode DMSNESGetContextWrite(DM dm,SNESDM *snesdm)
2356cab3a1bSJed Brown {
2366cab3a1bSJed Brown   PetscErrorCode ierr;
2376cab3a1bSJed Brown   SNESDM         sdm;
2386cab3a1bSJed Brown 
2396cab3a1bSJed Brown   PetscFunctionBegin;
2406cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2416cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
2426cab3a1bSJed Brown   if (!sdm->originaldm) sdm->originaldm = dm;
2436cab3a1bSJed Brown   if (sdm->originaldm != dm) {  /* Copy on write */
2446cab3a1bSJed Brown     PetscContainer container;
2456cab3a1bSJed Brown     SNESDM         oldsdm = sdm;
2466cab3a1bSJed Brown     ierr = PetscInfo(dm,"Copying SNESDM due to write\n");CHKERRQ(ierr);
2476cab3a1bSJed Brown     ierr = PetscContainerCreate(((PetscObject)dm)->comm,&container);CHKERRQ(ierr);
2486cab3a1bSJed Brown     ierr = PetscNewLog(dm,struct _n_SNESDM,&sdm);CHKERRQ(ierr);
2498caf3d72SBarry Smith     ierr = PetscMemcpy(sdm,oldsdm,sizeof(*sdm));CHKERRQ(ierr);
2506cab3a1bSJed Brown     ierr = PetscContainerSetPointer(container,sdm);CHKERRQ(ierr);
2516cab3a1bSJed Brown     ierr = PetscContainerSetUserDestroy(container,PetscContainerDestroy_SNESDM);CHKERRQ(ierr);
2526cab3a1bSJed Brown     ierr = PetscObjectCompose((PetscObject)dm,"SNESDM",(PetscObject)container);CHKERRQ(ierr);
2536cab3a1bSJed Brown     ierr = PetscContainerDestroy(&container);CHKERRQ(ierr);
254e3c0b8a2SPeter Brune     /* implementation specific copy hooks */
255e3c0b8a2SPeter Brune     ierr = (sdm->duplicate)(oldsdm,dm);CHKERRQ(ierr);
2566cab3a1bSJed Brown   }
2576cab3a1bSJed Brown   *snesdm = sdm;
2586cab3a1bSJed Brown   PetscFunctionReturn(0);
2596cab3a1bSJed Brown }
2606cab3a1bSJed Brown 
2616cab3a1bSJed Brown #undef __FUNCT__
2626cab3a1bSJed Brown #define __FUNCT__ "DMSNESCopyContext"
2636cab3a1bSJed Brown /*@C
2646cab3a1bSJed Brown    DMSNESCopyContext - copies a DM context to a new DM
2656cab3a1bSJed Brown 
2666cab3a1bSJed Brown    Logically Collective
2676cab3a1bSJed Brown 
2686cab3a1bSJed Brown    Input Arguments:
2696cab3a1bSJed Brown +  dmsrc - DM to obtain context from
2706cab3a1bSJed Brown -  dmdest - DM to add context to
2716cab3a1bSJed Brown 
2726cab3a1bSJed Brown    Level: developer
2736cab3a1bSJed Brown 
2746cab3a1bSJed Brown    Note:
2756cab3a1bSJed Brown    The context is copied by reference. This function does not ensure that a context exists.
2766cab3a1bSJed Brown 
2776cab3a1bSJed Brown .seealso: DMSNESGetContext(), SNESSetDM()
2786cab3a1bSJed Brown @*/
2796cab3a1bSJed Brown PetscErrorCode DMSNESCopyContext(DM dmsrc,DM dmdest)
2806cab3a1bSJed Brown {
2816cab3a1bSJed Brown   PetscErrorCode ierr;
2826cab3a1bSJed Brown   PetscContainer container;
2836cab3a1bSJed Brown 
2846cab3a1bSJed Brown   PetscFunctionBegin;
2856cab3a1bSJed Brown   PetscValidHeaderSpecific(dmsrc,DM_CLASSID,1);
2866cab3a1bSJed Brown   PetscValidHeaderSpecific(dmdest,DM_CLASSID,2);
2876cab3a1bSJed Brown   ierr = PetscObjectQuery((PetscObject)dmsrc,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
2886cab3a1bSJed Brown   if (container) {
2896cab3a1bSJed Brown     ierr = PetscObjectCompose((PetscObject)dmdest,"SNESDM",(PetscObject)container);CHKERRQ(ierr);
290caa4e7f2SJed Brown     ierr = DMCoarsenHookAdd(dmdest,DMCoarsenHook_SNESDM,DMRestrictHook_SNESDM,PETSC_NULL);CHKERRQ(ierr);
291*03a0fabfSPeter Brune     ierr = DMRefineHookAdd(dmdest,DMRefineHook_SNESDM,DMInterpolateHook_SNESDM,PETSC_NULL);CHKERRQ(ierr);
2926cab3a1bSJed Brown   }
2936cab3a1bSJed Brown   PetscFunctionReturn(0);
2946cab3a1bSJed Brown }
2956cab3a1bSJed Brown 
2966cab3a1bSJed Brown #undef __FUNCT__
2976cab3a1bSJed Brown #define __FUNCT__ "DMSNESSetFunction"
2986cab3a1bSJed Brown /*@C
2996cab3a1bSJed Brown    DMSNESSetFunction - set SNES residual evaluation function
3006cab3a1bSJed Brown 
3016cab3a1bSJed Brown    Not Collective
3026cab3a1bSJed Brown 
3036cab3a1bSJed Brown    Input Arguments:
3046cab3a1bSJed Brown +  dm - DM to be used with SNES
3056cab3a1bSJed Brown .  func - residual evaluation function, see SNESSetFunction() for calling sequence
3066cab3a1bSJed Brown -  ctx - context for residual evaluation
3076cab3a1bSJed Brown 
3086cab3a1bSJed Brown    Level: advanced
3096cab3a1bSJed Brown 
3106cab3a1bSJed Brown    Note:
3116cab3a1bSJed Brown    SNESSetFunction() is normally used, but it calls this function internally because the user context is actually
3126cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
3136cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
3146cab3a1bSJed Brown 
3156cab3a1bSJed Brown .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian()
3166cab3a1bSJed Brown @*/
3176cab3a1bSJed Brown PetscErrorCode DMSNESSetFunction(DM dm,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
3186cab3a1bSJed Brown {
3196cab3a1bSJed Brown   PetscErrorCode ierr;
3206cab3a1bSJed Brown   SNESDM sdm;
3216cab3a1bSJed Brown 
3226cab3a1bSJed Brown   PetscFunctionBegin;
3236cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3246cab3a1bSJed Brown   ierr = DMSNESGetContextWrite(dm,&sdm);CHKERRQ(ierr);
3256cab3a1bSJed Brown   if (func) sdm->computefunction = func;
3266cab3a1bSJed Brown   if (ctx)  sdm->functionctx = ctx;
3276cab3a1bSJed Brown   PetscFunctionReturn(0);
3286cab3a1bSJed Brown }
3296cab3a1bSJed Brown 
3306cab3a1bSJed Brown #undef __FUNCT__
3316cab3a1bSJed Brown #define __FUNCT__ "DMSNESGetFunction"
3326cab3a1bSJed Brown /*@C
3336cab3a1bSJed Brown    DMSNESGetFunction - get SNES residual evaluation function
3346cab3a1bSJed Brown 
3356cab3a1bSJed Brown    Not Collective
3366cab3a1bSJed Brown 
3376cab3a1bSJed Brown    Input Argument:
3386cab3a1bSJed Brown .  dm - DM to be used with SNES
3396cab3a1bSJed Brown 
3406cab3a1bSJed Brown    Output Arguments:
3416cab3a1bSJed Brown +  func - residual evaluation function, see SNESSetFunction() for calling sequence
3426cab3a1bSJed Brown -  ctx - context for residual evaluation
3436cab3a1bSJed Brown 
3446cab3a1bSJed Brown    Level: advanced
3456cab3a1bSJed Brown 
3466cab3a1bSJed Brown    Note:
3476cab3a1bSJed Brown    SNESGetFunction() is normally used, but it calls this function internally because the user context is actually
3486cab3a1bSJed Brown    associated with the DM.
3496cab3a1bSJed Brown 
3506cab3a1bSJed Brown .seealso: DMSNESSetContext(), DMSNESSetFunction(), SNESSetFunction()
3516cab3a1bSJed Brown @*/
3526cab3a1bSJed Brown PetscErrorCode DMSNESGetFunction(DM dm,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
3536cab3a1bSJed Brown {
3546cab3a1bSJed Brown   PetscErrorCode ierr;
3556cab3a1bSJed Brown   SNESDM sdm;
3566cab3a1bSJed Brown 
3576cab3a1bSJed Brown   PetscFunctionBegin;
3586cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3596cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
3606cab3a1bSJed Brown   if (func) *func = sdm->computefunction;
3616cab3a1bSJed Brown   if (ctx)  *ctx = sdm->functionctx;
3626cab3a1bSJed Brown   PetscFunctionReturn(0);
3636cab3a1bSJed Brown }
3646cab3a1bSJed Brown 
3656cab3a1bSJed Brown #undef __FUNCT__
3666cab3a1bSJed Brown #define __FUNCT__ "DMSNESSetGS"
3676cab3a1bSJed Brown /*@C
3686cab3a1bSJed Brown    DMSNESSetGS - set SNES Gauss-Seidel relaxation function
3696cab3a1bSJed Brown 
3706cab3a1bSJed Brown    Not Collective
3716cab3a1bSJed Brown 
3726cab3a1bSJed Brown    Input Argument:
3736cab3a1bSJed Brown +  dm - DM to be used with SNES
3746cab3a1bSJed Brown .  func - relaxation function, see SNESSetGS() for calling sequence
3756cab3a1bSJed Brown -  ctx - context for residual evaluation
3766cab3a1bSJed Brown 
3776cab3a1bSJed Brown    Level: advanced
3786cab3a1bSJed Brown 
3796cab3a1bSJed Brown    Note:
3806cab3a1bSJed Brown    SNESSetGS() is normally used, but it calls this function internally because the user context is actually
3816cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
3826cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
3836cab3a1bSJed Brown 
3846cab3a1bSJed Brown .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian(), DMSNESSetFunction()
3856cab3a1bSJed Brown @*/
3866cab3a1bSJed Brown PetscErrorCode DMSNESSetGS(DM dm,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
3876cab3a1bSJed Brown {
3886cab3a1bSJed Brown   PetscErrorCode ierr;
3896cab3a1bSJed Brown   SNESDM sdm;
3906cab3a1bSJed Brown 
3916cab3a1bSJed Brown   PetscFunctionBegin;
3926cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3936cab3a1bSJed Brown   ierr = DMSNESGetContextWrite(dm,&sdm);CHKERRQ(ierr);
3946cab3a1bSJed Brown   if (func) sdm->computegs = func;
3956cab3a1bSJed Brown   if (ctx)  sdm->gsctx = ctx;
3966cab3a1bSJed Brown   PetscFunctionReturn(0);
3976cab3a1bSJed Brown }
3986cab3a1bSJed Brown 
3996cab3a1bSJed Brown #undef __FUNCT__
4006cab3a1bSJed Brown #define __FUNCT__ "DMSNESGetGS"
4016cab3a1bSJed Brown /*@C
4026cab3a1bSJed Brown    DMSNESGetGS - get SNES Gauss-Seidel relaxation function
4036cab3a1bSJed Brown 
4046cab3a1bSJed Brown    Not Collective
4056cab3a1bSJed Brown 
4066cab3a1bSJed Brown    Input Argument:
4076cab3a1bSJed Brown .  dm - DM to be used with SNES
4086cab3a1bSJed Brown 
4096cab3a1bSJed Brown    Output Arguments:
4106cab3a1bSJed Brown +  func - relaxation function, see SNESSetGS() for calling sequence
4116cab3a1bSJed Brown -  ctx - context for residual evaluation
4126cab3a1bSJed Brown 
4136cab3a1bSJed Brown    Level: advanced
4146cab3a1bSJed Brown 
4156cab3a1bSJed Brown    Note:
4166cab3a1bSJed Brown    SNESGetGS() is normally used, but it calls this function internally because the user context is actually
4176cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
4186cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
4196cab3a1bSJed Brown 
4206cab3a1bSJed Brown .seealso: DMSNESSetContext(), SNESGetGS(), DMSNESGetJacobian(), DMSNESGetFunction()
4216cab3a1bSJed Brown @*/
4226cab3a1bSJed Brown PetscErrorCode DMSNESGetGS(DM dm,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
4236cab3a1bSJed Brown {
4246cab3a1bSJed Brown   PetscErrorCode ierr;
4256cab3a1bSJed Brown   SNESDM sdm;
4266cab3a1bSJed Brown 
4276cab3a1bSJed Brown   PetscFunctionBegin;
4286cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4296cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
4306cab3a1bSJed Brown   if (func) *func = sdm->computegs;
4316cab3a1bSJed Brown   if (ctx)  *ctx = sdm->gsctx;
4326cab3a1bSJed Brown   PetscFunctionReturn(0);
4336cab3a1bSJed Brown }
4346cab3a1bSJed Brown 
4356cab3a1bSJed Brown #undef __FUNCT__
4366cab3a1bSJed Brown #define __FUNCT__ "DMSNESSetJacobian"
4376cab3a1bSJed Brown /*@C
438ecfdb398SPeter Brune    DMSNESSetJacobian - set SNES Jacobian evaluation function
4396cab3a1bSJed Brown 
4406cab3a1bSJed Brown    Not Collective
4416cab3a1bSJed Brown 
4426cab3a1bSJed Brown    Input Argument:
4436cab3a1bSJed Brown +  dm - DM to be used with SNES
4446cab3a1bSJed Brown .  func - Jacobian evaluation function, see SNESSetJacobian() for calling sequence
4456cab3a1bSJed Brown -  ctx - context for residual evaluation
4466cab3a1bSJed Brown 
4476cab3a1bSJed Brown    Level: advanced
4486cab3a1bSJed Brown 
4496cab3a1bSJed Brown    Note:
4506cab3a1bSJed Brown    SNESSetJacobian() is normally used, but it calls this function internally because the user context is actually
4516cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
4526cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
4536cab3a1bSJed Brown 
4546cab3a1bSJed Brown .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESGetJacobian(), SNESSetJacobian()
4556cab3a1bSJed Brown @*/
4566cab3a1bSJed Brown PetscErrorCode DMSNESSetJacobian(DM dm,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
4576cab3a1bSJed Brown {
4586cab3a1bSJed Brown   PetscErrorCode ierr;
4596cab3a1bSJed Brown   SNESDM sdm;
4606cab3a1bSJed Brown 
4616cab3a1bSJed Brown   PetscFunctionBegin;
4626cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4636cab3a1bSJed Brown   ierr = DMSNESGetContextWrite(dm,&sdm);CHKERRQ(ierr);
4646cab3a1bSJed Brown   if (func) sdm->computejacobian = func;
4656cab3a1bSJed Brown   if (ctx)  sdm->jacobianctx = ctx;
4666cab3a1bSJed Brown   PetscFunctionReturn(0);
4676cab3a1bSJed Brown }
4686cab3a1bSJed Brown 
4696cab3a1bSJed Brown #undef __FUNCT__
4706cab3a1bSJed Brown #define __FUNCT__ "DMSNESGetJacobian"
4716cab3a1bSJed Brown /*@C
472ecfdb398SPeter Brune    DMSNESGetJacobian - get SNES Jacobian evaluation function
4736cab3a1bSJed Brown 
4746cab3a1bSJed Brown    Not Collective
4756cab3a1bSJed Brown 
4766cab3a1bSJed Brown    Input Argument:
4776cab3a1bSJed Brown .  dm - DM to be used with SNES
4786cab3a1bSJed Brown 
4796cab3a1bSJed Brown    Output Arguments:
4806cab3a1bSJed Brown +  func - Jacobian evaluation function, see SNESSetJacobian() for calling sequence
4816cab3a1bSJed Brown -  ctx - context for residual evaluation
4826cab3a1bSJed Brown 
4836cab3a1bSJed Brown    Level: advanced
4846cab3a1bSJed Brown 
4856cab3a1bSJed Brown    Note:
4866cab3a1bSJed Brown    SNESGetJacobian() is normally used, but it calls this function internally because the user context is actually
4876cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
4886cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
4896cab3a1bSJed Brown 
4906cab3a1bSJed Brown .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian()
4916cab3a1bSJed Brown @*/
4926cab3a1bSJed Brown PetscErrorCode DMSNESGetJacobian(DM dm,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
4936cab3a1bSJed Brown {
4946cab3a1bSJed Brown   PetscErrorCode ierr;
4956cab3a1bSJed Brown   SNESDM sdm;
4966cab3a1bSJed Brown 
4976cab3a1bSJed Brown   PetscFunctionBegin;
4986cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4996cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
5006cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
5016cab3a1bSJed Brown   if (ctx)  *ctx = sdm->jacobianctx;
5026cab3a1bSJed Brown   PetscFunctionReturn(0);
5036cab3a1bSJed Brown }
5046cab3a1bSJed Brown 
5056cab3a1bSJed Brown #undef __FUNCT__
506e03ab78fSPeter Brune #define __FUNCT__ "DMSNESSetPicard"
507e03ab78fSPeter Brune /*@C
508e03ab78fSPeter Brune    DMSNESSetPicard - set SNES Picard iteration matrix and RHS evaluation functions.
509e03ab78fSPeter Brune 
510e03ab78fSPeter Brune    Not Collective
511e03ab78fSPeter Brune 
512e03ab78fSPeter Brune    Input Argument:
513e03ab78fSPeter Brune +  dm - DM to be used with SNES
514e03ab78fSPeter Brune .  func - RHS evaluation function, see SNESSetFunction() for calling sequence
515e03ab78fSPeter Brune .  pjac - Picard matrix evaluation function, see SNESSetJacobian() for calling sequence
516e03ab78fSPeter Brune -  ctx - context for residual evaluation
517e03ab78fSPeter Brune 
518e03ab78fSPeter Brune    Level: advanced
519e03ab78fSPeter Brune 
520e03ab78fSPeter Brune .seealso: SNESSetPicard(), DMSNESSetFunction(), DMSNESSetJacobian()
521e03ab78fSPeter Brune @*/
522e03ab78fSPeter Brune PetscErrorCode DMSNESSetPicard(DM dm,PetscErrorCode (*pfunc)(SNES,Vec,Vec,void*),PetscErrorCode (*pjac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
523e03ab78fSPeter Brune {
524e03ab78fSPeter Brune   PetscErrorCode ierr;
525e03ab78fSPeter Brune   SNESDM sdm;
526e03ab78fSPeter Brune 
527e03ab78fSPeter Brune   PetscFunctionBegin;
528e03ab78fSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
529e03ab78fSPeter Brune   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
530e03ab78fSPeter Brune   if (pfunc) sdm->computepfunction = pfunc;
531e03ab78fSPeter Brune   if (pjac)  sdm->computepjacobian = pjac;
532e03ab78fSPeter Brune   if (ctx)   sdm->pctx             = ctx;
533e03ab78fSPeter Brune   PetscFunctionReturn(0);
534e03ab78fSPeter Brune }
535e03ab78fSPeter Brune 
5367971a8bfSPeter Brune 
5377971a8bfSPeter Brune #undef __FUNCT__
5387971a8bfSPeter Brune #define __FUNCT__ "DMSNESGetPicard"
5397971a8bfSPeter Brune /*@C
5407971a8bfSPeter Brune    DMSNESGetPicard - get SNES Picard iteration evaluation functions
5417971a8bfSPeter Brune 
5427971a8bfSPeter Brune    Not Collective
5437971a8bfSPeter Brune 
5447971a8bfSPeter Brune    Input Argument:
5457971a8bfSPeter Brune .  dm - DM to be used with SNES
5467971a8bfSPeter Brune 
5477971a8bfSPeter Brune    Output Arguments:
5487971a8bfSPeter Brune +  pfunc - Jacobian evaluation function, see SNESSetJacobian() for calling sequence
5497971a8bfSPeter Brune .  pjac  - RHS evaluation function, see SNESSetFunction() for calling sequence
5507971a8bfSPeter Brune -  ctx - context for residual evaluation
5517971a8bfSPeter Brune 
5527971a8bfSPeter Brune    Level: advanced
5537971a8bfSPeter Brune 
5547971a8bfSPeter Brune .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian()
5557971a8bfSPeter Brune @*/
5567971a8bfSPeter Brune PetscErrorCode DMSNESGetPicard(DM dm,PetscErrorCode (**pfunc)(SNES,Vec,Vec,void*),PetscErrorCode (**pjac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
5577971a8bfSPeter Brune {
5587971a8bfSPeter Brune   PetscErrorCode ierr;
5597971a8bfSPeter Brune   SNESDM sdm;
5607971a8bfSPeter Brune 
5617971a8bfSPeter Brune   PetscFunctionBegin;
5627971a8bfSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5637971a8bfSPeter Brune   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
5647971a8bfSPeter Brune   if (pfunc) *pfunc = sdm->computepfunction;
5657971a8bfSPeter Brune   if (pjac) *pjac   = sdm->computepjacobian;
5667971a8bfSPeter Brune   if (ctx)  *ctx    = sdm->pctx;
5677971a8bfSPeter Brune   PetscFunctionReturn(0);
5687971a8bfSPeter Brune }
5697971a8bfSPeter Brune 
5707971a8bfSPeter Brune 
571e03ab78fSPeter Brune #undef __FUNCT__
5726cab3a1bSJed Brown #define __FUNCT__ "SNESDefaultComputeFunction_DMLegacy"
5736cab3a1bSJed Brown static PetscErrorCode SNESDefaultComputeFunction_DMLegacy(SNES snes,Vec X,Vec F,void *ctx)
5746cab3a1bSJed Brown {
5756cab3a1bSJed Brown   PetscErrorCode ierr;
5766cab3a1bSJed Brown   DM             dm;
5776cab3a1bSJed Brown 
5786cab3a1bSJed Brown   PetscFunctionBegin;
5796cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
5806cab3a1bSJed Brown   ierr = DMComputeFunction(dm,X,F);CHKERRQ(ierr);
5816cab3a1bSJed Brown   PetscFunctionReturn(0);
5826cab3a1bSJed Brown }
5836cab3a1bSJed Brown 
5846cab3a1bSJed Brown #undef __FUNCT__
5856cab3a1bSJed Brown #define __FUNCT__ "SNESDefaultComputeJacobian_DMLegacy"
5866cab3a1bSJed Brown static PetscErrorCode SNESDefaultComputeJacobian_DMLegacy(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *mstr,void *ctx)
5876cab3a1bSJed Brown {
5886cab3a1bSJed Brown   PetscErrorCode ierr;
5896cab3a1bSJed Brown   DM             dm;
5906cab3a1bSJed Brown 
5916cab3a1bSJed Brown   PetscFunctionBegin;
5926cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
5936cab3a1bSJed Brown   ierr = DMComputeJacobian(dm,X,*A,*B,mstr);CHKERRQ(ierr);
5946cab3a1bSJed Brown   PetscFunctionReturn(0);
5956cab3a1bSJed Brown }
5966cab3a1bSJed Brown 
5976cab3a1bSJed Brown #undef __FUNCT__
5986cab3a1bSJed Brown #define __FUNCT__ "DMSNESSetUpLegacy"
5996cab3a1bSJed Brown /* Sets up calling of legacy DM routines */
6006cab3a1bSJed Brown PetscErrorCode DMSNESSetUpLegacy(DM dm)
6016cab3a1bSJed Brown {
6026cab3a1bSJed Brown   PetscErrorCode ierr;
6036cab3a1bSJed Brown   SNESDM         sdm;
6046cab3a1bSJed Brown 
6056cab3a1bSJed Brown   PetscFunctionBegin;
6066cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
6076cab3a1bSJed Brown   if (!sdm->computefunction) {ierr = DMSNESSetFunction(dm,SNESDefaultComputeFunction_DMLegacy,PETSC_NULL);CHKERRQ(ierr);}
6086cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
609679f678eSPeter Brune   if (!sdm->computejacobian) {
610679f678eSPeter Brune     if (dm->ops->functionj) {
611679f678eSPeter Brune       ierr = DMSNESSetJacobian(dm,SNESDefaultComputeJacobian_DMLegacy,PETSC_NULL);CHKERRQ(ierr);
612679f678eSPeter Brune     } else {
613679f678eSPeter Brune       ierr = DMSNESSetJacobian(dm,SNESDefaultComputeJacobianColor,PETSC_NULL);CHKERRQ(ierr);
614679f678eSPeter Brune     }
615679f678eSPeter Brune   }
6166cab3a1bSJed Brown   PetscFunctionReturn(0);
6176cab3a1bSJed Brown }
6186427ad5bSPeter Brune 
6196427ad5bSPeter Brune /* block functions */
6206427ad5bSPeter Brune 
6216427ad5bSPeter Brune #undef __FUNCT__
6226427ad5bSPeter Brune #define __FUNCT__ "DMSNESSetBlockFunction"
6236427ad5bSPeter Brune /*@C
6246427ad5bSPeter Brune    DMSNESSetBlockFunction - set SNES residual evaluation function
6256427ad5bSPeter Brune 
6266427ad5bSPeter Brune    Not Collective
6276427ad5bSPeter Brune 
6286427ad5bSPeter Brune    Input Arguments:
6296427ad5bSPeter Brune +  dm - DM to be used with SNES
6306427ad5bSPeter Brune .  func - residual evaluation function, see SNESSetFunction() for calling sequence
6316427ad5bSPeter Brune -  ctx - context for residual evaluation
6326427ad5bSPeter Brune 
6336427ad5bSPeter Brune    Level: developer
6346427ad5bSPeter Brune 
6356427ad5bSPeter Brune    Note:
6366427ad5bSPeter Brune    Mostly for use in DM implementations and transferred to a block function rather than being called from here.
6376427ad5bSPeter Brune 
6386427ad5bSPeter Brune .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian()
6396427ad5bSPeter Brune @*/
6406427ad5bSPeter Brune PetscErrorCode DMSNESSetBlockFunction(DM dm,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
6416427ad5bSPeter Brune {
6426427ad5bSPeter Brune   PetscErrorCode ierr;
6436427ad5bSPeter Brune   SNESDM sdm;
6446427ad5bSPeter Brune 
6456427ad5bSPeter Brune   PetscFunctionBegin;
6466427ad5bSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6476427ad5bSPeter Brune   ierr = DMSNESGetContextWrite(dm,&sdm);CHKERRQ(ierr);
6486427ad5bSPeter Brune   if (func) sdm->computeblockfunction = func;
6496427ad5bSPeter Brune   if (ctx)  sdm->blockfunctionctx = ctx;
6506427ad5bSPeter Brune   PetscFunctionReturn(0);
6516427ad5bSPeter Brune }
6526427ad5bSPeter Brune 
6536427ad5bSPeter Brune #undef __FUNCT__
6546427ad5bSPeter Brune #define __FUNCT__ "DMSNESGetBlockFunction"
6556427ad5bSPeter Brune /*@C
6566427ad5bSPeter Brune    DMSNESGetBlockFunction - get SNES residual evaluation function
6576427ad5bSPeter Brune 
6586427ad5bSPeter Brune    Not Collective
6596427ad5bSPeter Brune 
6606427ad5bSPeter Brune    Input Argument:
6616427ad5bSPeter Brune .  dm - DM to be used with SNES
6626427ad5bSPeter Brune 
6636427ad5bSPeter Brune    Output Arguments:
6646427ad5bSPeter Brune +  func - residual evaluation function, see SNESSetFunction() for calling sequence
6656427ad5bSPeter Brune -  ctx - context for residual evaluation
6666427ad5bSPeter Brune 
6676427ad5bSPeter Brune    Level: developer
6686427ad5bSPeter Brune 
6696427ad5bSPeter Brune .seealso: DMSNESSetContext(), DMSNESSetFunction(), SNESSetFunction()
6706427ad5bSPeter Brune @*/
6716427ad5bSPeter Brune PetscErrorCode DMSNESGetBlockFunction(DM dm,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
6726427ad5bSPeter Brune {
6736427ad5bSPeter Brune   PetscErrorCode ierr;
6746427ad5bSPeter Brune   SNESDM sdm;
6756427ad5bSPeter Brune 
6766427ad5bSPeter Brune   PetscFunctionBegin;
6776427ad5bSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6786427ad5bSPeter Brune   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
6796427ad5bSPeter Brune   if (func) *func = sdm->computeblockfunction;
6806427ad5bSPeter Brune   if (ctx)  *ctx = sdm->blockfunctionctx;
6816427ad5bSPeter Brune   PetscFunctionReturn(0);
6826427ad5bSPeter Brune }
6836427ad5bSPeter Brune 
6846427ad5bSPeter Brune 
6856427ad5bSPeter Brune #undef __FUNCT__
6866427ad5bSPeter Brune #define __FUNCT__ "DMSNESSetBlockJacobian"
6876427ad5bSPeter Brune /*@C
6886427ad5bSPeter Brune    DMSNESSetJacobian - set SNES Jacobian evaluation function
6896427ad5bSPeter Brune 
6906427ad5bSPeter Brune    Not Collective
6916427ad5bSPeter Brune 
6926427ad5bSPeter Brune    Input Argument:
6936427ad5bSPeter Brune +  dm - DM to be used with SNES
6946427ad5bSPeter Brune .  func - Jacobian evaluation function, see SNESSetJacobian() for calling sequence
6956427ad5bSPeter Brune -  ctx - context for residual evaluation
6966427ad5bSPeter Brune 
6976427ad5bSPeter Brune    Level: advanced
6986427ad5bSPeter Brune 
6996427ad5bSPeter Brune    Note:
7006427ad5bSPeter Brune    Mostly for use in DM implementations and transferred to a block function rather than being called from here.
7016427ad5bSPeter Brune 
7026427ad5bSPeter Brune .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESGetJacobian(), SNESSetJacobian()
7036427ad5bSPeter Brune @*/
7046427ad5bSPeter Brune PetscErrorCode DMSNESSetBlockJacobian(DM dm,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
7056427ad5bSPeter Brune {
7066427ad5bSPeter Brune   PetscErrorCode ierr;
7076427ad5bSPeter Brune   SNESDM sdm;
7086427ad5bSPeter Brune 
7096427ad5bSPeter Brune   PetscFunctionBegin;
7106427ad5bSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7116427ad5bSPeter Brune   ierr = DMSNESGetContextWrite(dm,&sdm);CHKERRQ(ierr);
7126427ad5bSPeter Brune   if (func) sdm->computeblockjacobian = func;
7136427ad5bSPeter Brune   if (ctx)  sdm->blockjacobianctx = ctx;
7146427ad5bSPeter Brune   PetscFunctionReturn(0);
7156427ad5bSPeter Brune }
7166427ad5bSPeter Brune 
7176427ad5bSPeter Brune #undef __FUNCT__
7186427ad5bSPeter Brune #define __FUNCT__ "DMSNESGetBlockJacobian"
7196427ad5bSPeter Brune /*@C
7206427ad5bSPeter Brune    DMSNESGetBlockJacobian - get SNES Jacobian evaluation function
7216427ad5bSPeter Brune 
7226427ad5bSPeter Brune    Not Collective
7236427ad5bSPeter Brune 
7246427ad5bSPeter Brune    Input Argument:
7256427ad5bSPeter Brune .  dm - DM to be used with SNES
7266427ad5bSPeter Brune 
7276427ad5bSPeter Brune    Output Arguments:
7286427ad5bSPeter Brune +  func - Jacobian evaluation function, see SNESSetJacobian() for calling sequence
7296427ad5bSPeter Brune -  ctx - context for residual evaluation
7306427ad5bSPeter Brune 
7316427ad5bSPeter Brune    Level: advanced
7326427ad5bSPeter Brune 
7336427ad5bSPeter Brune .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian()
7346427ad5bSPeter Brune @*/
7356427ad5bSPeter Brune PetscErrorCode DMSNESGetBlockJacobian(DM dm,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
7366427ad5bSPeter Brune {
7376427ad5bSPeter Brune   PetscErrorCode ierr;
7386427ad5bSPeter Brune   SNESDM sdm;
7396427ad5bSPeter Brune 
7406427ad5bSPeter Brune   PetscFunctionBegin;
7416427ad5bSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7426427ad5bSPeter Brune   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
7436427ad5bSPeter Brune   if (func) *func = sdm->computeblockjacobian;
7446427ad5bSPeter Brune   if (ctx)  *ctx = sdm->blockjacobianctx;
7456427ad5bSPeter Brune   PetscFunctionReturn(0);
7466427ad5bSPeter Brune }
747