xref: /petsc/src/ts/utils/dmlocalts.c (revision af0996ce37bc06907c37d8d91773840993d61e62)
1*af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
2*af0996ceSBarry Smith #include <petsc/private/tsimpl.h>   /*I "petscts.h" I*/
3d433e6cbSMatthew G. Knepley 
4d433e6cbSMatthew G. Knepley typedef struct {
5d433e6cbSMatthew G. Knepley   PetscErrorCode (*ifunctionlocal)(DM,PetscReal,Vec,Vec,Vec,void*);
6d433e6cbSMatthew G. Knepley   PetscErrorCode (*ijacobianlocal)(DM,PetscReal,Vec,Vec,PetscReal,Mat,Mat,void*);
7d433e6cbSMatthew G. Knepley   PetscErrorCode (*rhsfunctionlocal)(DM,PetscReal,Vec,Vec,void*);
8d433e6cbSMatthew G. Knepley   void *ifunctionlocalctx;
9d433e6cbSMatthew G. Knepley   void *ijacobianlocalctx;
10d433e6cbSMatthew G. Knepley   void *rhsfunctionlocalctx;
11d433e6cbSMatthew G. Knepley } DMTS_Local;
12d433e6cbSMatthew G. Knepley 
13d433e6cbSMatthew G. Knepley #undef __FUNCT__
14d433e6cbSMatthew G. Knepley #define __FUNCT__ "DMTSDestroy_DMLocal"
15d433e6cbSMatthew G. Knepley static PetscErrorCode DMTSDestroy_DMLocal(DMTS tdm)
16d433e6cbSMatthew G. Knepley {
17d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
18d433e6cbSMatthew G. Knepley 
19d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
20d433e6cbSMatthew G. Knepley   ierr = PetscFree(tdm->data);CHKERRQ(ierr);
21d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
22d433e6cbSMatthew G. Knepley }
23d433e6cbSMatthew G. Knepley 
24d433e6cbSMatthew G. Knepley #undef __FUNCT__
25d433e6cbSMatthew G. Knepley #define __FUNCT__ "DMTSDuplicate_DMLocal"
26d433e6cbSMatthew G. Knepley static PetscErrorCode DMTSDuplicate_DMLocal(DMTS oldtdm, DMTS tdm)
27d433e6cbSMatthew G. Knepley {
28d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
29d433e6cbSMatthew G. Knepley 
30d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
31d433e6cbSMatthew G. Knepley   ierr = PetscNewLog(tdm, (DMTS_Local **) &tdm->data);CHKERRQ(ierr);
32d433e6cbSMatthew G. Knepley   if (oldtdm->data) {ierr = PetscMemcpy(tdm->data, oldtdm->data, sizeof(DMTS_Local));CHKERRQ(ierr);}
33d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
34d433e6cbSMatthew G. Knepley }
35d433e6cbSMatthew G. Knepley 
36d433e6cbSMatthew G. Knepley #undef __FUNCT__
37d433e6cbSMatthew G. Knepley #define __FUNCT__ "DMLocalTSGetContext"
38d433e6cbSMatthew G. Knepley static PetscErrorCode DMLocalTSGetContext(DM dm, DMTS tdm, DMTS_Local **dmlocalts)
39d433e6cbSMatthew G. Knepley {
40d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
41d433e6cbSMatthew G. Knepley 
42d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
43d433e6cbSMatthew G. Knepley   *dmlocalts = NULL;
44d433e6cbSMatthew G. Knepley   if (!tdm->data) {
45d433e6cbSMatthew G. Knepley     ierr = PetscNewLog(dm, (DMTS_Local **) &tdm->data);CHKERRQ(ierr);
46d433e6cbSMatthew G. Knepley 
47d433e6cbSMatthew G. Knepley     tdm->ops->destroy   = DMTSDestroy_DMLocal;
48d433e6cbSMatthew G. Knepley     tdm->ops->duplicate = DMTSDuplicate_DMLocal;
49d433e6cbSMatthew G. Knepley   }
50d433e6cbSMatthew G. Knepley   *dmlocalts = (DMTS_Local *) tdm->data;
51d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
52d433e6cbSMatthew G. Knepley }
53d433e6cbSMatthew G. Knepley 
54d433e6cbSMatthew G. Knepley #undef __FUNCT__
55d433e6cbSMatthew G. Knepley #define __FUNCT__ "TSComputeIFunction_DMLocal"
56d433e6cbSMatthew G. Knepley static PetscErrorCode TSComputeIFunction_DMLocal(TS ts, PetscReal time, Vec X, Vec X_t, Vec F, void *ctx)
57d433e6cbSMatthew G. Knepley {
58d433e6cbSMatthew G. Knepley   DM             dm;
59d433e6cbSMatthew G. Knepley   Vec            locX, locX_t, locF;
60d433e6cbSMatthew G. Knepley   DMTS_Local    *dmlocalts = (DMTS_Local *) ctx;
61d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
62d433e6cbSMatthew G. Knepley 
63d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
64d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
65d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(X,VEC_CLASSID,3);
66d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(X_t,VEC_CLASSID,4);
67d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(F,VEC_CLASSID,5);
68d433e6cbSMatthew G. Knepley   ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
69d433e6cbSMatthew G. Knepley   ierr = DMGetLocalVector(dm, &locX);CHKERRQ(ierr);
70d433e6cbSMatthew G. Knepley   ierr = DMGetLocalVector(dm, &locX_t);CHKERRQ(ierr);
71d433e6cbSMatthew G. Knepley   ierr = DMGetLocalVector(dm, &locF);CHKERRQ(ierr);
72d433e6cbSMatthew G. Knepley   ierr = VecZeroEntries(locX);CHKERRQ(ierr);
73d433e6cbSMatthew G. Knepley   ierr = VecZeroEntries(locX_t);CHKERRQ(ierr);
74d433e6cbSMatthew G. Knepley   ierr = DMGlobalToLocalBegin(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr);
75d433e6cbSMatthew G. Knepley   ierr = DMGlobalToLocalEnd(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr);
76d433e6cbSMatthew G. Knepley   ierr = DMGlobalToLocalBegin(dm, X_t, INSERT_VALUES, locX_t);CHKERRQ(ierr);
77d433e6cbSMatthew G. Knepley   ierr = DMGlobalToLocalEnd(dm, X_t, INSERT_VALUES, locX_t);CHKERRQ(ierr);
78d433e6cbSMatthew G. Knepley   ierr = VecZeroEntries(locF);CHKERRQ(ierr);
79d433e6cbSMatthew G. Knepley   CHKMEMQ;
80d433e6cbSMatthew G. Knepley   ierr = (*dmlocalts->ifunctionlocal)(dm, time, locX, locX_t, locF, dmlocalts->ifunctionlocalctx);CHKERRQ(ierr);
81d433e6cbSMatthew G. Knepley   CHKMEMQ;
82d433e6cbSMatthew G. Knepley   ierr = VecZeroEntries(F);CHKERRQ(ierr);
83d433e6cbSMatthew G. Knepley   ierr = DMLocalToGlobalBegin(dm, locF, ADD_VALUES, F);CHKERRQ(ierr);
84d433e6cbSMatthew G. Knepley   ierr = DMLocalToGlobalEnd(dm, locF, ADD_VALUES, F);CHKERRQ(ierr);
85d433e6cbSMatthew G. Knepley   ierr = DMRestoreLocalVector(dm, &locX);CHKERRQ(ierr);
86d433e6cbSMatthew G. Knepley   ierr = DMRestoreLocalVector(dm, &locX_t);CHKERRQ(ierr);
87d433e6cbSMatthew G. Knepley   ierr = DMRestoreLocalVector(dm, &locF);CHKERRQ(ierr);
88d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
89d433e6cbSMatthew G. Knepley }
90d433e6cbSMatthew G. Knepley 
91d433e6cbSMatthew G. Knepley #undef __FUNCT__
92d433e6cbSMatthew G. Knepley #define __FUNCT__ "TSComputeRHSFunction_DMLocal"
93d433e6cbSMatthew G. Knepley static PetscErrorCode TSComputeRHSFunction_DMLocal(TS ts, PetscReal time, Vec X, Vec F, void *ctx)
94d433e6cbSMatthew G. Knepley {
95d433e6cbSMatthew G. Knepley   DM             dm;
96d433e6cbSMatthew G. Knepley   Vec            locX;
97d433e6cbSMatthew G. Knepley   DMTS_Local    *dmlocalts = (DMTS_Local *) ctx;
98d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
99d433e6cbSMatthew G. Knepley 
100d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
101d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
102d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(X,VEC_CLASSID,3);
103d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(F,VEC_CLASSID,5);
104d433e6cbSMatthew G. Knepley   ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
105d433e6cbSMatthew G. Knepley   ierr = DMGetLocalVector(dm, &locX);CHKERRQ(ierr);
106d433e6cbSMatthew G. Knepley   ierr = VecZeroEntries(locX);CHKERRQ(ierr);
107d433e6cbSMatthew G. Knepley   ierr = DMGlobalToLocalBegin(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr);
108d433e6cbSMatthew G. Knepley   ierr = DMGlobalToLocalEnd(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr);
109d433e6cbSMatthew G. Knepley   ierr = VecZeroEntries(F);CHKERRQ(ierr);
110d433e6cbSMatthew G. Knepley   CHKMEMQ;
111d433e6cbSMatthew G. Knepley   ierr = (*dmlocalts->rhsfunctionlocal)(dm, time, locX, F, dmlocalts->rhsfunctionlocalctx);CHKERRQ(ierr);
112d433e6cbSMatthew G. Knepley   CHKMEMQ;
113d433e6cbSMatthew G. Knepley   ierr = DMRestoreLocalVector(dm, &locX);CHKERRQ(ierr);
114d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
115d433e6cbSMatthew G. Knepley }
116d433e6cbSMatthew G. Knepley 
117d433e6cbSMatthew G. Knepley #undef __FUNCT__
118d433e6cbSMatthew G. Knepley #define __FUNCT__ "TSComputeIJacobian_DMLocal"
119d433e6cbSMatthew G. Knepley static PetscErrorCode TSComputeIJacobian_DMLocal(TS ts, PetscReal time, Vec X, Vec X_t, PetscReal a, Mat A, Mat B, void *ctx)
120d433e6cbSMatthew G. Knepley {
121d433e6cbSMatthew G. Knepley   DM             dm;
122d433e6cbSMatthew G. Knepley   Vec            locX, locX_t;
123d433e6cbSMatthew G. Knepley   DMTS_Local    *dmlocalts = (DMTS_Local *) ctx;
124d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
125d433e6cbSMatthew G. Knepley 
126d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
127d433e6cbSMatthew G. Knepley   ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
128d433e6cbSMatthew G. Knepley   if (dmlocalts->ijacobianlocal) {
129d433e6cbSMatthew G. Knepley     ierr = DMGetLocalVector(dm, &locX);CHKERRQ(ierr);
130d433e6cbSMatthew G. Knepley     ierr = DMGetLocalVector(dm, &locX_t);CHKERRQ(ierr);
131d433e6cbSMatthew G. Knepley     ierr = VecZeroEntries(locX);CHKERRQ(ierr);
132d433e6cbSMatthew G. Knepley     ierr = VecZeroEntries(locX_t);CHKERRQ(ierr);
133d433e6cbSMatthew G. Knepley     ierr = DMGlobalToLocalBegin(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr);
134d433e6cbSMatthew G. Knepley     ierr = DMGlobalToLocalEnd(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr);
135d433e6cbSMatthew G. Knepley     ierr = DMGlobalToLocalBegin(dm, X_t, INSERT_VALUES, locX_t);CHKERRQ(ierr);
136d433e6cbSMatthew G. Knepley     ierr = DMGlobalToLocalEnd(dm, X_t, INSERT_VALUES, locX_t);CHKERRQ(ierr);
137d433e6cbSMatthew G. Knepley     CHKMEMQ;
138d433e6cbSMatthew G. Knepley     ierr = (*dmlocalts->ijacobianlocal)(dm, time, locX, locX_t, a, A, B, dmlocalts->ijacobianlocalctx);CHKERRQ(ierr);
139d433e6cbSMatthew G. Knepley     CHKMEMQ;
140d433e6cbSMatthew G. Knepley     ierr = DMRestoreLocalVector(dm, &locX);CHKERRQ(ierr);
141d433e6cbSMatthew G. Knepley     ierr = DMRestoreLocalVector(dm, &locX_t);CHKERRQ(ierr);
142d433e6cbSMatthew G. Knepley   } else {
143d433e6cbSMatthew G. Knepley     MatFDColoring fdcoloring;
144d433e6cbSMatthew G. Knepley     ierr = PetscObjectQuery((PetscObject) dm, "DMDASNES_FDCOLORING", (PetscObject *) &fdcoloring);CHKERRQ(ierr);
145d433e6cbSMatthew G. Knepley     if (!fdcoloring) {
146d433e6cbSMatthew G. Knepley       ISColoring coloring;
147d433e6cbSMatthew G. Knepley 
148d433e6cbSMatthew G. Knepley       ierr = DMCreateColoring(dm, dm->coloringtype, &coloring);CHKERRQ(ierr);
149d433e6cbSMatthew G. Knepley       ierr = MatFDColoringCreate(B, coloring, &fdcoloring);CHKERRQ(ierr);
150d433e6cbSMatthew G. Knepley       ierr = ISColoringDestroy(&coloring);CHKERRQ(ierr);
151d433e6cbSMatthew G. Knepley       switch (dm->coloringtype) {
152d433e6cbSMatthew G. Knepley       case IS_COLORING_GLOBAL:
153d433e6cbSMatthew G. Knepley         ierr = MatFDColoringSetFunction(fdcoloring, (PetscErrorCode (*)(void)) TSComputeIFunction_DMLocal, dmlocalts);CHKERRQ(ierr);
154d433e6cbSMatthew G. Knepley         break;
155d433e6cbSMatthew G. Knepley       default: SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_SUP, "No support for coloring type '%s'", ISColoringTypes[dm->coloringtype]);
156d433e6cbSMatthew G. Knepley       }
157d433e6cbSMatthew G. Knepley       ierr = PetscObjectSetOptionsPrefix((PetscObject) fdcoloring, ((PetscObject) dm)->prefix);CHKERRQ(ierr);
158d433e6cbSMatthew G. Knepley       ierr = MatFDColoringSetFromOptions(fdcoloring);CHKERRQ(ierr);
159d433e6cbSMatthew G. Knepley       ierr = MatFDColoringSetUp(B, coloring, fdcoloring);CHKERRQ(ierr);
160d433e6cbSMatthew G. Knepley       ierr = PetscObjectCompose((PetscObject) dm, "DMDASNES_FDCOLORING", (PetscObject) fdcoloring);CHKERRQ(ierr);
161d433e6cbSMatthew G. Knepley       ierr = PetscObjectDereference((PetscObject) fdcoloring);CHKERRQ(ierr);
162d433e6cbSMatthew G. Knepley 
163d433e6cbSMatthew G. Knepley       /* The following breaks an ugly reference counting loop that deserves a paragraph. MatFDColoringApply() will call
164d433e6cbSMatthew G. Knepley        * VecDuplicate() with the state Vec and store inside the MatFDColoring. This Vec will duplicate the Vec, but the
165d433e6cbSMatthew G. Knepley        * MatFDColoring is composed with the DM. We dereference the DM here so that the reference count will eventually
166d433e6cbSMatthew G. Knepley        * drop to 0. Note the code in DMDestroy() that exits early for a negative reference count. That code path will be
167d433e6cbSMatthew G. Knepley        * taken when the PetscObjectList for the Vec inside MatFDColoring is destroyed.
168d433e6cbSMatthew G. Knepley        */
169d433e6cbSMatthew G. Knepley       ierr = PetscObjectDereference((PetscObject) dm);CHKERRQ(ierr);
170d433e6cbSMatthew G. Knepley     }
171d433e6cbSMatthew G. Knepley     ierr = MatFDColoringApply(B, fdcoloring, X, ts);CHKERRQ(ierr);
172d433e6cbSMatthew G. Knepley   }
173d433e6cbSMatthew G. Knepley   /* This will be redundant if the user called both, but it's too common to forget. */
174d433e6cbSMatthew G. Knepley   if (A != B) {
175d433e6cbSMatthew G. Knepley     ierr = MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
176d433e6cbSMatthew G. Knepley     ierr = MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
177d433e6cbSMatthew G. Knepley   }
178d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
179d433e6cbSMatthew G. Knepley }
180d433e6cbSMatthew G. Knepley 
181d433e6cbSMatthew G. Knepley #undef __FUNCT__
182d433e6cbSMatthew G. Knepley #define __FUNCT__ "DMTSSetIFunctionLocal"
183d433e6cbSMatthew G. Knepley /*@C
184d433e6cbSMatthew G. Knepley   DMTSSetIFunctionLocal - set a local implicit function evaluation function. This function is called with local vector
185d433e6cbSMatthew G. Knepley       containing the local vector information PLUS ghost point information. It should compute a result for all local
186d433e6cbSMatthew G. Knepley       elements and DMTS will automatically accumulate the overlapping values.
187d433e6cbSMatthew G. Knepley 
188d433e6cbSMatthew G. Knepley   Logically Collective
189d433e6cbSMatthew G. Knepley 
190d433e6cbSMatthew G. Knepley   Input Arguments:
191d433e6cbSMatthew G. Knepley + dm   - DM to associate callback with
192d433e6cbSMatthew G. Knepley . func - local function evaluation
193d433e6cbSMatthew G. Knepley - ctx  - context for function evaluation
194d433e6cbSMatthew G. Knepley 
195d433e6cbSMatthew G. Knepley   Level: beginner
196d433e6cbSMatthew G. Knepley 
197d433e6cbSMatthew G. Knepley .seealso: DMTSSetIFunction(), DMTSSetIJacobianLocal()
198d433e6cbSMatthew G. Knepley @*/
199d433e6cbSMatthew G. Knepley PetscErrorCode DMTSSetIFunctionLocal(DM dm, PetscErrorCode (*func)(DM, PetscReal, Vec, Vec, Vec, void *), void *ctx)
200d433e6cbSMatthew G. Knepley {
201d433e6cbSMatthew G. Knepley   DMTS           tdm;
202d433e6cbSMatthew G. Knepley   DMTS_Local    *dmlocalts;
203d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
204d433e6cbSMatthew G. Knepley 
205d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
206d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
207d433e6cbSMatthew G. Knepley   ierr = DMGetDMTSWrite(dm, &tdm);CHKERRQ(ierr);
208d433e6cbSMatthew G. Knepley   ierr = DMLocalTSGetContext(dm, tdm, &dmlocalts);CHKERRQ(ierr);
209d433e6cbSMatthew G. Knepley 
210d433e6cbSMatthew G. Knepley   dmlocalts->ifunctionlocal    = func;
211d433e6cbSMatthew G. Knepley   dmlocalts->ifunctionlocalctx = ctx;
212d433e6cbSMatthew G. Knepley 
213d433e6cbSMatthew G. Knepley   ierr = DMTSSetIFunction(dm, TSComputeIFunction_DMLocal, dmlocalts);CHKERRQ(ierr);
214d433e6cbSMatthew G. Knepley   if (!tdm->ops->ijacobian) {  /* Call us for the Jacobian too, can be overridden by the user. */
215d433e6cbSMatthew G. Knepley     ierr = DMTSSetIJacobian(dm, TSComputeIJacobian_DMLocal, dmlocalts);CHKERRQ(ierr);
216d433e6cbSMatthew G. Knepley   }
217d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
218d433e6cbSMatthew G. Knepley }
219d433e6cbSMatthew G. Knepley 
220d433e6cbSMatthew G. Knepley #undef __FUNCT__
221d433e6cbSMatthew G. Knepley #define __FUNCT__ "DMTSSetIJacobianLocal"
222d433e6cbSMatthew G. Knepley /*@C
223d433e6cbSMatthew G. Knepley   DMTSSetIJacobianLocal - set a local Jacobian evaluation function
224d433e6cbSMatthew G. Knepley 
225d433e6cbSMatthew G. Knepley   Logically Collective
226d433e6cbSMatthew G. Knepley 
227d433e6cbSMatthew G. Knepley   Input Arguments:
228d433e6cbSMatthew G. Knepley + dm - DM to associate callback with
229d433e6cbSMatthew G. Knepley . func - local Jacobian evaluation
230d433e6cbSMatthew G. Knepley - ctx - optional context for local Jacobian evaluation
231d433e6cbSMatthew G. Knepley 
232d433e6cbSMatthew G. Knepley   Level: beginner
233d433e6cbSMatthew G. Knepley 
234d433e6cbSMatthew G. Knepley .seealso: DMTSSetIFunctionLocal(), DMTSSetIJacobian(), DMTSSetIFunction()
235d433e6cbSMatthew G. Knepley @*/
236d433e6cbSMatthew G. Knepley PetscErrorCode DMTSSetIJacobianLocal(DM dm, PetscErrorCode (*func)(DM, PetscReal, Vec, Vec, PetscReal, Mat, Mat, void *), void *ctx)
237d433e6cbSMatthew G. Knepley {
238d433e6cbSMatthew G. Knepley   DMTS           tdm;
239d433e6cbSMatthew G. Knepley   DMTS_Local    *dmlocalts;
240d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
241d433e6cbSMatthew G. Knepley 
242d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
243d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
244d433e6cbSMatthew G. Knepley   ierr = DMGetDMTSWrite(dm, &tdm);CHKERRQ(ierr);
245d433e6cbSMatthew G. Knepley   ierr = DMLocalTSGetContext(dm, tdm, &dmlocalts);CHKERRQ(ierr);
246d433e6cbSMatthew G. Knepley 
247d433e6cbSMatthew G. Knepley   dmlocalts->ijacobianlocal    = func;
248d433e6cbSMatthew G. Knepley   dmlocalts->ijacobianlocalctx = ctx;
249d433e6cbSMatthew G. Knepley 
250d433e6cbSMatthew G. Knepley   ierr = DMTSSetIJacobian(dm, TSComputeIJacobian_DMLocal, dmlocalts);CHKERRQ(ierr);
251d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
252d433e6cbSMatthew G. Knepley }
253d433e6cbSMatthew G. Knepley 
254d433e6cbSMatthew G. Knepley #undef __FUNCT__
255d433e6cbSMatthew G. Knepley #define __FUNCT__ "DMTSSetRHSFunctionLocal"
256d433e6cbSMatthew G. Knepley /*@C
257d433e6cbSMatthew G. Knepley   DMTSSetRHSFunctionLocal - set a local rhs function evaluation function. This function is called with local vector
258d433e6cbSMatthew G. Knepley       containing the local vector information PLUS ghost point information. It should compute a result for all local
259d433e6cbSMatthew G. Knepley       elements and DMTS will automatically accumulate the overlapping values.
260d433e6cbSMatthew G. Knepley 
261d433e6cbSMatthew G. Knepley   Logically Collective
262d433e6cbSMatthew G. Knepley 
263d433e6cbSMatthew G. Knepley   Input Arguments:
264d433e6cbSMatthew G. Knepley + dm   - DM to associate callback with
265d433e6cbSMatthew G. Knepley . func - local function evaluation
266d433e6cbSMatthew G. Knepley - ctx  - context for function evaluation
267d433e6cbSMatthew G. Knepley 
268d433e6cbSMatthew G. Knepley   Level: beginner
269d433e6cbSMatthew G. Knepley 
270d433e6cbSMatthew G. Knepley .seealso: DMTSSetRHSFunction(), DMTSSetIFunction(), DMTSSetIJacobianLocal()
271d433e6cbSMatthew G. Knepley @*/
272d433e6cbSMatthew G. Knepley PetscErrorCode DMTSSetRHSFunctionLocal(DM dm, PetscErrorCode (*func)(DM, PetscReal, Vec, Vec, void *), void *ctx)
273d433e6cbSMatthew G. Knepley {
274d433e6cbSMatthew G. Knepley   DMTS           tdm;
275d433e6cbSMatthew G. Knepley   DMTS_Local    *dmlocalts;
276d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
277d433e6cbSMatthew G. Knepley 
278d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
279d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
280d433e6cbSMatthew G. Knepley   ierr = DMGetDMTSWrite(dm, &tdm);CHKERRQ(ierr);
281d433e6cbSMatthew G. Knepley   ierr = DMLocalTSGetContext(dm, tdm, &dmlocalts);CHKERRQ(ierr);
282d433e6cbSMatthew G. Knepley 
283d433e6cbSMatthew G. Knepley   dmlocalts->rhsfunctionlocal    = func;
284d433e6cbSMatthew G. Knepley   dmlocalts->rhsfunctionlocalctx = ctx;
285d433e6cbSMatthew G. Knepley 
286d433e6cbSMatthew G. Knepley   ierr = DMTSSetRHSFunction(dm, TSComputeRHSFunction_DMLocal, dmlocalts);CHKERRQ(ierr);
287d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
288d433e6cbSMatthew G. Knepley }
289