xref: /petsc/src/snes/utils/dmsnes.c (revision be95d8f1844f2f8de343ad9c31bb253bac1e0696)
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__
522c6f798SBarry Smith #define __FUNCT__ "DMSNESDestroy"
622c6f798SBarry Smith static PetscErrorCode DMSNESDestroy(DMSNES *kdm)
76cab3a1bSJed Brown {
86cab3a1bSJed Brown   PetscErrorCode ierr;
96cab3a1bSJed Brown 
106cab3a1bSJed Brown   PetscFunctionBegin;
1122c6f798SBarry Smith   if (!*kdm) PetscFunctionReturn(0);
1222c6f798SBarry Smith   PetscValidHeaderSpecific((*kdm),DMSNES_CLASSID,1);
1322c6f798SBarry Smith   if (--((PetscObject)(*kdm))->refct > 0) {*kdm = 0; PetscFunctionReturn(0);}
1422c6f798SBarry Smith   if ((*kdm)->ops->destroy) {ierr = ((*kdm)->ops->destroy)(*kdm);CHKERRQ(ierr);}
1522c6f798SBarry Smith   ierr = PetscHeaderDestroy(kdm);CHKERRQ(ierr);
1622c6f798SBarry Smith   PetscFunctionReturn(0);
1722c6f798SBarry Smith }
1822c6f798SBarry Smith 
1922c6f798SBarry Smith #undef __FUNCT__
202d53ad75SBarry Smith #define __FUNCT__ "DMSNESLoad"
212d53ad75SBarry Smith PetscErrorCode DMSNESLoad(DMSNES kdm,PetscViewer viewer)
222d53ad75SBarry Smith {
232d53ad75SBarry Smith   PetscErrorCode ierr;
242d53ad75SBarry Smith 
252d53ad75SBarry Smith   PetscFunctionBegin;
262d53ad75SBarry Smith   ierr = PetscViewerBinaryRead(viewer,&kdm->ops->computefunction,1,PETSC_FUNCTION);CHKERRQ(ierr);
272d53ad75SBarry Smith   ierr = PetscViewerBinaryRead(viewer,&kdm->ops->computejacobian,1,PETSC_FUNCTION);CHKERRQ(ierr);
282d53ad75SBarry Smith   PetscFunctionReturn(0);
292d53ad75SBarry Smith }
302d53ad75SBarry Smith 
312d53ad75SBarry Smith #undef __FUNCT__
322d53ad75SBarry Smith #define __FUNCT__ "DMSNESView"
332d53ad75SBarry Smith PetscErrorCode DMSNESView(DMSNES kdm,PetscViewer viewer)
342d53ad75SBarry Smith {
352d53ad75SBarry Smith   PetscErrorCode ierr;
362d53ad75SBarry Smith   PetscBool      isascii,isbinary;
372d53ad75SBarry Smith 
382d53ad75SBarry Smith   PetscFunctionBegin;
392d53ad75SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
402d53ad75SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
412d53ad75SBarry Smith   if (isascii) {
42c7a10e08SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
432d53ad75SBarry Smith     const char *fname;
442d53ad75SBarry Smith 
452d53ad75SBarry Smith     ierr = PetscFPTFind(kdm->ops->computefunction,&fname);CHKERRQ(ierr);
462d53ad75SBarry Smith     if (fname) {
472d53ad75SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"Function used by SNES: %s\n",fname);CHKERRQ(ierr);
482d53ad75SBarry Smith     }
492d53ad75SBarry Smith     ierr = PetscFPTFind(kdm->ops->computejacobian,&fname);CHKERRQ(ierr);
502d53ad75SBarry Smith     if (fname) {
512d53ad75SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"Jacobian function used by SNES: %s\n",fname);CHKERRQ(ierr);
522d53ad75SBarry Smith     }
53c7a10e08SBarry Smith #endif
542d53ad75SBarry Smith   } else if (isbinary) {
553964eb88SJed Brown     struct {
563964eb88SJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
579200755eSBarry Smith     } funcstruct;
589200755eSBarry Smith     struct {
593964eb88SJed Brown       PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
609200755eSBarry Smith     } jacstruct;
619200755eSBarry Smith     funcstruct.func = kdm->ops->computefunction;
629200755eSBarry Smith     jacstruct.jac   = kdm->ops->computejacobian;
639200755eSBarry Smith     ierr = PetscViewerBinaryWrite(viewer,&funcstruct,1,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr);
649200755eSBarry Smith     ierr = PetscViewerBinaryWrite(viewer,&jacstruct,1,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr);
652d53ad75SBarry Smith   }
662d53ad75SBarry Smith   PetscFunctionReturn(0);
672d53ad75SBarry Smith }
682d53ad75SBarry Smith 
692d53ad75SBarry Smith #undef __FUNCT__
7022c6f798SBarry Smith #define __FUNCT__ "DMSNESCreate"
7122c6f798SBarry Smith static PetscErrorCode DMSNESCreate(MPI_Comm comm,DMSNES *kdm)
7222c6f798SBarry Smith {
7322c6f798SBarry Smith   PetscErrorCode ierr;
7422c6f798SBarry Smith 
7522c6f798SBarry Smith   PetscFunctionBegin;
76607a6623SBarry Smith   ierr = SNESInitializePackage();CHKERRQ(ierr);
7767c2884eSBarry Smith   ierr = PetscHeaderCreate(*kdm, _p_DMSNES, struct _DMSNESOps, DMSNES_CLASSID,  "DMSNES", "DMSNES", "DMSNES", comm, DMSNESDestroy, DMSNESView);CHKERRQ(ierr);
7822c6f798SBarry Smith   ierr = PetscMemzero((*kdm)->ops, sizeof(struct _DMSNESOps));CHKERRQ(ierr);
796cab3a1bSJed Brown   PetscFunctionReturn(0);
806cab3a1bSJed Brown }
816cab3a1bSJed Brown 
826cab3a1bSJed Brown #undef __FUNCT__
83942e3340SBarry Smith #define __FUNCT__ "DMCoarsenHook_DMSNES"
84942e3340SBarry Smith /* Attaches the DMSNES to the coarse level.
856cab3a1bSJed Brown  * Under what conditions should we copy versus duplicate?
866cab3a1bSJed Brown  */
87942e3340SBarry Smith static PetscErrorCode DMCoarsenHook_DMSNES(DM dm,DM dmc,void *ctx)
886cab3a1bSJed Brown {
896cab3a1bSJed Brown   PetscErrorCode ierr;
906cab3a1bSJed Brown 
916cab3a1bSJed Brown   PetscFunctionBegin;
92942e3340SBarry Smith   ierr = DMCopyDMSNES(dm,dmc);CHKERRQ(ierr);
936cab3a1bSJed Brown   PetscFunctionReturn(0);
946cab3a1bSJed Brown }
956cab3a1bSJed Brown 
966cab3a1bSJed Brown #undef __FUNCT__
97942e3340SBarry Smith #define __FUNCT__ "DMRestrictHook_DMSNES"
98dfe15315SJed Brown /* This could restrict auxiliary information to the coarse level.
99caa4e7f2SJed Brown  */
100942e3340SBarry Smith static PetscErrorCode DMRestrictHook_DMSNES(DM dm,Mat Restrict,Vec rscale,Mat Inject,DM dmc,void *ctx)
101caa4e7f2SJed Brown {
102caa4e7f2SJed Brown 
103caa4e7f2SJed Brown   PetscFunctionBegin;
104caa4e7f2SJed Brown   PetscFunctionReturn(0);
105caa4e7f2SJed Brown }
106caa4e7f2SJed Brown 
107caa4e7f2SJed Brown #undef __FUNCT__
108be081cd6SPeter Brune #define __FUNCT__ "DMSubDomainHook_DMSNES"
109be081cd6SPeter Brune /* Attaches the DMSNES to the subdomain. */
110be081cd6SPeter Brune static PetscErrorCode DMSubDomainHook_DMSNES(DM dm,DM subdm,void *ctx)
111be081cd6SPeter Brune {
112be081cd6SPeter Brune   PetscErrorCode ierr;
113be081cd6SPeter Brune 
114be081cd6SPeter Brune   PetscFunctionBegin;
115be081cd6SPeter Brune   ierr = DMCopyDMSNES(dm,subdm);CHKERRQ(ierr);
116be081cd6SPeter Brune   PetscFunctionReturn(0);
117be081cd6SPeter Brune }
118be081cd6SPeter Brune 
119be081cd6SPeter Brune #undef __FUNCT__
120be081cd6SPeter Brune #define __FUNCT__ "DMSubDomainRestrictHook_DMSNES"
121be081cd6SPeter Brune /* This could restrict auxiliary information to the coarse level.
122be081cd6SPeter Brune  */
123be081cd6SPeter Brune static PetscErrorCode DMSubDomainRestrictHook_DMSNES(DM dm,VecScatter gscat,VecScatter lscat,DM subdm,void *ctx)
124be081cd6SPeter Brune {
125be081cd6SPeter Brune 
126be081cd6SPeter Brune   PetscFunctionBegin;
127be081cd6SPeter Brune   PetscFunctionReturn(0);
128be081cd6SPeter Brune }
129be081cd6SPeter Brune 
130be081cd6SPeter Brune #undef __FUNCT__
131942e3340SBarry Smith #define __FUNCT__ "DMRefineHook_DMSNES"
132942e3340SBarry Smith static PetscErrorCode DMRefineHook_DMSNES(DM dm,DM dmf,void *ctx)
13303a0fabfSPeter Brune {
13403a0fabfSPeter Brune   PetscErrorCode ierr;
13503a0fabfSPeter Brune 
13603a0fabfSPeter Brune   PetscFunctionBegin;
137942e3340SBarry Smith   ierr = DMCopyDMSNES(dm,dmf);CHKERRQ(ierr);
13803a0fabfSPeter Brune   PetscFunctionReturn(0);
13903a0fabfSPeter Brune }
14003a0fabfSPeter Brune 
14103a0fabfSPeter Brune #undef __FUNCT__
142942e3340SBarry Smith #define __FUNCT__ "DMInterpolateHook_DMSNES"
14303a0fabfSPeter Brune /* This could restrict auxiliary information to the coarse level.
14403a0fabfSPeter Brune  */
145942e3340SBarry Smith static PetscErrorCode DMInterpolateHook_DMSNES(DM dm,Mat Interp,DM dmf,void *ctx)
14603a0fabfSPeter Brune {
14703a0fabfSPeter Brune 
14803a0fabfSPeter Brune   PetscFunctionBegin;
14903a0fabfSPeter Brune   PetscFunctionReturn(0);
15003a0fabfSPeter Brune }
15103a0fabfSPeter Brune 
15203a0fabfSPeter Brune #undef __FUNCT__
15322c6f798SBarry Smith #define __FUNCT__ "DMSNESCopy"
15422c6f798SBarry Smith /*@C
15522c6f798SBarry Smith    DMSNESCopy - copies the information in a DMSNES to another DMSNES
15622c6f798SBarry Smith 
15722c6f798SBarry Smith    Not Collective
15822c6f798SBarry Smith 
15922c6f798SBarry Smith    Input Argument:
16022c6f798SBarry Smith +  kdm - Original DMSNES
16122c6f798SBarry Smith -  nkdm - DMSNES to receive the data, should have been created with DMSNESCreate()
16222c6f798SBarry Smith 
16322c6f798SBarry Smith    Level: developer
16422c6f798SBarry Smith 
16522c6f798SBarry Smith .seealso: DMSNESCreate(), DMSNESDestroy()
16622c6f798SBarry Smith @*/
16722c6f798SBarry Smith PetscErrorCode DMSNESCopy(DMSNES kdm,DMSNES nkdm)
16822c6f798SBarry Smith {
16922c6f798SBarry Smith   PetscErrorCode ierr;
17022c6f798SBarry Smith 
17122c6f798SBarry Smith   PetscFunctionBegin;
17222c6f798SBarry Smith   PetscValidHeaderSpecific(kdm,DMSNES_CLASSID,1);
17322c6f798SBarry Smith   PetscValidHeaderSpecific(nkdm,DMSNES_CLASSID,2);
17422c6f798SBarry Smith   nkdm->ops->computefunction  = kdm->ops->computefunction;
1752bc4d0c4SPeter Brune   nkdm->ops->computejacobian  = kdm->ops->computejacobian;
17622c6f798SBarry Smith   nkdm->ops->computegs        = kdm->ops->computegs;
17722c6f798SBarry Smith   nkdm->ops->computeobjective = kdm->ops->computeobjective;
17822c6f798SBarry Smith   nkdm->ops->computepjacobian = kdm->ops->computepjacobian;
17922c6f798SBarry Smith   nkdm->ops->computepfunction = kdm->ops->computepfunction;
18022c6f798SBarry Smith   nkdm->ops->destroy          = kdm->ops->destroy;
18122c6f798SBarry Smith   nkdm->ops->duplicate        = kdm->ops->duplicate;
18222c6f798SBarry Smith 
18322c6f798SBarry Smith   nkdm->functionctx  = kdm->functionctx;
18422c6f798SBarry Smith   nkdm->gsctx        = kdm->gsctx;
18522c6f798SBarry Smith   nkdm->pctx         = kdm->pctx;
18622c6f798SBarry Smith   nkdm->jacobianctx  = kdm->jacobianctx;
18722c6f798SBarry Smith   nkdm->objectivectx = kdm->objectivectx;
18822c6f798SBarry Smith   nkdm->data         = kdm->data;
18922c6f798SBarry Smith 
19022c6f798SBarry Smith   /*
19122c6f798SBarry Smith   nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0];
19222c6f798SBarry Smith   nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1];
19322c6f798SBarry Smith   nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2];
19422c6f798SBarry Smith   */
19522c6f798SBarry Smith 
19622c6f798SBarry Smith   /* implementation specific copy hooks */
19722c6f798SBarry Smith   if (kdm->ops->duplicate) {ierr = (*kdm->ops->duplicate)(kdm,nkdm);CHKERRQ(ierr);}
19822c6f798SBarry Smith   PetscFunctionReturn(0);
19922c6f798SBarry Smith }
20022c6f798SBarry Smith 
20122c6f798SBarry Smith #undef __FUNCT__
202942e3340SBarry Smith #define __FUNCT__ "DMGetDMSNES"
2036cab3a1bSJed Brown /*@C
204942e3340SBarry Smith    DMGetDMSNES - get read-only private DMSNES context from a DM
2056cab3a1bSJed Brown 
2066cab3a1bSJed Brown    Not Collective
2076cab3a1bSJed Brown 
2086cab3a1bSJed Brown    Input Argument:
2096cab3a1bSJed Brown .  dm - DM to be used with SNES
2106cab3a1bSJed Brown 
2116cab3a1bSJed Brown    Output Argument:
212942e3340SBarry Smith .  snesdm - private DMSNES context
2136cab3a1bSJed Brown 
2146cab3a1bSJed Brown    Level: developer
2156cab3a1bSJed Brown 
2166cab3a1bSJed Brown    Notes:
217942e3340SBarry Smith    Use DMGetDMSNESWrite() if write access is needed. The DMSNESSetXXX API should be used wherever possible.
2186cab3a1bSJed Brown 
219942e3340SBarry Smith .seealso: DMGetDMSNESWrite()
2206cab3a1bSJed Brown @*/
221942e3340SBarry Smith PetscErrorCode DMGetDMSNES(DM dm,DMSNES *snesdm)
2226cab3a1bSJed Brown {
2236cab3a1bSJed Brown   PetscErrorCode ierr;
2246cab3a1bSJed Brown 
2256cab3a1bSJed Brown   PetscFunctionBegin;
2266cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
227b4615a05SBarry Smith   *snesdm = (DMSNES) dm->dmsnes;
22822c6f798SBarry Smith   if (!*snesdm) {
229942e3340SBarry Smith     ierr = PetscInfo(dm,"Creating new DMSNES\n");CHKERRQ(ierr);
230ce94432eSBarry Smith     ierr = DMSNESCreate(PetscObjectComm((PetscObject)dm),snesdm);CHKERRQ(ierr);
2311aa26658SKarl Rupp 
232b4615a05SBarry Smith     dm->dmsnes = (PetscObject) *snesdm;
2331aa26658SKarl Rupp 
2340298fd71SBarry Smith     ierr = DMCoarsenHookAdd(dm,DMCoarsenHook_DMSNES,DMRestrictHook_DMSNES,NULL);CHKERRQ(ierr);
2350298fd71SBarry Smith     ierr = DMRefineHookAdd(dm,DMRefineHook_DMSNES,DMInterpolateHook_DMSNES,NULL);CHKERRQ(ierr);
2360298fd71SBarry Smith     ierr = DMSubDomainHookAdd(dm,DMSubDomainHook_DMSNES,DMSubDomainRestrictHook_DMSNES,NULL);CHKERRQ(ierr);
2376cab3a1bSJed Brown   }
2386cab3a1bSJed Brown   PetscFunctionReturn(0);
2396cab3a1bSJed Brown }
2406cab3a1bSJed Brown 
2416cab3a1bSJed Brown #undef __FUNCT__
242942e3340SBarry Smith #define __FUNCT__ "DMGetDMSNESWrite"
2436cab3a1bSJed Brown /*@C
244942e3340SBarry Smith    DMGetDMSNESWrite - get write access to private DMSNES context from a DM
2456cab3a1bSJed Brown 
2466cab3a1bSJed Brown    Not Collective
2476cab3a1bSJed Brown 
2486cab3a1bSJed Brown    Input Argument:
2496cab3a1bSJed Brown .  dm - DM to be used with SNES
2506cab3a1bSJed Brown 
2516cab3a1bSJed Brown    Output Argument:
252942e3340SBarry Smith .  snesdm - private DMSNES context
2536cab3a1bSJed Brown 
2546cab3a1bSJed Brown    Level: developer
2556cab3a1bSJed Brown 
256942e3340SBarry Smith .seealso: DMGetDMSNES()
2576cab3a1bSJed Brown @*/
258942e3340SBarry Smith PetscErrorCode DMGetDMSNESWrite(DM dm,DMSNES *snesdm)
2596cab3a1bSJed Brown {
2606cab3a1bSJed Brown   PetscErrorCode ierr;
261942e3340SBarry Smith   DMSNES         sdm;
2626cab3a1bSJed Brown 
2636cab3a1bSJed Brown   PetscFunctionBegin;
2646cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
265942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
2666cab3a1bSJed Brown   if (!sdm->originaldm) sdm->originaldm = dm;
2676cab3a1bSJed Brown   if (sdm->originaldm != dm) {  /* Copy on write */
268b4615a05SBarry Smith     DMSNES oldsdm = sdm;
269942e3340SBarry Smith     ierr       = PetscInfo(dm,"Copying DMSNES due to write\n");CHKERRQ(ierr);
270ce94432eSBarry Smith     ierr       = DMSNESCreate(PetscObjectComm((PetscObject)dm),&sdm);CHKERRQ(ierr);
27122c6f798SBarry Smith     ierr       = DMSNESCopy(oldsdm,sdm);CHKERRQ(ierr);
272b4615a05SBarry Smith     ierr       = DMSNESDestroy((DMSNES*)&dm->dmsnes);CHKERRQ(ierr);
273b4615a05SBarry Smith     dm->dmsnes = (PetscObject)sdm;
2746cab3a1bSJed Brown   }
2756cab3a1bSJed Brown   *snesdm = sdm;
2766cab3a1bSJed Brown   PetscFunctionReturn(0);
2776cab3a1bSJed Brown }
2786cab3a1bSJed Brown 
2796cab3a1bSJed Brown #undef __FUNCT__
280942e3340SBarry Smith #define __FUNCT__ "DMCopyDMSNES"
2816cab3a1bSJed Brown /*@C
282942e3340SBarry Smith    DMCopyDMSNES - copies a DM context to a new DM
2836cab3a1bSJed Brown 
2846cab3a1bSJed Brown    Logically Collective
2856cab3a1bSJed Brown 
2866cab3a1bSJed Brown    Input Arguments:
2876cab3a1bSJed Brown +  dmsrc - DM to obtain context from
2886cab3a1bSJed Brown -  dmdest - DM to add context to
2896cab3a1bSJed Brown 
2906cab3a1bSJed Brown    Level: developer
2916cab3a1bSJed Brown 
2926cab3a1bSJed Brown    Note:
2936cab3a1bSJed Brown    The context is copied by reference. This function does not ensure that a context exists.
2946cab3a1bSJed Brown 
295942e3340SBarry Smith .seealso: DMGetDMSNES(), SNESSetDM()
2966cab3a1bSJed Brown @*/
297942e3340SBarry Smith PetscErrorCode DMCopyDMSNES(DM dmsrc,DM dmdest)
2986cab3a1bSJed Brown {
2996cab3a1bSJed Brown   PetscErrorCode ierr;
3006cab3a1bSJed Brown 
3016cab3a1bSJed Brown   PetscFunctionBegin;
3026cab3a1bSJed Brown   PetscValidHeaderSpecific(dmsrc,DM_CLASSID,1);
3036cab3a1bSJed Brown   PetscValidHeaderSpecific(dmdest,DM_CLASSID,2);
304b4615a05SBarry Smith   ierr = DMSNESDestroy((DMSNES*)&dmdest->dmsnes);CHKERRQ(ierr);
3051aa26658SKarl Rupp 
306b4615a05SBarry Smith   dmdest->dmsnes = dmsrc->dmsnes;
3071aa26658SKarl Rupp 
308b4615a05SBarry Smith   ierr = PetscObjectReference(dmdest->dmsnes);CHKERRQ(ierr);
3090298fd71SBarry Smith   ierr = DMCoarsenHookAdd(dmdest,DMCoarsenHook_DMSNES,NULL,NULL);CHKERRQ(ierr);
3100298fd71SBarry Smith   ierr = DMRefineHookAdd(dmdest,DMRefineHook_DMSNES,NULL,NULL);CHKERRQ(ierr);
3110298fd71SBarry Smith   ierr = DMSubDomainHookAdd(dmdest,DMSubDomainHook_DMSNES,DMSubDomainRestrictHook_DMSNES,NULL);CHKERRQ(ierr);
3126cab3a1bSJed Brown   PetscFunctionReturn(0);
3136cab3a1bSJed Brown }
3146cab3a1bSJed Brown 
3156cab3a1bSJed Brown #undef __FUNCT__
3166cab3a1bSJed Brown #define __FUNCT__ "DMSNESSetFunction"
3176cab3a1bSJed Brown /*@C
3186cab3a1bSJed Brown    DMSNESSetFunction - set SNES residual evaluation function
3196cab3a1bSJed Brown 
3206cab3a1bSJed Brown    Not Collective
3216cab3a1bSJed Brown 
3226cab3a1bSJed Brown    Input Arguments:
3236cab3a1bSJed Brown +  dm - DM to be used with SNES
324f8b49ee9SBarry Smith .  f - residual evaluation function; see SNESFunction for details
3256cab3a1bSJed Brown -  ctx - context for residual evaluation
3266cab3a1bSJed Brown 
3276cab3a1bSJed Brown    Level: advanced
3286cab3a1bSJed Brown 
3296cab3a1bSJed Brown    Note:
3306cab3a1bSJed Brown    SNESSetFunction() is normally used, but it calls this function internally because the user context is actually
3316cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
3326cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
3336cab3a1bSJed Brown 
334bf388a1fSBarry Smith .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian(), SNESFunction
3356cab3a1bSJed Brown @*/
336f8b49ee9SBarry Smith PetscErrorCode DMSNESSetFunction(DM dm,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
3376cab3a1bSJed Brown {
3386cab3a1bSJed Brown   PetscErrorCode ierr;
339942e3340SBarry Smith   DMSNES         sdm;
3406cab3a1bSJed Brown 
3416cab3a1bSJed Brown   PetscFunctionBegin;
3426cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
343f8b49ee9SBarry Smith   if (f || ctx) {
344942e3340SBarry Smith     ierr = DMGetDMSNESWrite(dm,&sdm);CHKERRQ(ierr);
345fdaff8d6SPeter Brune   }
346f8b49ee9SBarry Smith   if (f) sdm->ops->computefunction = f;
3476cab3a1bSJed Brown   if (ctx) sdm->functionctx = ctx;
3486cab3a1bSJed Brown   PetscFunctionReturn(0);
3496cab3a1bSJed Brown }
3506cab3a1bSJed Brown 
3516cab3a1bSJed Brown #undef __FUNCT__
3526cab3a1bSJed Brown #define __FUNCT__ "DMSNESGetFunction"
3536cab3a1bSJed Brown /*@C
3546cab3a1bSJed Brown    DMSNESGetFunction - get SNES residual evaluation function
3556cab3a1bSJed Brown 
3566cab3a1bSJed Brown    Not Collective
3576cab3a1bSJed Brown 
3586cab3a1bSJed Brown    Input Argument:
3596cab3a1bSJed Brown .  dm - DM to be used with SNES
3606cab3a1bSJed Brown 
3616cab3a1bSJed Brown    Output Arguments:
362f8b49ee9SBarry Smith +  f - residual evaluation function; see SNESFunction for details
3636cab3a1bSJed Brown -  ctx - context for residual evaluation
3646cab3a1bSJed Brown 
3656cab3a1bSJed Brown    Level: advanced
3666cab3a1bSJed Brown 
3676cab3a1bSJed Brown    Note:
3686cab3a1bSJed Brown    SNESGetFunction() is normally used, but it calls this function internally because the user context is actually
3696cab3a1bSJed Brown    associated with the DM.
3706cab3a1bSJed Brown 
371bf388a1fSBarry Smith .seealso: DMSNESSetContext(), DMSNESSetFunction(), SNESSetFunction(), SNESFunction
3726cab3a1bSJed Brown @*/
373f8b49ee9SBarry Smith PetscErrorCode DMSNESGetFunction(DM dm,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx)
3746cab3a1bSJed Brown {
3756cab3a1bSJed Brown   PetscErrorCode ierr;
376942e3340SBarry Smith   DMSNES         sdm;
3776cab3a1bSJed Brown 
3786cab3a1bSJed Brown   PetscFunctionBegin;
3796cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
380942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
381f8b49ee9SBarry Smith   if (f) *f = sdm->ops->computefunction;
3826cab3a1bSJed Brown   if (ctx) *ctx = sdm->functionctx;
3836cab3a1bSJed Brown   PetscFunctionReturn(0);
3846cab3a1bSJed Brown }
3856cab3a1bSJed Brown 
3866cab3a1bSJed Brown #undef __FUNCT__
3872a4ee8f2SPeter Brune #define __FUNCT__ "DMSNESSetObjective"
3882a4ee8f2SPeter Brune /*@C
389081a7dcdSPeter Brune    DMSNESSetObjective - set SNES objective evaluation function
3902a4ee8f2SPeter Brune 
3912a4ee8f2SPeter Brune    Not Collective
3922a4ee8f2SPeter Brune 
3932a4ee8f2SPeter Brune    Input Arguments:
3942a4ee8f2SPeter Brune +  dm - DM to be used with SNES
395f8b49ee9SBarry Smith .  obj - objective evaluation function; see SNESObjectiveFunction for details
3962a4ee8f2SPeter Brune -  ctx - context for residual evaluation
3972a4ee8f2SPeter Brune 
3982a4ee8f2SPeter Brune    Level: advanced
3992a4ee8f2SPeter Brune 
4002a4ee8f2SPeter Brune .seealso: DMSNESSetContext(), SNESGetObjective(), DMSNESSetFunction()
4012a4ee8f2SPeter Brune @*/
402f8b49ee9SBarry Smith PetscErrorCode DMSNESSetObjective(DM dm,PetscErrorCode (*obj)(SNES,Vec,PetscReal*,void*),void *ctx)
4032a4ee8f2SPeter Brune {
4042a4ee8f2SPeter Brune   PetscErrorCode ierr;
405942e3340SBarry Smith   DMSNES         sdm;
4062a4ee8f2SPeter Brune 
4072a4ee8f2SPeter Brune   PetscFunctionBegin;
4082a4ee8f2SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
409f8b49ee9SBarry Smith   if (obj || ctx) {
410942e3340SBarry Smith     ierr = DMGetDMSNESWrite(dm,&sdm);CHKERRQ(ierr);
411fdaff8d6SPeter Brune   }
412f8b49ee9SBarry Smith   if (obj) sdm->ops->computeobjective = obj;
4132a4ee8f2SPeter Brune   if (ctx) sdm->objectivectx = ctx;
4142a4ee8f2SPeter Brune   PetscFunctionReturn(0);
4152a4ee8f2SPeter Brune }
4162a4ee8f2SPeter Brune 
4172a4ee8f2SPeter Brune #undef __FUNCT__
4182a4ee8f2SPeter Brune #define __FUNCT__ "DMSNESGetObjective"
4192a4ee8f2SPeter Brune /*@C
4202a4ee8f2SPeter Brune    DMSNESGetObjective - get SNES objective evaluation function
4212a4ee8f2SPeter Brune 
4222a4ee8f2SPeter Brune    Not Collective
4232a4ee8f2SPeter Brune 
4242a4ee8f2SPeter Brune    Input Argument:
4252a4ee8f2SPeter Brune .  dm - DM to be used with SNES
4262a4ee8f2SPeter Brune 
4272a4ee8f2SPeter Brune    Output Arguments:
428f8b49ee9SBarry Smith +  obj- residual evaluation function; see SNESObjectiveFunction for details
4292a4ee8f2SPeter Brune -  ctx - context for residual evaluation
4302a4ee8f2SPeter Brune 
4312a4ee8f2SPeter Brune    Level: advanced
4322a4ee8f2SPeter Brune 
4332a4ee8f2SPeter Brune    Note:
4342a4ee8f2SPeter Brune    SNESGetFunction() is normally used, but it calls this function internally because the user context is actually
4352a4ee8f2SPeter Brune    associated with the DM.
4362a4ee8f2SPeter Brune 
4372a4ee8f2SPeter Brune .seealso: DMSNESSetContext(), DMSNESSetObjective(), SNESSetFunction()
4382a4ee8f2SPeter Brune @*/
439f8b49ee9SBarry Smith PetscErrorCode DMSNESGetObjective(DM dm,PetscErrorCode (**obj)(SNES,Vec,PetscReal*,void*),void **ctx)
4402a4ee8f2SPeter Brune {
4412a4ee8f2SPeter Brune   PetscErrorCode ierr;
442942e3340SBarry Smith   DMSNES         sdm;
4432a4ee8f2SPeter Brune 
4442a4ee8f2SPeter Brune   PetscFunctionBegin;
4452a4ee8f2SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
446942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
447f8b49ee9SBarry Smith   if (obj) *obj = sdm->ops->computeobjective;
4482a4ee8f2SPeter Brune   if (ctx) *ctx = sdm->objectivectx;
4492a4ee8f2SPeter Brune   PetscFunctionReturn(0);
4502a4ee8f2SPeter Brune }
4512a4ee8f2SPeter Brune 
4522a4ee8f2SPeter Brune #undef __FUNCT__
453*be95d8f1SBarry Smith #define __FUNCT__ "DMSNESSetNGS"
4546cab3a1bSJed Brown /*@C
455*be95d8f1SBarry Smith    DMSNESSetNGS - set SNES Gauss-Seidel relaxation function
4566cab3a1bSJed Brown 
4576cab3a1bSJed Brown    Not Collective
4586cab3a1bSJed Brown 
4596cab3a1bSJed Brown    Input Argument:
4606cab3a1bSJed Brown +  dm - DM to be used with SNES
461*be95d8f1SBarry Smith .  f  - relaxation function, see SNESGSFunction
4626cab3a1bSJed Brown -  ctx - context for residual evaluation
4636cab3a1bSJed Brown 
4646cab3a1bSJed Brown    Level: advanced
4656cab3a1bSJed Brown 
4666cab3a1bSJed Brown    Note:
467*be95d8f1SBarry Smith    SNESSetNGS() is normally used, but it calls this function internally because the user context is actually
4686cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
4696cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
4706cab3a1bSJed Brown 
471bf388a1fSBarry Smith .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian(), DMSNESSetFunction(), SNESGSFunction
4726cab3a1bSJed Brown @*/
473*be95d8f1SBarry Smith PetscErrorCode DMSNESSetNGS(DM dm,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
4746cab3a1bSJed Brown {
4756cab3a1bSJed Brown   PetscErrorCode ierr;
476942e3340SBarry Smith   DMSNES         sdm;
4776cab3a1bSJed Brown 
4786cab3a1bSJed Brown   PetscFunctionBegin;
4796cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
480*be95d8f1SBarry Smith   if (f || ctx) {
481942e3340SBarry Smith     ierr = DMGetDMSNESWrite(dm,&sdm);CHKERRQ(ierr);
482fdaff8d6SPeter Brune   }
483*be95d8f1SBarry Smith   if (f) sdm->ops->computegs = f;
4846cab3a1bSJed Brown   if (ctx) sdm->gsctx = ctx;
4856cab3a1bSJed Brown   PetscFunctionReturn(0);
4866cab3a1bSJed Brown }
4876cab3a1bSJed Brown 
4886cab3a1bSJed Brown #undef __FUNCT__
489*be95d8f1SBarry Smith #define __FUNCT__ "DMSNESGetNGS"
4906cab3a1bSJed Brown /*@C
491*be95d8f1SBarry Smith    DMSNESGetNGS - get SNES Gauss-Seidel relaxation function
4926cab3a1bSJed Brown 
4936cab3a1bSJed Brown    Not Collective
4946cab3a1bSJed Brown 
4956cab3a1bSJed Brown    Input Argument:
4966cab3a1bSJed Brown .  dm - DM to be used with SNES
4976cab3a1bSJed Brown 
4986cab3a1bSJed Brown    Output Arguments:
499*be95d8f1SBarry Smith +  f - relaxation function which performs Gauss-Seidel sweeps, see SNESGSFunction
5006cab3a1bSJed Brown -  ctx - context for residual evaluation
5016cab3a1bSJed Brown 
5026cab3a1bSJed Brown    Level: advanced
5036cab3a1bSJed Brown 
5046cab3a1bSJed Brown    Note:
505*be95d8f1SBarry Smith    SNESGetNGS() is normally used, but it calls this function internally because the user context is actually
5066cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
5076cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
5086cab3a1bSJed Brown 
509*be95d8f1SBarry Smith .seealso: DMSNESSetContext(), SNESGetNGS(), DMSNESGetJacobian(), DMSNESGetFunction(), SNESNGSFunction
5106cab3a1bSJed Brown @*/
511*be95d8f1SBarry Smith PetscErrorCode DMSNESGetNGS(DM dm,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx)
5126cab3a1bSJed Brown {
5136cab3a1bSJed Brown   PetscErrorCode ierr;
514942e3340SBarry Smith   DMSNES         sdm;
5156cab3a1bSJed Brown 
5166cab3a1bSJed Brown   PetscFunctionBegin;
5176cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
518942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
519*be95d8f1SBarry Smith   if (f) *f = sdm->ops->computegs;
5206cab3a1bSJed Brown   if (ctx) *ctx = sdm->gsctx;
5216cab3a1bSJed Brown   PetscFunctionReturn(0);
5226cab3a1bSJed Brown }
5236cab3a1bSJed Brown 
5246cab3a1bSJed Brown #undef __FUNCT__
5256cab3a1bSJed Brown #define __FUNCT__ "DMSNESSetJacobian"
5266cab3a1bSJed Brown /*@C
527ecfdb398SPeter Brune    DMSNESSetJacobian - set SNES Jacobian evaluation function
5286cab3a1bSJed Brown 
5296cab3a1bSJed Brown    Not Collective
5306cab3a1bSJed Brown 
5316cab3a1bSJed Brown    Input Argument:
5326cab3a1bSJed Brown +  dm - DM to be used with SNES
533f8b49ee9SBarry Smith .  J - Jacobian evaluation function
5346cab3a1bSJed Brown -  ctx - context for residual evaluation
5356cab3a1bSJed Brown 
5366cab3a1bSJed Brown    Level: advanced
5376cab3a1bSJed Brown 
5386cab3a1bSJed Brown    Note:
5396cab3a1bSJed Brown    SNESSetJacobian() is normally used, but it calls this function internally because the user context is actually
5406cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
5416cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
5426cab3a1bSJed Brown 
543bf388a1fSBarry Smith .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESGetJacobian(), SNESSetJacobian(), SNESJacobianFunction
5446cab3a1bSJed Brown @*/
545f8b49ee9SBarry Smith PetscErrorCode DMSNESSetJacobian(DM dm,PetscErrorCode (*J)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
5466cab3a1bSJed Brown {
5476cab3a1bSJed Brown   PetscErrorCode ierr;
548942e3340SBarry Smith   DMSNES         sdm;
5496cab3a1bSJed Brown 
5506cab3a1bSJed Brown   PetscFunctionBegin;
5516cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
552f8b49ee9SBarry Smith   if (J || ctx) {
553942e3340SBarry Smith     ierr = DMGetDMSNESWrite(dm,&sdm);CHKERRQ(ierr);
5541fdfe764SBarry Smith   }
555f8b49ee9SBarry Smith   if (J) sdm->ops->computejacobian = J;
5566cab3a1bSJed Brown   if (ctx) sdm->jacobianctx = ctx;
5576cab3a1bSJed Brown   PetscFunctionReturn(0);
5586cab3a1bSJed Brown }
5596cab3a1bSJed Brown 
5606cab3a1bSJed Brown #undef __FUNCT__
5616cab3a1bSJed Brown #define __FUNCT__ "DMSNESGetJacobian"
5626cab3a1bSJed Brown /*@C
563ecfdb398SPeter Brune    DMSNESGetJacobian - get SNES Jacobian evaluation function
5646cab3a1bSJed Brown 
5656cab3a1bSJed Brown    Not Collective
5666cab3a1bSJed Brown 
5676cab3a1bSJed Brown    Input Argument:
5686cab3a1bSJed Brown .  dm - DM to be used with SNES
5696cab3a1bSJed Brown 
5706cab3a1bSJed Brown    Output Arguments:
571f8b49ee9SBarry Smith +  J - Jacobian evaluation function; see SNESJacobianFunction for all calling sequence
5726cab3a1bSJed Brown -  ctx - context for residual evaluation
5736cab3a1bSJed Brown 
5746cab3a1bSJed Brown    Level: advanced
5756cab3a1bSJed Brown 
5766cab3a1bSJed Brown    Note:
5776cab3a1bSJed Brown    SNESGetJacobian() is normally used, but it calls this function internally because the user context is actually
5786cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
5796cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
5806cab3a1bSJed Brown 
581bf388a1fSBarry Smith .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian(), SNESJacobianFunction
5826cab3a1bSJed Brown @*/
583f8b49ee9SBarry Smith PetscErrorCode DMSNESGetJacobian(DM dm,PetscErrorCode (**J)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
5846cab3a1bSJed Brown {
5856cab3a1bSJed Brown   PetscErrorCode ierr;
586942e3340SBarry Smith   DMSNES         sdm;
5876cab3a1bSJed Brown 
5886cab3a1bSJed Brown   PetscFunctionBegin;
5896cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
590942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
591f8b49ee9SBarry Smith   if (J) *J = sdm->ops->computejacobian;
5926cab3a1bSJed Brown   if (ctx) *ctx = sdm->jacobianctx;
5936cab3a1bSJed Brown   PetscFunctionReturn(0);
5946cab3a1bSJed Brown }
5956cab3a1bSJed Brown 
5966cab3a1bSJed Brown #undef __FUNCT__
597e03ab78fSPeter Brune #define __FUNCT__ "DMSNESSetPicard"
598e03ab78fSPeter Brune /*@C
599e03ab78fSPeter Brune    DMSNESSetPicard - set SNES Picard iteration matrix and RHS evaluation functions.
600e03ab78fSPeter Brune 
601e03ab78fSPeter Brune    Not Collective
602e03ab78fSPeter Brune 
603e03ab78fSPeter Brune    Input Argument:
604e03ab78fSPeter Brune +  dm - DM to be used with SNES
605f8b49ee9SBarry Smith .  b - RHS evaluation function
606f8b49ee9SBarry Smith .  J - Picard matrix evaluation function
607e03ab78fSPeter Brune -  ctx - context for residual evaluation
608e03ab78fSPeter Brune 
609e03ab78fSPeter Brune    Level: advanced
610e03ab78fSPeter Brune 
611e03ab78fSPeter Brune .seealso: SNESSetPicard(), DMSNESSetFunction(), DMSNESSetJacobian()
612e03ab78fSPeter Brune @*/
613f8b49ee9SBarry Smith PetscErrorCode DMSNESSetPicard(DM dm,PetscErrorCode (*b)(SNES,Vec,Vec,void*),PetscErrorCode (*J)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
614e03ab78fSPeter Brune {
615e03ab78fSPeter Brune   PetscErrorCode ierr;
616942e3340SBarry Smith   DMSNES         sdm;
617e03ab78fSPeter Brune 
618e03ab78fSPeter Brune   PetscFunctionBegin;
619e03ab78fSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
620942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
621f8b49ee9SBarry Smith   if (b) sdm->ops->computepfunction = b;
622f8b49ee9SBarry Smith   if (J) sdm->ops->computepjacobian = J;
623e03ab78fSPeter Brune   if (ctx) sdm->pctx = ctx;
624e03ab78fSPeter Brune   PetscFunctionReturn(0);
625e03ab78fSPeter Brune }
626e03ab78fSPeter Brune 
6277971a8bfSPeter Brune #undef __FUNCT__
6287971a8bfSPeter Brune #define __FUNCT__ "DMSNESGetPicard"
6297971a8bfSPeter Brune /*@C
6307971a8bfSPeter Brune    DMSNESGetPicard - get SNES Picard iteration evaluation functions
6317971a8bfSPeter Brune 
6327971a8bfSPeter Brune    Not Collective
6337971a8bfSPeter Brune 
6347971a8bfSPeter Brune    Input Argument:
6357971a8bfSPeter Brune .  dm - DM to be used with SNES
6367971a8bfSPeter Brune 
6377971a8bfSPeter Brune    Output Arguments:
638f8b49ee9SBarry Smith +  b - RHS evaluation function; see SNESFunction for details
639f8b49ee9SBarry Smith .  J  - RHS evaluation function; see SNESJacobianFunction for detailsa
6407971a8bfSPeter Brune -  ctx - context for residual evaluation
6417971a8bfSPeter Brune 
6427971a8bfSPeter Brune    Level: advanced
6437971a8bfSPeter Brune 
6447971a8bfSPeter Brune .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian()
6457971a8bfSPeter Brune @*/
646f8b49ee9SBarry Smith PetscErrorCode DMSNESGetPicard(DM dm,PetscErrorCode (**b)(SNES,Vec,Vec,void*),PetscErrorCode (**J)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
6477971a8bfSPeter Brune {
6487971a8bfSPeter Brune   PetscErrorCode ierr;
649942e3340SBarry Smith   DMSNES         sdm;
6507971a8bfSPeter Brune 
6517971a8bfSPeter Brune   PetscFunctionBegin;
6527971a8bfSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
653942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
654f8b49ee9SBarry Smith   if (b) *b = sdm->ops->computepfunction;
655f8b49ee9SBarry Smith   if (J) *J = sdm->ops->computepjacobian;
6567971a8bfSPeter Brune   if (ctx) *ctx = sdm->pctx;
6577971a8bfSPeter Brune   PetscFunctionReturn(0);
6587971a8bfSPeter Brune }
659