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); 2326cab3a1bSJed Brown } 2336cab3a1bSJed Brown *snesdm = sdm; 2346cab3a1bSJed Brown PetscFunctionReturn(0); 2356cab3a1bSJed Brown } 2366cab3a1bSJed Brown 2376cab3a1bSJed Brown #undef __FUNCT__ 2386cab3a1bSJed Brown #define __FUNCT__ "DMSNESCopyContext" 2396cab3a1bSJed Brown /*@C 2406cab3a1bSJed Brown DMSNESCopyContext - copies a DM context to a new DM 2416cab3a1bSJed Brown 2426cab3a1bSJed Brown Logically Collective 2436cab3a1bSJed Brown 2446cab3a1bSJed Brown Input Arguments: 2456cab3a1bSJed Brown + dmsrc - DM to obtain context from 2466cab3a1bSJed Brown - dmdest - DM to add context to 2476cab3a1bSJed Brown 2486cab3a1bSJed Brown Level: developer 2496cab3a1bSJed Brown 2506cab3a1bSJed Brown Note: 2516cab3a1bSJed Brown The context is copied by reference. This function does not ensure that a context exists. 2526cab3a1bSJed Brown 2536cab3a1bSJed Brown .seealso: DMSNESGetContext(), SNESSetDM() 2546cab3a1bSJed Brown @*/ 2556cab3a1bSJed Brown PetscErrorCode DMSNESCopyContext(DM dmsrc,DM dmdest) 2566cab3a1bSJed Brown { 2576cab3a1bSJed Brown PetscErrorCode ierr; 2586cab3a1bSJed Brown PetscContainer container; 2596cab3a1bSJed Brown 2606cab3a1bSJed Brown PetscFunctionBegin; 2616cab3a1bSJed Brown PetscValidHeaderSpecific(dmsrc,DM_CLASSID,1); 2626cab3a1bSJed Brown PetscValidHeaderSpecific(dmdest,DM_CLASSID,2); 2636cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dmsrc,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 2646cab3a1bSJed Brown if (container) { 2656cab3a1bSJed Brown ierr = PetscObjectCompose((PetscObject)dmdest,"SNESDM",(PetscObject)container);CHKERRQ(ierr); 266caa4e7f2SJed Brown ierr = DMCoarsenHookAdd(dmdest,DMCoarsenHook_SNESDM,DMRestrictHook_SNESDM,PETSC_NULL);CHKERRQ(ierr); 2676cab3a1bSJed Brown } 2686cab3a1bSJed Brown PetscFunctionReturn(0); 2696cab3a1bSJed Brown } 2706cab3a1bSJed Brown 2716cab3a1bSJed Brown #undef __FUNCT__ 2726cab3a1bSJed Brown #define __FUNCT__ "DMSNESSetFunction" 2736cab3a1bSJed Brown /*@C 2746cab3a1bSJed Brown DMSNESSetFunction - set SNES residual evaluation function 2756cab3a1bSJed Brown 2766cab3a1bSJed Brown Not Collective 2776cab3a1bSJed Brown 2786cab3a1bSJed Brown Input Arguments: 2796cab3a1bSJed Brown + dm - DM to be used with SNES 2806cab3a1bSJed Brown . func - residual evaluation function, see SNESSetFunction() for calling sequence 2816cab3a1bSJed Brown - ctx - context for residual evaluation 2826cab3a1bSJed Brown 2836cab3a1bSJed Brown Level: advanced 2846cab3a1bSJed Brown 2856cab3a1bSJed Brown Note: 2866cab3a1bSJed Brown SNESSetFunction() is normally used, but it calls this function internally because the user context is actually 2876cab3a1bSJed Brown associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 2886cab3a1bSJed Brown not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 2896cab3a1bSJed Brown 2906cab3a1bSJed Brown .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian() 2916cab3a1bSJed Brown @*/ 2926cab3a1bSJed Brown PetscErrorCode DMSNESSetFunction(DM dm,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 2936cab3a1bSJed Brown { 2946cab3a1bSJed Brown PetscErrorCode ierr; 2956cab3a1bSJed Brown SNESDM sdm; 2966cab3a1bSJed Brown 2976cab3a1bSJed Brown PetscFunctionBegin; 2986cab3a1bSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2996cab3a1bSJed Brown ierr = DMSNESGetContextWrite(dm,&sdm);CHKERRQ(ierr); 3006cab3a1bSJed Brown if (func) sdm->computefunction = func; 3016cab3a1bSJed Brown if (ctx) sdm->functionctx = ctx; 3026cab3a1bSJed Brown PetscFunctionReturn(0); 3036cab3a1bSJed Brown } 3046cab3a1bSJed Brown 3056cab3a1bSJed Brown #undef __FUNCT__ 3066cab3a1bSJed Brown #define __FUNCT__ "DMSNESGetFunction" 3076cab3a1bSJed Brown /*@C 3086cab3a1bSJed Brown DMSNESGetFunction - get SNES residual evaluation function 3096cab3a1bSJed Brown 3106cab3a1bSJed Brown Not Collective 3116cab3a1bSJed Brown 3126cab3a1bSJed Brown Input Argument: 3136cab3a1bSJed Brown . dm - DM to be used with SNES 3146cab3a1bSJed Brown 3156cab3a1bSJed Brown Output Arguments: 3166cab3a1bSJed Brown + func - residual evaluation function, see SNESSetFunction() for calling sequence 3176cab3a1bSJed Brown - ctx - context for residual evaluation 3186cab3a1bSJed Brown 3196cab3a1bSJed Brown Level: advanced 3206cab3a1bSJed Brown 3216cab3a1bSJed Brown Note: 3226cab3a1bSJed Brown SNESGetFunction() is normally used, but it calls this function internally because the user context is actually 3236cab3a1bSJed Brown associated with the DM. 3246cab3a1bSJed Brown 3256cab3a1bSJed Brown .seealso: DMSNESSetContext(), DMSNESSetFunction(), SNESSetFunction() 3266cab3a1bSJed Brown @*/ 3276cab3a1bSJed Brown PetscErrorCode DMSNESGetFunction(DM dm,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 3286cab3a1bSJed Brown { 3296cab3a1bSJed Brown PetscErrorCode ierr; 3306cab3a1bSJed Brown SNESDM sdm; 3316cab3a1bSJed Brown 3326cab3a1bSJed Brown PetscFunctionBegin; 3336cab3a1bSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3346cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 3356cab3a1bSJed Brown if (func) *func = sdm->computefunction; 3366cab3a1bSJed Brown if (ctx) *ctx = sdm->functionctx; 3376cab3a1bSJed Brown PetscFunctionReturn(0); 3386cab3a1bSJed Brown } 3396cab3a1bSJed Brown 3406cab3a1bSJed Brown #undef __FUNCT__ 3416cab3a1bSJed Brown #define __FUNCT__ "DMSNESSetGS" 3426cab3a1bSJed Brown /*@C 3436cab3a1bSJed Brown DMSNESSetGS - set SNES Gauss-Seidel relaxation function 3446cab3a1bSJed Brown 3456cab3a1bSJed Brown Not Collective 3466cab3a1bSJed Brown 3476cab3a1bSJed Brown Input Argument: 3486cab3a1bSJed Brown + dm - DM to be used with SNES 3496cab3a1bSJed Brown . func - relaxation function, see SNESSetGS() for calling sequence 3506cab3a1bSJed Brown - ctx - context for residual evaluation 3516cab3a1bSJed Brown 3526cab3a1bSJed Brown Level: advanced 3536cab3a1bSJed Brown 3546cab3a1bSJed Brown Note: 3556cab3a1bSJed Brown SNESSetGS() is normally used, but it calls this function internally because the user context is actually 3566cab3a1bSJed Brown associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 3576cab3a1bSJed Brown not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 3586cab3a1bSJed Brown 3596cab3a1bSJed Brown .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian(), DMSNESSetFunction() 3606cab3a1bSJed Brown @*/ 3616cab3a1bSJed Brown PetscErrorCode DMSNESSetGS(DM dm,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 3626cab3a1bSJed Brown { 3636cab3a1bSJed Brown PetscErrorCode ierr; 3646cab3a1bSJed Brown SNESDM sdm; 3656cab3a1bSJed Brown 3666cab3a1bSJed Brown PetscFunctionBegin; 3676cab3a1bSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3686cab3a1bSJed Brown ierr = DMSNESGetContextWrite(dm,&sdm);CHKERRQ(ierr); 3696cab3a1bSJed Brown if (func) sdm->computegs = func; 3706cab3a1bSJed Brown if (ctx) sdm->gsctx = ctx; 3716cab3a1bSJed Brown PetscFunctionReturn(0); 3726cab3a1bSJed Brown } 3736cab3a1bSJed Brown 3746cab3a1bSJed Brown #undef __FUNCT__ 3756cab3a1bSJed Brown #define __FUNCT__ "DMSNESGetGS" 3766cab3a1bSJed Brown /*@C 3776cab3a1bSJed Brown DMSNESGetGS - get SNES Gauss-Seidel relaxation function 3786cab3a1bSJed Brown 3796cab3a1bSJed Brown Not Collective 3806cab3a1bSJed Brown 3816cab3a1bSJed Brown Input Argument: 3826cab3a1bSJed Brown . dm - DM to be used with SNES 3836cab3a1bSJed Brown 3846cab3a1bSJed Brown Output Arguments: 3856cab3a1bSJed Brown + func - relaxation function, see SNESSetGS() for calling sequence 3866cab3a1bSJed Brown - ctx - context for residual evaluation 3876cab3a1bSJed Brown 3886cab3a1bSJed Brown Level: advanced 3896cab3a1bSJed Brown 3906cab3a1bSJed Brown Note: 3916cab3a1bSJed Brown SNESGetGS() is normally used, but it calls this function internally because the user context is actually 3926cab3a1bSJed Brown associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 3936cab3a1bSJed Brown not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 3946cab3a1bSJed Brown 3956cab3a1bSJed Brown .seealso: DMSNESSetContext(), SNESGetGS(), DMSNESGetJacobian(), DMSNESGetFunction() 3966cab3a1bSJed Brown @*/ 3976cab3a1bSJed Brown PetscErrorCode DMSNESGetGS(DM dm,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 3986cab3a1bSJed Brown { 3996cab3a1bSJed Brown PetscErrorCode ierr; 4006cab3a1bSJed Brown SNESDM sdm; 4016cab3a1bSJed Brown 4026cab3a1bSJed Brown PetscFunctionBegin; 4036cab3a1bSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4046cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 4056cab3a1bSJed Brown if (func) *func = sdm->computegs; 4066cab3a1bSJed Brown if (ctx) *ctx = sdm->gsctx; 4076cab3a1bSJed Brown PetscFunctionReturn(0); 4086cab3a1bSJed Brown } 4096cab3a1bSJed Brown 4106cab3a1bSJed Brown #undef __FUNCT__ 4116cab3a1bSJed Brown #define __FUNCT__ "DMSNESSetJacobian" 4126cab3a1bSJed Brown /*@C 413ecfdb398SPeter Brune DMSNESSetJacobian - set SNES Jacobian evaluation function 4146cab3a1bSJed Brown 4156cab3a1bSJed Brown Not Collective 4166cab3a1bSJed Brown 4176cab3a1bSJed Brown Input Argument: 4186cab3a1bSJed Brown + dm - DM to be used with SNES 4196cab3a1bSJed Brown . func - Jacobian evaluation function, see SNESSetJacobian() for calling sequence 4206cab3a1bSJed Brown - ctx - context for residual evaluation 4216cab3a1bSJed Brown 4226cab3a1bSJed Brown Level: advanced 4236cab3a1bSJed Brown 4246cab3a1bSJed Brown Note: 4256cab3a1bSJed Brown SNESSetJacobian() is normally used, but it calls this function internally because the user context is actually 4266cab3a1bSJed Brown associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 4276cab3a1bSJed Brown not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 4286cab3a1bSJed Brown 4296cab3a1bSJed Brown .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESGetJacobian(), SNESSetJacobian() 4306cab3a1bSJed Brown @*/ 4316cab3a1bSJed Brown PetscErrorCode DMSNESSetJacobian(DM dm,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 4326cab3a1bSJed Brown { 4336cab3a1bSJed Brown PetscErrorCode ierr; 4346cab3a1bSJed Brown SNESDM sdm; 4356cab3a1bSJed Brown 4366cab3a1bSJed Brown PetscFunctionBegin; 4376cab3a1bSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4386cab3a1bSJed Brown ierr = DMSNESGetContextWrite(dm,&sdm);CHKERRQ(ierr); 4396cab3a1bSJed Brown if (func) sdm->computejacobian = func; 4406cab3a1bSJed Brown if (ctx) sdm->jacobianctx = ctx; 4416cab3a1bSJed Brown PetscFunctionReturn(0); 4426cab3a1bSJed Brown } 4436cab3a1bSJed Brown 4446cab3a1bSJed Brown #undef __FUNCT__ 4456cab3a1bSJed Brown #define __FUNCT__ "DMSNESGetJacobian" 4466cab3a1bSJed Brown /*@C 447ecfdb398SPeter Brune DMSNESGetJacobian - get SNES Jacobian evaluation function 4486cab3a1bSJed Brown 4496cab3a1bSJed Brown Not Collective 4506cab3a1bSJed Brown 4516cab3a1bSJed Brown Input Argument: 4526cab3a1bSJed Brown . dm - DM to be used with SNES 4536cab3a1bSJed Brown 4546cab3a1bSJed Brown Output Arguments: 4556cab3a1bSJed Brown + func - Jacobian evaluation function, see SNESSetJacobian() for calling sequence 4566cab3a1bSJed Brown - ctx - context for residual evaluation 4576cab3a1bSJed Brown 4586cab3a1bSJed Brown Level: advanced 4596cab3a1bSJed Brown 4606cab3a1bSJed Brown Note: 4616cab3a1bSJed Brown SNESGetJacobian() is normally used, but it calls this function internally because the user context is actually 4626cab3a1bSJed Brown associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 4636cab3a1bSJed Brown not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 4646cab3a1bSJed Brown 4656cab3a1bSJed Brown .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian() 4666cab3a1bSJed Brown @*/ 4676cab3a1bSJed Brown PetscErrorCode DMSNESGetJacobian(DM dm,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 4686cab3a1bSJed Brown { 4696cab3a1bSJed Brown PetscErrorCode ierr; 4706cab3a1bSJed Brown SNESDM sdm; 4716cab3a1bSJed Brown 4726cab3a1bSJed Brown PetscFunctionBegin; 4736cab3a1bSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4746cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 4756cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 4766cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 4776cab3a1bSJed Brown PetscFunctionReturn(0); 4786cab3a1bSJed Brown } 4796cab3a1bSJed Brown 4806cab3a1bSJed Brown #undef __FUNCT__ 481e03ab78fSPeter Brune #define __FUNCT__ "DMSNESSetPicard" 482e03ab78fSPeter Brune /*@C 483e03ab78fSPeter Brune DMSNESSetPicard - set SNES Picard iteration matrix and RHS evaluation functions. 484e03ab78fSPeter Brune 485e03ab78fSPeter Brune Not Collective 486e03ab78fSPeter Brune 487e03ab78fSPeter Brune Input Argument: 488e03ab78fSPeter Brune + dm - DM to be used with SNES 489e03ab78fSPeter Brune . func - RHS evaluation function, see SNESSetFunction() for calling sequence 490e03ab78fSPeter Brune . pjac - Picard matrix evaluation function, see SNESSetJacobian() for calling sequence 491e03ab78fSPeter Brune - ctx - context for residual evaluation 492e03ab78fSPeter Brune 493e03ab78fSPeter Brune Level: advanced 494e03ab78fSPeter Brune 495e03ab78fSPeter Brune .seealso: SNESSetPicard(), DMSNESSetFunction(), DMSNESSetJacobian() 496e03ab78fSPeter Brune @*/ 497e03ab78fSPeter Brune PetscErrorCode DMSNESSetPicard(DM dm,PetscErrorCode (*pfunc)(SNES,Vec,Vec,void*),PetscErrorCode (*pjac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 498e03ab78fSPeter Brune { 499e03ab78fSPeter Brune PetscErrorCode ierr; 500e03ab78fSPeter Brune SNESDM sdm; 501e03ab78fSPeter Brune 502e03ab78fSPeter Brune PetscFunctionBegin; 503e03ab78fSPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 504e03ab78fSPeter Brune ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 505e03ab78fSPeter Brune if (pfunc) sdm->computepfunction = pfunc; 506e03ab78fSPeter Brune if (pjac) sdm->computepjacobian = pjac; 507e03ab78fSPeter Brune if (ctx) sdm->pctx = ctx; 508e03ab78fSPeter Brune PetscFunctionReturn(0); 509e03ab78fSPeter Brune } 510e03ab78fSPeter Brune 5117971a8bfSPeter Brune 5127971a8bfSPeter Brune #undef __FUNCT__ 5137971a8bfSPeter Brune #define __FUNCT__ "DMSNESGetPicard" 5147971a8bfSPeter Brune /*@C 5157971a8bfSPeter Brune DMSNESGetPicard - get SNES Picard iteration evaluation functions 5167971a8bfSPeter Brune 5177971a8bfSPeter Brune Not Collective 5187971a8bfSPeter Brune 5197971a8bfSPeter Brune Input Argument: 5207971a8bfSPeter Brune . dm - DM to be used with SNES 5217971a8bfSPeter Brune 5227971a8bfSPeter Brune Output Arguments: 5237971a8bfSPeter Brune + pfunc - Jacobian evaluation function, see SNESSetJacobian() for calling sequence 5247971a8bfSPeter Brune . pjac - RHS evaluation function, see SNESSetFunction() for calling sequence 5257971a8bfSPeter Brune - ctx - context for residual evaluation 5267971a8bfSPeter Brune 5277971a8bfSPeter Brune Level: advanced 5287971a8bfSPeter Brune 5297971a8bfSPeter Brune .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian() 5307971a8bfSPeter Brune @*/ 5317971a8bfSPeter Brune PetscErrorCode DMSNESGetPicard(DM dm,PetscErrorCode (**pfunc)(SNES,Vec,Vec,void*),PetscErrorCode (**pjac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 5327971a8bfSPeter Brune { 5337971a8bfSPeter Brune PetscErrorCode ierr; 5347971a8bfSPeter Brune SNESDM sdm; 5357971a8bfSPeter Brune 5367971a8bfSPeter Brune PetscFunctionBegin; 5377971a8bfSPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 5387971a8bfSPeter Brune ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 5397971a8bfSPeter Brune if (pfunc) *pfunc = sdm->computepfunction; 5407971a8bfSPeter Brune if (pjac) *pjac = sdm->computepjacobian; 5417971a8bfSPeter Brune if (ctx) *ctx = sdm->pctx; 5427971a8bfSPeter Brune PetscFunctionReturn(0); 5437971a8bfSPeter Brune } 5447971a8bfSPeter Brune 5457971a8bfSPeter Brune 546e03ab78fSPeter Brune #undef __FUNCT__ 5476cab3a1bSJed Brown #define __FUNCT__ "SNESDefaultComputeFunction_DMLegacy" 5486cab3a1bSJed Brown static PetscErrorCode SNESDefaultComputeFunction_DMLegacy(SNES snes,Vec X,Vec F,void *ctx) 5496cab3a1bSJed Brown { 5506cab3a1bSJed Brown PetscErrorCode ierr; 5516cab3a1bSJed Brown DM dm; 5526cab3a1bSJed Brown 5536cab3a1bSJed Brown PetscFunctionBegin; 5546cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 5556cab3a1bSJed Brown ierr = DMComputeFunction(dm,X,F);CHKERRQ(ierr); 5566cab3a1bSJed Brown PetscFunctionReturn(0); 5576cab3a1bSJed Brown } 5586cab3a1bSJed Brown 5596cab3a1bSJed Brown #undef __FUNCT__ 5606cab3a1bSJed Brown #define __FUNCT__ "SNESDefaultComputeJacobian_DMLegacy" 5616cab3a1bSJed Brown static PetscErrorCode SNESDefaultComputeJacobian_DMLegacy(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *mstr,void *ctx) 5626cab3a1bSJed Brown { 5636cab3a1bSJed Brown PetscErrorCode ierr; 5646cab3a1bSJed Brown DM dm; 5656cab3a1bSJed Brown 5666cab3a1bSJed Brown PetscFunctionBegin; 5676cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 5686cab3a1bSJed Brown ierr = DMComputeJacobian(dm,X,*A,*B,mstr);CHKERRQ(ierr); 5696cab3a1bSJed Brown PetscFunctionReturn(0); 5706cab3a1bSJed Brown } 5716cab3a1bSJed Brown 5726cab3a1bSJed Brown #undef __FUNCT__ 5736cab3a1bSJed Brown #define __FUNCT__ "DMSNESSetUpLegacy" 5746cab3a1bSJed Brown /* Sets up calling of legacy DM routines */ 5756cab3a1bSJed Brown PetscErrorCode DMSNESSetUpLegacy(DM dm) 5766cab3a1bSJed Brown { 5776cab3a1bSJed Brown PetscErrorCode ierr; 5786cab3a1bSJed Brown SNESDM sdm; 5796cab3a1bSJed Brown 5806cab3a1bSJed Brown PetscFunctionBegin; 5816cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 5826cab3a1bSJed Brown if (!sdm->computefunction) {ierr = DMSNESSetFunction(dm,SNESDefaultComputeFunction_DMLegacy,PETSC_NULL);CHKERRQ(ierr);} 5836cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 584679f678eSPeter Brune if (!sdm->computejacobian) { 585679f678eSPeter Brune if (dm->ops->functionj) { 586679f678eSPeter Brune ierr = DMSNESSetJacobian(dm,SNESDefaultComputeJacobian_DMLegacy,PETSC_NULL);CHKERRQ(ierr); 587679f678eSPeter Brune } else { 588679f678eSPeter Brune ierr = DMSNESSetJacobian(dm,SNESDefaultComputeJacobianColor,PETSC_NULL);CHKERRQ(ierr); 589679f678eSPeter Brune } 590679f678eSPeter Brune } 5916cab3a1bSJed Brown PetscFunctionReturn(0); 5926cab3a1bSJed Brown } 593*6427ad5bSPeter Brune 594*6427ad5bSPeter Brune /* block functions */ 595*6427ad5bSPeter Brune 596*6427ad5bSPeter Brune #undef __FUNCT__ 597*6427ad5bSPeter Brune #define __FUNCT__ "DMSNESSetBlockFunction" 598*6427ad5bSPeter Brune /*@C 599*6427ad5bSPeter Brune DMSNESSetBlockFunction - set SNES residual evaluation function 600*6427ad5bSPeter Brune 601*6427ad5bSPeter Brune Not Collective 602*6427ad5bSPeter Brune 603*6427ad5bSPeter Brune Input Arguments: 604*6427ad5bSPeter Brune + dm - DM to be used with SNES 605*6427ad5bSPeter Brune . func - residual evaluation function, see SNESSetFunction() for calling sequence 606*6427ad5bSPeter Brune - ctx - context for residual evaluation 607*6427ad5bSPeter Brune 608*6427ad5bSPeter Brune Level: developer 609*6427ad5bSPeter Brune 610*6427ad5bSPeter Brune Note: 611*6427ad5bSPeter Brune Mostly for use in DM implementations and transferred to a block function rather than being called from here. 612*6427ad5bSPeter Brune 613*6427ad5bSPeter Brune .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian() 614*6427ad5bSPeter Brune @*/ 615*6427ad5bSPeter Brune PetscErrorCode DMSNESSetBlockFunction(DM dm,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 616*6427ad5bSPeter Brune { 617*6427ad5bSPeter Brune PetscErrorCode ierr; 618*6427ad5bSPeter Brune SNESDM sdm; 619*6427ad5bSPeter Brune 620*6427ad5bSPeter Brune PetscFunctionBegin; 621*6427ad5bSPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 622*6427ad5bSPeter Brune ierr = DMSNESGetContextWrite(dm,&sdm);CHKERRQ(ierr); 623*6427ad5bSPeter Brune if (func) sdm->computeblockfunction = func; 624*6427ad5bSPeter Brune if (ctx) sdm->blockfunctionctx = ctx; 625*6427ad5bSPeter Brune PetscFunctionReturn(0); 626*6427ad5bSPeter Brune } 627*6427ad5bSPeter Brune 628*6427ad5bSPeter Brune #undef __FUNCT__ 629*6427ad5bSPeter Brune #define __FUNCT__ "DMSNESGetBlockFunction" 630*6427ad5bSPeter Brune /*@C 631*6427ad5bSPeter Brune DMSNESGetBlockFunction - get SNES residual evaluation function 632*6427ad5bSPeter Brune 633*6427ad5bSPeter Brune Not Collective 634*6427ad5bSPeter Brune 635*6427ad5bSPeter Brune Input Argument: 636*6427ad5bSPeter Brune . dm - DM to be used with SNES 637*6427ad5bSPeter Brune 638*6427ad5bSPeter Brune Output Arguments: 639*6427ad5bSPeter Brune + func - residual evaluation function, see SNESSetFunction() for calling sequence 640*6427ad5bSPeter Brune - ctx - context for residual evaluation 641*6427ad5bSPeter Brune 642*6427ad5bSPeter Brune Level: developer 643*6427ad5bSPeter Brune 644*6427ad5bSPeter Brune .seealso: DMSNESSetContext(), DMSNESSetFunction(), SNESSetFunction() 645*6427ad5bSPeter Brune @*/ 646*6427ad5bSPeter Brune PetscErrorCode DMSNESGetBlockFunction(DM dm,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 647*6427ad5bSPeter Brune { 648*6427ad5bSPeter Brune PetscErrorCode ierr; 649*6427ad5bSPeter Brune SNESDM sdm; 650*6427ad5bSPeter Brune 651*6427ad5bSPeter Brune PetscFunctionBegin; 652*6427ad5bSPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 653*6427ad5bSPeter Brune ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 654*6427ad5bSPeter Brune if (func) *func = sdm->computeblockfunction; 655*6427ad5bSPeter Brune if (ctx) *ctx = sdm->blockfunctionctx; 656*6427ad5bSPeter Brune PetscFunctionReturn(0); 657*6427ad5bSPeter Brune } 658*6427ad5bSPeter Brune 659*6427ad5bSPeter Brune 660*6427ad5bSPeter Brune #undef __FUNCT__ 661*6427ad5bSPeter Brune #define __FUNCT__ "DMSNESSetBlockJacobian" 662*6427ad5bSPeter Brune /*@C 663*6427ad5bSPeter Brune DMSNESSetJacobian - set SNES Jacobian evaluation function 664*6427ad5bSPeter Brune 665*6427ad5bSPeter Brune Not Collective 666*6427ad5bSPeter Brune 667*6427ad5bSPeter Brune Input Argument: 668*6427ad5bSPeter Brune + dm - DM to be used with SNES 669*6427ad5bSPeter Brune . func - Jacobian evaluation function, see SNESSetJacobian() for calling sequence 670*6427ad5bSPeter Brune - ctx - context for residual evaluation 671*6427ad5bSPeter Brune 672*6427ad5bSPeter Brune Level: advanced 673*6427ad5bSPeter Brune 674*6427ad5bSPeter Brune Note: 675*6427ad5bSPeter Brune Mostly for use in DM implementations and transferred to a block function rather than being called from here. 676*6427ad5bSPeter Brune 677*6427ad5bSPeter Brune .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESGetJacobian(), SNESSetJacobian() 678*6427ad5bSPeter Brune @*/ 679*6427ad5bSPeter Brune PetscErrorCode DMSNESSetBlockJacobian(DM dm,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 680*6427ad5bSPeter Brune { 681*6427ad5bSPeter Brune PetscErrorCode ierr; 682*6427ad5bSPeter Brune SNESDM sdm; 683*6427ad5bSPeter Brune 684*6427ad5bSPeter Brune PetscFunctionBegin; 685*6427ad5bSPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 686*6427ad5bSPeter Brune ierr = DMSNESGetContextWrite(dm,&sdm);CHKERRQ(ierr); 687*6427ad5bSPeter Brune if (func) sdm->computeblockjacobian = func; 688*6427ad5bSPeter Brune if (ctx) sdm->blockjacobianctx = ctx; 689*6427ad5bSPeter Brune PetscFunctionReturn(0); 690*6427ad5bSPeter Brune } 691*6427ad5bSPeter Brune 692*6427ad5bSPeter Brune #undef __FUNCT__ 693*6427ad5bSPeter Brune #define __FUNCT__ "DMSNESGetBlockJacobian" 694*6427ad5bSPeter Brune /*@C 695*6427ad5bSPeter Brune DMSNESGetBlockJacobian - get SNES Jacobian evaluation function 696*6427ad5bSPeter Brune 697*6427ad5bSPeter Brune Not Collective 698*6427ad5bSPeter Brune 699*6427ad5bSPeter Brune Input Argument: 700*6427ad5bSPeter Brune . dm - DM to be used with SNES 701*6427ad5bSPeter Brune 702*6427ad5bSPeter Brune Output Arguments: 703*6427ad5bSPeter Brune + func - Jacobian evaluation function, see SNESSetJacobian() for calling sequence 704*6427ad5bSPeter Brune - ctx - context for residual evaluation 705*6427ad5bSPeter Brune 706*6427ad5bSPeter Brune Level: advanced 707*6427ad5bSPeter Brune 708*6427ad5bSPeter Brune .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian() 709*6427ad5bSPeter Brune @*/ 710*6427ad5bSPeter Brune PetscErrorCode DMSNESGetBlockJacobian(DM dm,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 711*6427ad5bSPeter Brune { 712*6427ad5bSPeter Brune PetscErrorCode ierr; 713*6427ad5bSPeter Brune SNESDM sdm; 714*6427ad5bSPeter Brune 715*6427ad5bSPeter Brune PetscFunctionBegin; 716*6427ad5bSPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 717*6427ad5bSPeter Brune ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 718*6427ad5bSPeter Brune if (func) *func = sdm->computeblockjacobian; 719*6427ad5bSPeter Brune if (ctx) *ctx = sdm->blockjacobianctx; 720*6427ad5bSPeter Brune PetscFunctionReturn(0); 721*6427ad5bSPeter Brune } 722