xref: /petsc/src/ts/utils/dmlocalts.c (revision b4937a871eb039ca2dcd55b5c176b375745f00b6)
1af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
2af0996ceSBarry Smith #include <petsc/private/tsimpl.h>   /*I "petscts.h" I*/
3d433e6cbSMatthew G. Knepley 
4d433e6cbSMatthew G. Knepley typedef struct {
5f2b97b97SMatthew G. Knepley   PetscErrorCode (*boundarylocal)(DM,PetscReal,Vec,Vec,void*);
6d433e6cbSMatthew G. Knepley   PetscErrorCode (*ifunctionlocal)(DM,PetscReal,Vec,Vec,Vec,void*);
7d433e6cbSMatthew G. Knepley   PetscErrorCode (*ijacobianlocal)(DM,PetscReal,Vec,Vec,PetscReal,Mat,Mat,void*);
8d433e6cbSMatthew G. Knepley   PetscErrorCode (*rhsfunctionlocal)(DM,PetscReal,Vec,Vec,void*);
9f2b97b97SMatthew G. Knepley   void *boundarylocalctx;
10d433e6cbSMatthew G. Knepley   void *ifunctionlocalctx;
11d433e6cbSMatthew G. Knepley   void *ijacobianlocalctx;
12d433e6cbSMatthew G. Knepley   void *rhsfunctionlocalctx;
13*b4937a87SMatthew G. Knepley   Vec   lumpedmassinv;
14*b4937a87SMatthew G. Knepley   Mat   mass;
15*b4937a87SMatthew G. Knepley   KSP   kspmass;
16d433e6cbSMatthew G. Knepley } DMTS_Local;
17d433e6cbSMatthew G. Knepley 
18d433e6cbSMatthew G. Knepley static PetscErrorCode DMTSDestroy_DMLocal(DMTS tdm)
19d433e6cbSMatthew G. Knepley {
20d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
21d433e6cbSMatthew G. Knepley 
22d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
23d433e6cbSMatthew G. Knepley   ierr = PetscFree(tdm->data);CHKERRQ(ierr);
24d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
25d433e6cbSMatthew G. Knepley }
26d433e6cbSMatthew G. Knepley 
27d433e6cbSMatthew G. Knepley static PetscErrorCode DMTSDuplicate_DMLocal(DMTS oldtdm, DMTS tdm)
28d433e6cbSMatthew G. Knepley {
29d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
30d433e6cbSMatthew G. Knepley 
31d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
32d433e6cbSMatthew G. Knepley   ierr = PetscNewLog(tdm, (DMTS_Local **) &tdm->data);CHKERRQ(ierr);
33d433e6cbSMatthew G. Knepley   if (oldtdm->data) {ierr = PetscMemcpy(tdm->data, oldtdm->data, sizeof(DMTS_Local));CHKERRQ(ierr);}
34d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
35d433e6cbSMatthew G. Knepley }
36d433e6cbSMatthew G. Knepley 
37d433e6cbSMatthew G. Knepley static PetscErrorCode DMLocalTSGetContext(DM dm, DMTS tdm, DMTS_Local **dmlocalts)
38d433e6cbSMatthew G. Knepley {
39d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
40d433e6cbSMatthew G. Knepley 
41d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
42d433e6cbSMatthew G. Knepley   *dmlocalts = NULL;
43d433e6cbSMatthew G. Knepley   if (!tdm->data) {
44d433e6cbSMatthew G. Knepley     ierr = PetscNewLog(dm, (DMTS_Local **) &tdm->data);CHKERRQ(ierr);
45d433e6cbSMatthew G. Knepley 
46d433e6cbSMatthew G. Knepley     tdm->ops->destroy   = DMTSDestroy_DMLocal;
47d433e6cbSMatthew G. Knepley     tdm->ops->duplicate = DMTSDuplicate_DMLocal;
48d433e6cbSMatthew G. Knepley   }
49d433e6cbSMatthew G. Knepley   *dmlocalts = (DMTS_Local *) tdm->data;
50d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
51d433e6cbSMatthew G. Knepley }
52d433e6cbSMatthew G. Knepley 
53d433e6cbSMatthew G. Knepley static PetscErrorCode TSComputeIFunction_DMLocal(TS ts, PetscReal time, Vec X, Vec X_t, Vec F, void *ctx)
54d433e6cbSMatthew G. Knepley {
55d433e6cbSMatthew G. Knepley   DM             dm;
56d433e6cbSMatthew G. Knepley   Vec            locX, locX_t, locF;
57d433e6cbSMatthew G. Knepley   DMTS_Local    *dmlocalts = (DMTS_Local *) ctx;
58d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
59d433e6cbSMatthew G. Knepley 
60d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
61d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
62d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(X,VEC_CLASSID,3);
63d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(X_t,VEC_CLASSID,4);
64d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(F,VEC_CLASSID,5);
65d433e6cbSMatthew G. Knepley   ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
66d433e6cbSMatthew G. Knepley   ierr = DMGetLocalVector(dm, &locX);CHKERRQ(ierr);
67d433e6cbSMatthew G. Knepley   ierr = DMGetLocalVector(dm, &locX_t);CHKERRQ(ierr);
68d433e6cbSMatthew G. Knepley   ierr = DMGetLocalVector(dm, &locF);CHKERRQ(ierr);
69d433e6cbSMatthew G. Knepley   ierr = VecZeroEntries(locX);CHKERRQ(ierr);
70d433e6cbSMatthew G. Knepley   ierr = VecZeroEntries(locX_t);CHKERRQ(ierr);
71f2b97b97SMatthew G. Knepley   if (dmlocalts->boundarylocal) {ierr = (*dmlocalts->boundarylocal)(dm, time, locX, locX_t,dmlocalts->boundarylocalctx);CHKERRQ(ierr);}
72d433e6cbSMatthew G. Knepley   ierr = DMGlobalToLocalBegin(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr);
73d433e6cbSMatthew G. Knepley   ierr = DMGlobalToLocalEnd(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr);
74d433e6cbSMatthew G. Knepley   ierr = DMGlobalToLocalBegin(dm, X_t, INSERT_VALUES, locX_t);CHKERRQ(ierr);
75d433e6cbSMatthew G. Knepley   ierr = DMGlobalToLocalEnd(dm, X_t, INSERT_VALUES, locX_t);CHKERRQ(ierr);
76d433e6cbSMatthew G. Knepley   ierr = VecZeroEntries(locF);CHKERRQ(ierr);
77d433e6cbSMatthew G. Knepley   CHKMEMQ;
78d433e6cbSMatthew G. Knepley   ierr = (*dmlocalts->ifunctionlocal)(dm, time, locX, locX_t, locF, dmlocalts->ifunctionlocalctx);CHKERRQ(ierr);
79d433e6cbSMatthew G. Knepley   CHKMEMQ;
80d433e6cbSMatthew G. Knepley   ierr = VecZeroEntries(F);CHKERRQ(ierr);
81d433e6cbSMatthew G. Knepley   ierr = DMLocalToGlobalBegin(dm, locF, ADD_VALUES, F);CHKERRQ(ierr);
82d433e6cbSMatthew G. Knepley   ierr = DMLocalToGlobalEnd(dm, locF, ADD_VALUES, F);CHKERRQ(ierr);
83d433e6cbSMatthew G. Knepley   ierr = DMRestoreLocalVector(dm, &locX);CHKERRQ(ierr);
84d433e6cbSMatthew G. Knepley   ierr = DMRestoreLocalVector(dm, &locX_t);CHKERRQ(ierr);
85d433e6cbSMatthew G. Knepley   ierr = DMRestoreLocalVector(dm, &locF);CHKERRQ(ierr);
86d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
87d433e6cbSMatthew G. Knepley }
88d433e6cbSMatthew G. Knepley 
89d433e6cbSMatthew G. Knepley static PetscErrorCode TSComputeRHSFunction_DMLocal(TS ts, PetscReal time, Vec X, Vec F, void *ctx)
90d433e6cbSMatthew G. Knepley {
91d433e6cbSMatthew G. Knepley   DM             dm;
92*b4937a87SMatthew G. Knepley   Vec            locX, locF;
93d433e6cbSMatthew G. Knepley   DMTS_Local    *dmlocalts = (DMTS_Local *) ctx;
94d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
95d433e6cbSMatthew G. Knepley 
96d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
97d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
98d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(X,VEC_CLASSID,3);
99064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(F,VEC_CLASSID,4);
100d433e6cbSMatthew G. Knepley   ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
101d433e6cbSMatthew G. Knepley   ierr = DMGetLocalVector(dm, &locX);CHKERRQ(ierr);
102*b4937a87SMatthew G. Knepley   ierr = DMGetLocalVector(dm, &locF);CHKERRQ(ierr);
103d433e6cbSMatthew G. Knepley   ierr = VecZeroEntries(locX);CHKERRQ(ierr);
104f2b97b97SMatthew G. Knepley   if (dmlocalts->boundarylocal) {ierr = (*dmlocalts->boundarylocal)(dm,time,locX,NULL,dmlocalts->boundarylocalctx);CHKERRQ(ierr);}
105d433e6cbSMatthew G. Knepley   ierr = DMGlobalToLocalBegin(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr);
106d433e6cbSMatthew G. Knepley   ierr = DMGlobalToLocalEnd(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr);
107*b4937a87SMatthew G. Knepley   ierr = VecZeroEntries(locF);CHKERRQ(ierr);
108*b4937a87SMatthew G. Knepley   CHKMEMQ;
109*b4937a87SMatthew G. Knepley   ierr = (*dmlocalts->rhsfunctionlocal)(dm, time, locX, locF, dmlocalts->rhsfunctionlocalctx);CHKERRQ(ierr);
110*b4937a87SMatthew G. Knepley   CHKMEMQ;
111d433e6cbSMatthew G. Knepley   ierr = VecZeroEntries(F);CHKERRQ(ierr);
112*b4937a87SMatthew G. Knepley   ierr = DMLocalToGlobalBegin(dm, locF, ADD_VALUES, F);CHKERRQ(ierr);
113*b4937a87SMatthew G. Knepley   ierr = DMLocalToGlobalEnd(dm, locF, ADD_VALUES, F);CHKERRQ(ierr);
114*b4937a87SMatthew G. Knepley   if (dmlocalts->lumpedmassinv) {
115*b4937a87SMatthew G. Knepley     ierr = VecPointwiseMult(F, dmlocalts->lumpedmassinv, F);CHKERRQ(ierr);
116*b4937a87SMatthew G. Knepley   } else if (dmlocalts->kspmass) {
117*b4937a87SMatthew G. Knepley     Vec tmp;
118*b4937a87SMatthew G. Knepley 
119*b4937a87SMatthew G. Knepley     ierr = DMGetGlobalVector(dm, &tmp);CHKERRQ(ierr);
120*b4937a87SMatthew G. Knepley     ierr = KSPSolve(dmlocalts->kspmass, F, tmp);CHKERRQ(ierr);
121*b4937a87SMatthew G. Knepley     ierr = VecCopy(tmp, F);CHKERRQ(ierr);
122*b4937a87SMatthew G. Knepley     ierr = DMRestoreGlobalVector(dm, &tmp);CHKERRQ(ierr);
123*b4937a87SMatthew G. Knepley   }
124d433e6cbSMatthew G. Knepley   ierr = DMRestoreLocalVector(dm, &locX);CHKERRQ(ierr);
125*b4937a87SMatthew G. Knepley   ierr = DMRestoreLocalVector(dm, &locF);CHKERRQ(ierr);
126d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
127d433e6cbSMatthew G. Knepley }
128d433e6cbSMatthew G. Knepley 
129d433e6cbSMatthew G. Knepley static PetscErrorCode TSComputeIJacobian_DMLocal(TS ts, PetscReal time, Vec X, Vec X_t, PetscReal a, Mat A, Mat B, void *ctx)
130d433e6cbSMatthew G. Knepley {
131d433e6cbSMatthew G. Knepley   DM             dm;
132d433e6cbSMatthew G. Knepley   Vec            locX, locX_t;
133d433e6cbSMatthew G. Knepley   DMTS_Local    *dmlocalts = (DMTS_Local *) ctx;
134d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
135d433e6cbSMatthew G. Knepley 
136d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
137d433e6cbSMatthew G. Knepley   ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
138d433e6cbSMatthew G. Knepley   if (dmlocalts->ijacobianlocal) {
139d433e6cbSMatthew G. Knepley     ierr = DMGetLocalVector(dm, &locX);CHKERRQ(ierr);
140d433e6cbSMatthew G. Knepley     ierr = DMGetLocalVector(dm, &locX_t);CHKERRQ(ierr);
141d433e6cbSMatthew G. Knepley     ierr = VecZeroEntries(locX);CHKERRQ(ierr);
142d433e6cbSMatthew G. Knepley     ierr = VecZeroEntries(locX_t);CHKERRQ(ierr);
143ac5ac1d1Smtmcgurn-buffalo     if (dmlocalts->boundarylocal) {ierr = (*dmlocalts->boundarylocal)(dm,time,locX,locX_t,dmlocalts->boundarylocalctx);CHKERRQ(ierr);}
144d433e6cbSMatthew G. Knepley     ierr = DMGlobalToLocalBegin(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr);
145d433e6cbSMatthew G. Knepley     ierr = DMGlobalToLocalEnd(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr);
146d433e6cbSMatthew G. Knepley     ierr = DMGlobalToLocalBegin(dm, X_t, INSERT_VALUES, locX_t);CHKERRQ(ierr);
147d433e6cbSMatthew G. Knepley     ierr = DMGlobalToLocalEnd(dm, X_t, INSERT_VALUES, locX_t);CHKERRQ(ierr);
148d433e6cbSMatthew G. Knepley     CHKMEMQ;
149d433e6cbSMatthew G. Knepley     ierr = (*dmlocalts->ijacobianlocal)(dm, time, locX, locX_t, a, A, B, dmlocalts->ijacobianlocalctx);CHKERRQ(ierr);
150d433e6cbSMatthew G. Knepley     CHKMEMQ;
151d433e6cbSMatthew G. Knepley     ierr = DMRestoreLocalVector(dm, &locX);CHKERRQ(ierr);
152d433e6cbSMatthew G. Knepley     ierr = DMRestoreLocalVector(dm, &locX_t);CHKERRQ(ierr);
153d433e6cbSMatthew G. Knepley   } else {
154d433e6cbSMatthew G. Knepley     MatFDColoring fdcoloring;
155d433e6cbSMatthew G. Knepley     ierr = PetscObjectQuery((PetscObject) dm, "DMDASNES_FDCOLORING", (PetscObject *) &fdcoloring);CHKERRQ(ierr);
156d433e6cbSMatthew G. Knepley     if (!fdcoloring) {
157d433e6cbSMatthew G. Knepley       ISColoring coloring;
158d433e6cbSMatthew G. Knepley 
159d433e6cbSMatthew G. Knepley       ierr = DMCreateColoring(dm, dm->coloringtype, &coloring);CHKERRQ(ierr);
160d433e6cbSMatthew G. Knepley       ierr = MatFDColoringCreate(B, coloring, &fdcoloring);CHKERRQ(ierr);
161d433e6cbSMatthew G. Knepley       ierr = ISColoringDestroy(&coloring);CHKERRQ(ierr);
162d433e6cbSMatthew G. Knepley       switch (dm->coloringtype) {
163d433e6cbSMatthew G. Knepley       case IS_COLORING_GLOBAL:
164d433e6cbSMatthew G. Knepley         ierr = MatFDColoringSetFunction(fdcoloring, (PetscErrorCode (*)(void)) TSComputeIFunction_DMLocal, dmlocalts);CHKERRQ(ierr);
165d433e6cbSMatthew G. Knepley         break;
166d433e6cbSMatthew G. Knepley       default: SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_SUP, "No support for coloring type '%s'", ISColoringTypes[dm->coloringtype]);
167d433e6cbSMatthew G. Knepley       }
168d433e6cbSMatthew G. Knepley       ierr = PetscObjectSetOptionsPrefix((PetscObject) fdcoloring, ((PetscObject) dm)->prefix);CHKERRQ(ierr);
169d433e6cbSMatthew G. Knepley       ierr = MatFDColoringSetFromOptions(fdcoloring);CHKERRQ(ierr);
170d433e6cbSMatthew G. Knepley       ierr = MatFDColoringSetUp(B, coloring, fdcoloring);CHKERRQ(ierr);
171d433e6cbSMatthew G. Knepley       ierr = PetscObjectCompose((PetscObject) dm, "DMDASNES_FDCOLORING", (PetscObject) fdcoloring);CHKERRQ(ierr);
172d433e6cbSMatthew G. Knepley       ierr = PetscObjectDereference((PetscObject) fdcoloring);CHKERRQ(ierr);
173d433e6cbSMatthew G. Knepley 
174d433e6cbSMatthew G. Knepley       /* The following breaks an ugly reference counting loop that deserves a paragraph. MatFDColoringApply() will call
175d433e6cbSMatthew G. Knepley        * VecDuplicate() with the state Vec and store inside the MatFDColoring. This Vec will duplicate the Vec, but the
176d433e6cbSMatthew G. Knepley        * MatFDColoring is composed with the DM. We dereference the DM here so that the reference count will eventually
177d433e6cbSMatthew G. Knepley        * drop to 0. Note the code in DMDestroy() that exits early for a negative reference count. That code path will be
178d433e6cbSMatthew G. Knepley        * taken when the PetscObjectList for the Vec inside MatFDColoring is destroyed.
179d433e6cbSMatthew G. Knepley        */
180d433e6cbSMatthew G. Knepley       ierr = PetscObjectDereference((PetscObject) dm);CHKERRQ(ierr);
181d433e6cbSMatthew G. Knepley     }
182d433e6cbSMatthew G. Knepley     ierr = MatFDColoringApply(B, fdcoloring, X, ts);CHKERRQ(ierr);
183d433e6cbSMatthew G. Knepley   }
184d433e6cbSMatthew G. Knepley   /* This will be redundant if the user called both, but it's too common to forget. */
185d433e6cbSMatthew G. Knepley   if (A != B) {
186d433e6cbSMatthew G. Knepley     ierr = MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
187d433e6cbSMatthew G. Knepley     ierr = MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
188d433e6cbSMatthew G. Knepley   }
189d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
190d433e6cbSMatthew G. Knepley }
191d433e6cbSMatthew G. Knepley 
1927eb36faeSMatthew G. Knepley /*@C
193f2b97b97SMatthew G. Knepley   DMTSSetBoundaryLocal - set the function for essential boundary data for a local implicit function evaluation.
194a40652d4SToby Isaac     It should set the essential boundary data for the local portion of the solution X, as well its time derivative X_t (if it is not NULL).
195a40652d4SToby Isaac     Vectors are initialized to zero before this function, so it is only needed for non homogeneous data.
196a40652d4SToby Isaac 
197a40652d4SToby Isaac   Note that this function is somewhat optional: boundary data could potentially be inserted by a function passed to
198a40652d4SToby Isaac   DMTSSetIFunctionLocal().  The use case for this function is for discretizations with constraints (see
199a40652d4SToby Isaac   DMGetDefaultConstraints()): this function inserts boundary values before constraint interpolation.
2007eb36faeSMatthew G. Knepley 
2017eb36faeSMatthew G. Knepley   Logically Collective
2027eb36faeSMatthew G. Knepley 
2034165533cSJose E. Roman   Input Parameters:
2047eb36faeSMatthew G. Knepley + dm   - DM to associate callback with
205a40652d4SToby Isaac . func - local function evaluation
206a40652d4SToby Isaac - ctx  - context for function evaluation
2077eb36faeSMatthew G. Knepley 
2087eb36faeSMatthew G. Knepley   Level: intermediate
2097eb36faeSMatthew G. Knepley 
210a40652d4SToby Isaac .seealso: DMTSSetIFunction(), DMTSSetIJacobianLocal()
2117eb36faeSMatthew G. Knepley @*/
212f2b97b97SMatthew G. Knepley PetscErrorCode DMTSSetBoundaryLocal(DM dm, PetscErrorCode (*func)(DM, PetscReal, Vec, Vec, void *), void *ctx)
2137eb36faeSMatthew G. Knepley {
2147eb36faeSMatthew G. Knepley   DMTS           tdm;
2157eb36faeSMatthew G. Knepley   DMTS_Local    *dmlocalts;
2167eb36faeSMatthew G. Knepley   PetscErrorCode ierr;
2177eb36faeSMatthew G. Knepley 
2187eb36faeSMatthew G. Knepley   PetscFunctionBegin;
2197eb36faeSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2207eb36faeSMatthew G. Knepley   ierr = DMGetDMTSWrite(dm, &tdm);CHKERRQ(ierr);
2217eb36faeSMatthew G. Knepley   ierr = DMLocalTSGetContext(dm, tdm, &dmlocalts);CHKERRQ(ierr);
2227eb36faeSMatthew G. Knepley 
2237eb36faeSMatthew G. Knepley   dmlocalts->boundarylocal    = func;
2247eb36faeSMatthew G. Knepley   dmlocalts->boundarylocalctx = ctx;
225a40652d4SToby Isaac 
2267eb36faeSMatthew G. Knepley   PetscFunctionReturn(0);
2277eb36faeSMatthew G. Knepley }
2287eb36faeSMatthew G. Knepley 
229d433e6cbSMatthew G. Knepley /*@C
230d433e6cbSMatthew G. Knepley   DMTSSetIFunctionLocal - set a local implicit function evaluation function. This function is called with local vector
231d433e6cbSMatthew G. Knepley       containing the local vector information PLUS ghost point information. It should compute a result for all local
232d433e6cbSMatthew G. Knepley       elements and DMTS will automatically accumulate the overlapping values.
233d433e6cbSMatthew G. Knepley 
234d433e6cbSMatthew G. Knepley   Logically Collective
235d433e6cbSMatthew G. Knepley 
2364165533cSJose E. Roman   Input Parameters:
237d433e6cbSMatthew G. Knepley + dm   - DM to associate callback with
238d433e6cbSMatthew G. Knepley . func - local function evaluation
239d433e6cbSMatthew G. Knepley - ctx  - context for function evaluation
240d433e6cbSMatthew G. Knepley 
241d433e6cbSMatthew G. Knepley   Level: beginner
242d433e6cbSMatthew G. Knepley 
243d433e6cbSMatthew G. Knepley .seealso: DMTSSetIFunction(), DMTSSetIJacobianLocal()
244d433e6cbSMatthew G. Knepley @*/
245d433e6cbSMatthew G. Knepley PetscErrorCode DMTSSetIFunctionLocal(DM dm, PetscErrorCode (*func)(DM, PetscReal, Vec, Vec, Vec, void *), void *ctx)
246d433e6cbSMatthew G. Knepley {
247d433e6cbSMatthew G. Knepley   DMTS           tdm;
248d433e6cbSMatthew G. Knepley   DMTS_Local    *dmlocalts;
249d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
250d433e6cbSMatthew G. Knepley 
251d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
252d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
253d433e6cbSMatthew G. Knepley   ierr = DMGetDMTSWrite(dm, &tdm);CHKERRQ(ierr);
254d433e6cbSMatthew G. Knepley   ierr = DMLocalTSGetContext(dm, tdm, &dmlocalts);CHKERRQ(ierr);
255d433e6cbSMatthew G. Knepley 
256d433e6cbSMatthew G. Knepley   dmlocalts->ifunctionlocal    = func;
257d433e6cbSMatthew G. Knepley   dmlocalts->ifunctionlocalctx = ctx;
258d433e6cbSMatthew G. Knepley 
259d433e6cbSMatthew G. Knepley   ierr = DMTSSetIFunction(dm, TSComputeIFunction_DMLocal, dmlocalts);CHKERRQ(ierr);
260d433e6cbSMatthew G. Knepley   if (!tdm->ops->ijacobian) {  /* Call us for the Jacobian too, can be overridden by the user. */
261d433e6cbSMatthew G. Knepley     ierr = DMTSSetIJacobian(dm, TSComputeIJacobian_DMLocal, dmlocalts);CHKERRQ(ierr);
262d433e6cbSMatthew G. Knepley   }
263d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
264d433e6cbSMatthew G. Knepley }
265d433e6cbSMatthew G. Knepley 
266d433e6cbSMatthew G. Knepley /*@C
267d433e6cbSMatthew G. Knepley   DMTSSetIJacobianLocal - set a local Jacobian evaluation function
268d433e6cbSMatthew G. Knepley 
269d433e6cbSMatthew G. Knepley   Logically Collective
270d433e6cbSMatthew G. Knepley 
2714165533cSJose E. Roman   Input Parameters:
272d433e6cbSMatthew G. Knepley + dm - DM to associate callback with
273d433e6cbSMatthew G. Knepley . func - local Jacobian evaluation
274d433e6cbSMatthew G. Knepley - ctx - optional context for local Jacobian evaluation
275d433e6cbSMatthew G. Knepley 
276d433e6cbSMatthew G. Knepley   Level: beginner
277d433e6cbSMatthew G. Knepley 
278d433e6cbSMatthew G. Knepley .seealso: DMTSSetIFunctionLocal(), DMTSSetIJacobian(), DMTSSetIFunction()
279d433e6cbSMatthew G. Knepley @*/
280d433e6cbSMatthew G. Knepley PetscErrorCode DMTSSetIJacobianLocal(DM dm, PetscErrorCode (*func)(DM, PetscReal, Vec, Vec, PetscReal, Mat, Mat, void *), void *ctx)
281d433e6cbSMatthew G. Knepley {
282d433e6cbSMatthew G. Knepley   DMTS           tdm;
283d433e6cbSMatthew G. Knepley   DMTS_Local    *dmlocalts;
284d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
285d433e6cbSMatthew G. Knepley 
286d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
287d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
288d433e6cbSMatthew G. Knepley   ierr = DMGetDMTSWrite(dm, &tdm);CHKERRQ(ierr);
289d433e6cbSMatthew G. Knepley   ierr = DMLocalTSGetContext(dm, tdm, &dmlocalts);CHKERRQ(ierr);
290d433e6cbSMatthew G. Knepley 
291d433e6cbSMatthew G. Knepley   dmlocalts->ijacobianlocal    = func;
292d433e6cbSMatthew G. Knepley   dmlocalts->ijacobianlocalctx = ctx;
293d433e6cbSMatthew G. Knepley 
294d433e6cbSMatthew G. Knepley   ierr = DMTSSetIJacobian(dm, TSComputeIJacobian_DMLocal, dmlocalts);CHKERRQ(ierr);
295d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
296d433e6cbSMatthew G. Knepley }
297d433e6cbSMatthew G. Knepley 
298d433e6cbSMatthew G. Knepley /*@C
299d433e6cbSMatthew G. Knepley   DMTSSetRHSFunctionLocal - set a local rhs function evaluation function. This function is called with local vector
300d433e6cbSMatthew G. Knepley       containing the local vector information PLUS ghost point information. It should compute a result for all local
301d433e6cbSMatthew G. Knepley       elements and DMTS will automatically accumulate the overlapping values.
302d433e6cbSMatthew G. Knepley 
303d433e6cbSMatthew G. Knepley   Logically Collective
304d433e6cbSMatthew G. Knepley 
3054165533cSJose E. Roman   Input Parameters:
306d433e6cbSMatthew G. Knepley + dm   - DM to associate callback with
307d433e6cbSMatthew G. Knepley . func - local function evaluation
308d433e6cbSMatthew G. Knepley - ctx  - context for function evaluation
309d433e6cbSMatthew G. Knepley 
310d433e6cbSMatthew G. Knepley   Level: beginner
311d433e6cbSMatthew G. Knepley 
312d433e6cbSMatthew G. Knepley .seealso: DMTSSetRHSFunction(), DMTSSetIFunction(), DMTSSetIJacobianLocal()
313d433e6cbSMatthew G. Knepley @*/
314d433e6cbSMatthew G. Knepley PetscErrorCode DMTSSetRHSFunctionLocal(DM dm, PetscErrorCode (*func)(DM, PetscReal, Vec, Vec, void *), void *ctx)
315d433e6cbSMatthew G. Knepley {
316d433e6cbSMatthew G. Knepley   DMTS           tdm;
317d433e6cbSMatthew G. Knepley   DMTS_Local    *dmlocalts;
318d433e6cbSMatthew G. Knepley   PetscErrorCode ierr;
319d433e6cbSMatthew G. Knepley 
320d433e6cbSMatthew G. Knepley   PetscFunctionBegin;
321d433e6cbSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
322d433e6cbSMatthew G. Knepley   ierr = DMGetDMTSWrite(dm, &tdm);CHKERRQ(ierr);
323d433e6cbSMatthew G. Knepley   ierr = DMLocalTSGetContext(dm, tdm, &dmlocalts);CHKERRQ(ierr);
324d433e6cbSMatthew G. Knepley 
325d433e6cbSMatthew G. Knepley   dmlocalts->rhsfunctionlocal    = func;
326d433e6cbSMatthew G. Knepley   dmlocalts->rhsfunctionlocalctx = ctx;
327d433e6cbSMatthew G. Knepley 
328d433e6cbSMatthew G. Knepley   ierr = DMTSSetRHSFunction(dm, TSComputeRHSFunction_DMLocal, dmlocalts);CHKERRQ(ierr);
329d433e6cbSMatthew G. Knepley   PetscFunctionReturn(0);
330d433e6cbSMatthew G. Knepley }
331*b4937a87SMatthew G. Knepley 
332*b4937a87SMatthew G. Knepley /*@C
333*b4937a87SMatthew G. Knepley   DMTSCreateRHSMassMatrix - This creates the mass matrix associated with the given DM, and a solver to invert it, and stores them in the DMTS context.
334*b4937a87SMatthew G. Knepley 
335*b4937a87SMatthew G. Knepley   Collective on dm
336*b4937a87SMatthew G. Knepley 
337*b4937a87SMatthew G. Knepley   Input Parameters:
338*b4937a87SMatthew G. Knepley . dm   - DM providing the mass matrix
339*b4937a87SMatthew G. Knepley 
340*b4937a87SMatthew G. Knepley   Note: The idea here is that an explicit system can be given a mass matrix, based on the DM, which is inverted on the RHS at each step.
341*b4937a87SMatthew G. Knepley 
342*b4937a87SMatthew G. Knepley   Level: developer
343*b4937a87SMatthew G. Knepley 
344*b4937a87SMatthew G. Knepley .seealso: DMTSCreateRHSMassMatrixLumped(), DMTSDestroyRHSMassMatrix(), DMCreateMassMatrix(), DMTS
345*b4937a87SMatthew G. Knepley @*/
346*b4937a87SMatthew G. Knepley PetscErrorCode DMTSCreateRHSMassMatrix(DM dm)
347*b4937a87SMatthew G. Knepley {
348*b4937a87SMatthew G. Knepley   DMTS           tdm;
349*b4937a87SMatthew G. Knepley   DMTS_Local    *dmlocalts;
350*b4937a87SMatthew G. Knepley   const char    *prefix;
351*b4937a87SMatthew G. Knepley   PetscErrorCode ierr;
352*b4937a87SMatthew G. Knepley 
353*b4937a87SMatthew G. Knepley   PetscFunctionBegin;
354*b4937a87SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
355*b4937a87SMatthew G. Knepley   ierr = DMGetDMTSWrite(dm, &tdm);CHKERRQ(ierr);
356*b4937a87SMatthew G. Knepley   ierr = DMLocalTSGetContext(dm, tdm, &dmlocalts);CHKERRQ(ierr);
357*b4937a87SMatthew G. Knepley   ierr = DMCreateMassMatrix(dm, dm, &dmlocalts->mass);CHKERRQ(ierr);
358*b4937a87SMatthew G. Knepley   ierr = KSPCreate(PetscObjectComm((PetscObject) dm), &dmlocalts->kspmass);CHKERRQ(ierr);
359*b4937a87SMatthew G. Knepley   ierr = PetscObjectGetOptionsPrefix((PetscObject) dm, &prefix);CHKERRQ(ierr);
360*b4937a87SMatthew G. Knepley   ierr = KSPSetOptionsPrefix(dmlocalts->kspmass, prefix);CHKERRQ(ierr);
361*b4937a87SMatthew G. Knepley   ierr = KSPAppendOptionsPrefix(dmlocalts->kspmass, "mass_");CHKERRQ(ierr);
362*b4937a87SMatthew G. Knepley   ierr = KSPSetFromOptions(dmlocalts->kspmass);CHKERRQ(ierr);
363*b4937a87SMatthew G. Knepley   ierr = KSPSetOperators(dmlocalts->kspmass, dmlocalts->mass, dmlocalts->mass);CHKERRQ(ierr);
364*b4937a87SMatthew G. Knepley   PetscFunctionReturn(0);
365*b4937a87SMatthew G. Knepley }
366*b4937a87SMatthew G. Knepley 
367*b4937a87SMatthew G. Knepley /*@C
368*b4937a87SMatthew G. Knepley   DMTSCreateRHSMassMatrixLumped - This creates the lumped mass matrix associated with the given DM, and a solver to invert it, and stores them in the DMTS context.
369*b4937a87SMatthew G. Knepley 
370*b4937a87SMatthew G. Knepley   Collective on dm
371*b4937a87SMatthew G. Knepley 
372*b4937a87SMatthew G. Knepley   Input Parameters:
373*b4937a87SMatthew G. Knepley . dm   - DM providing the mass matrix
374*b4937a87SMatthew G. Knepley 
375*b4937a87SMatthew G. Knepley   Note: The idea here is that an explicit system can be given a mass matrix, based on the DM, which is inverted on the RHS at each step.
376*b4937a87SMatthew G. Knepley   Since the matrix is lumped, inversion is trivial.
377*b4937a87SMatthew G. Knepley 
378*b4937a87SMatthew G. Knepley   Level: developer
379*b4937a87SMatthew G. Knepley 
380*b4937a87SMatthew G. Knepley .seealso: DMTSCreateRHSMassMatrix(), DMTSDestroyRHSMassMatrix(), DMCreateMassMatrix(), DMTS
381*b4937a87SMatthew G. Knepley @*/
382*b4937a87SMatthew G. Knepley PetscErrorCode DMTSCreateRHSMassMatrixLumped(DM dm)
383*b4937a87SMatthew G. Knepley {
384*b4937a87SMatthew G. Knepley   DMTS           tdm;
385*b4937a87SMatthew G. Knepley   DMTS_Local    *dmlocalts;
386*b4937a87SMatthew G. Knepley   PetscErrorCode ierr;
387*b4937a87SMatthew G. Knepley 
388*b4937a87SMatthew G. Knepley   PetscFunctionBegin;
389*b4937a87SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
390*b4937a87SMatthew G. Knepley   ierr = DMGetDMTSWrite(dm, &tdm);CHKERRQ(ierr);
391*b4937a87SMatthew G. Knepley   ierr = DMLocalTSGetContext(dm, tdm, &dmlocalts);CHKERRQ(ierr);
392*b4937a87SMatthew G. Knepley   ierr = DMCreateMassMatrixLumped(dm, &dmlocalts->lumpedmassinv);CHKERRQ(ierr);
393*b4937a87SMatthew G. Knepley   ierr = VecReciprocal(dmlocalts->lumpedmassinv);CHKERRQ(ierr);
394*b4937a87SMatthew G. Knepley   ierr = VecViewFromOptions(dmlocalts->lumpedmassinv, NULL, "-lumped_mass_inv_view");CHKERRQ(ierr);
395*b4937a87SMatthew G. Knepley   PetscFunctionReturn(0);
396*b4937a87SMatthew G. Knepley }
397*b4937a87SMatthew G. Knepley 
398*b4937a87SMatthew G. Knepley /*@C
399*b4937a87SMatthew G. Knepley   DMTSDestroyRHSMassMatrix - Destroys the mass matrix and solver stored in the DMTS context, if they exist.
400*b4937a87SMatthew G. Knepley 
401*b4937a87SMatthew G. Knepley   Logically Collective
402*b4937a87SMatthew G. Knepley 
403*b4937a87SMatthew G. Knepley   Input Parameters:
404*b4937a87SMatthew G. Knepley . dm   - DM providing the mass matrix
405*b4937a87SMatthew G. Knepley 
406*b4937a87SMatthew G. Knepley   Level: developer
407*b4937a87SMatthew G. Knepley 
408*b4937a87SMatthew G. Knepley .seealso: DMTSCreateRHSMassMatrixLumped(), DMCreateMassMatrix(), DMCreateMassMatrix(), DMTS
409*b4937a87SMatthew G. Knepley @*/
410*b4937a87SMatthew G. Knepley PetscErrorCode DMTSDestroyRHSMassMatrix(DM dm)
411*b4937a87SMatthew G. Knepley {
412*b4937a87SMatthew G. Knepley   DMTS           tdm;
413*b4937a87SMatthew G. Knepley   DMTS_Local    *dmlocalts;
414*b4937a87SMatthew G. Knepley   PetscErrorCode ierr;
415*b4937a87SMatthew G. Knepley 
416*b4937a87SMatthew G. Knepley   PetscFunctionBegin;
417*b4937a87SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
418*b4937a87SMatthew G. Knepley   ierr = DMGetDMTSWrite(dm, &tdm);CHKERRQ(ierr);
419*b4937a87SMatthew G. Knepley   ierr = DMLocalTSGetContext(dm, tdm, &dmlocalts);CHKERRQ(ierr);
420*b4937a87SMatthew G. Knepley   ierr = VecDestroy(&dmlocalts->lumpedmassinv);CHKERRQ(ierr);
421*b4937a87SMatthew G. Knepley   ierr = MatDestroy(&dmlocalts->mass);CHKERRQ(ierr);
422*b4937a87SMatthew G. Knepley   ierr = KSPDestroy(&dmlocalts->kspmass);CHKERRQ(ierr);
423*b4937a87SMatthew G. Knepley   PetscFunctionReturn(0);
424*b4937a87SMatthew G. Knepley }
425