xref: /petsc/src/dm/impls/shell/dmshell.c (revision 2fe279fdf3e687a416e4eadb7d3c7a82d60442c6)
1fe1899a2SJed Brown #include <petscdmshell.h> /*I    "petscdmshell.h"  I*/
207475bc1SBarry Smith #include <petscmat.h>
3af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
4fe1899a2SJed Brown 
5fe1899a2SJed Brown typedef struct {
6fe1899a2SJed Brown   Vec        Xglobal;
7dc43b69eSJed Brown   Vec        Xlocal;
8fe1899a2SJed Brown   Mat        A;
9a94b16f6SRichard Tran Mills   VecScatter gtol;
10a94b16f6SRichard Tran Mills   VecScatter ltog;
11f089877aSRichard Tran Mills   VecScatter ltol;
12fef3a512SBarry Smith   void      *ctx;
1309904cd0SBarry Smith   PetscErrorCode (*destroyctx)(void *);
14fe1899a2SJed Brown } DM_Shell;
15fe1899a2SJed Brown 
167a108d1dSBarry Smith /*@
1720f4b53cSBarry Smith    DMGlobalToLocalBeginDefaultShell - Uses the GlobalToLocal `VecScatter` context set by the user to begin a global to local scatter
1820f4b53cSBarry Smith 
198d359177SBarry Smith   Collective
208d359177SBarry Smith 
214165533cSJose E. Roman    Input Parameters:
2220f4b53cSBarry Smith +  dm - `DMSHELL`
238d359177SBarry Smith .  g - global vector
2420f4b53cSBarry Smith .  mode - `InsertMode`
258d359177SBarry Smith -  l - local vector
268d359177SBarry Smith 
277a108d1dSBarry Smith    Level: advanced
288d359177SBarry Smith 
2920f4b53cSBarry Smith    Note:
3020f4b53cSBarry Smith    This is not normally called directly by user code, generally user code calls `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()`. If the user provides their own custom routines to `DMShellSetLocalToGlobal()` then those routines might have reason to call this function.
317a108d1dSBarry Smith 
3220f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMGlobalToLocalEndDefaultShell()`
338d359177SBarry Smith @*/
34d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalBeginDefaultShell(DM dm, Vec g, InsertMode mode, Vec l)
35d71ae5a4SJacob Faibussowitsch {
368d359177SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
378d359177SBarry Smith 
388d359177SBarry Smith   PetscFunctionBegin;
397a8be351SBarry Smith   PetscCheck(shell->gtol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
409566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->gtol, g, l, mode, SCATTER_FORWARD));
413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
428d359177SBarry Smith }
438d359177SBarry Smith 
447a108d1dSBarry Smith /*@
4520f4b53cSBarry Smith    DMGlobalToLocalEndDefaultShell - Uses the GlobalToLocal `VecScatter` context set by the user to end a global to local scatter
468d359177SBarry Smith    Collective
478d359177SBarry Smith 
484165533cSJose E. Roman    Input Parameters:
4920f4b53cSBarry Smith +  dm - `DMSHELL`
508d359177SBarry Smith .  g - global vector
5120f4b53cSBarry Smith .  mode - `InsertMode`
528d359177SBarry Smith -  l - local vector
538d359177SBarry Smith 
547a108d1dSBarry Smith    Level: advanced
558d359177SBarry Smith 
5620f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMGlobalToLocalBeginDefaultShell()`
578d359177SBarry Smith @*/
58d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalEndDefaultShell(DM dm, Vec g, InsertMode mode, Vec l)
59d71ae5a4SJacob Faibussowitsch {
608d359177SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
618d359177SBarry Smith 
628d359177SBarry Smith   PetscFunctionBegin;
637a8be351SBarry Smith   PetscCheck(shell->gtol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
649566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->gtol, g, l, mode, SCATTER_FORWARD));
653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
668d359177SBarry Smith }
678d359177SBarry Smith 
68c5076b69SRichard Tran Mills /*@
6920f4b53cSBarry Smith    DMLocalToGlobalBeginDefaultShell - Uses the LocalToGlobal `VecScatter` context set by the user to begin a local to global scatter
70c5076b69SRichard Tran Mills    Collective
71c5076b69SRichard Tran Mills 
724165533cSJose E. Roman    Input Parameters:
7320f4b53cSBarry Smith +  dm - `DMSHELL`
74c5076b69SRichard Tran Mills .  l - local vector
7520f4b53cSBarry Smith .  mode - `InsertMode`
76c5076b69SRichard Tran Mills -  g - global vector
77c5076b69SRichard Tran Mills 
78c5076b69SRichard Tran Mills    Level: advanced
79c5076b69SRichard Tran Mills 
8020f4b53cSBarry Smith    Note:
8120f4b53cSBarry Smith    This is not normally called directly by user code, generally user code calls `DMLocalToGlobalBegin()` and `DMLocalToGlobalEnd()`. If the user provides their own custom routines to `DMShellSetLocalToGlobal()` then those routines might have reason to call this function.
82c5076b69SRichard Tran Mills 
8320f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMLocalToGlobalEndDefaultShell()`
84c5076b69SRichard Tran Mills @*/
85d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalBeginDefaultShell(DM dm, Vec l, InsertMode mode, Vec g)
86d71ae5a4SJacob Faibussowitsch {
87c5076b69SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
88c5076b69SRichard Tran Mills 
89c5076b69SRichard Tran Mills   PetscFunctionBegin;
907a8be351SBarry Smith   PetscCheck(shell->ltog, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
919566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->ltog, l, g, mode, SCATTER_FORWARD));
923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
93c5076b69SRichard Tran Mills }
94c5076b69SRichard Tran Mills 
95c5076b69SRichard Tran Mills /*@
9620f4b53cSBarry Smith    DMLocalToGlobalEndDefaultShell - Uses the LocalToGlobal `VecScatter` context set by the user to end a local to global scatter
97c5076b69SRichard Tran Mills    Collective
98c5076b69SRichard Tran Mills 
994165533cSJose E. Roman    Input Parameters:
10020f4b53cSBarry Smith +  dm - `DMSHELL`
101c5076b69SRichard Tran Mills .  l - local vector
10220f4b53cSBarry Smith .  mode - `InsertMode`
103c5076b69SRichard Tran Mills -  g - global vector
104c5076b69SRichard Tran Mills 
105c5076b69SRichard Tran Mills    Level: advanced
106c5076b69SRichard Tran Mills 
10720f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMLocalToGlobalBeginDefaultShell()`
108c5076b69SRichard Tran Mills @*/
109d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalEndDefaultShell(DM dm, Vec l, InsertMode mode, Vec g)
110d71ae5a4SJacob Faibussowitsch {
111c5076b69SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
112c5076b69SRichard Tran Mills 
113c5076b69SRichard Tran Mills   PetscFunctionBegin;
1147a8be351SBarry Smith   PetscCheck(shell->ltog, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
1159566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->ltog, l, g, mode, SCATTER_FORWARD));
1163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
117c5076b69SRichard Tran Mills }
118c5076b69SRichard Tran Mills 
119f3db62a7SRichard Tran Mills /*@
12020f4b53cSBarry Smith    DMLocalToLocalBeginDefaultShell - Uses the LocalToLocal `VecScatter` context set by the user to begin a local to local scatter
121f3db62a7SRichard Tran Mills    Collective
122f3db62a7SRichard Tran Mills 
1234165533cSJose E. Roman    Input Parameters:
12420f4b53cSBarry Smith +  dm - `DMSHELL`
125f3db62a7SRichard Tran Mills .  g - the original local vector
12620f4b53cSBarry Smith -  mode - `InsertMode`
127f3db62a7SRichard Tran Mills 
128f3db62a7SRichard Tran Mills    Output Parameter:
129f3db62a7SRichard Tran Mills .  l  - the local vector with correct ghost values
130f3db62a7SRichard Tran Mills 
131f3db62a7SRichard Tran Mills    Level: advanced
132f3db62a7SRichard Tran Mills 
13320f4b53cSBarry Smith    Note:
13420f4b53cSBarry Smith    This is not normally called directly by user code, generally user code calls `DMLocalToLocalBegin()` and `DMLocalToLocalEnd()`. If the user provides their own custom routines to `DMShellSetLocalToLocal()` then those routines might have reason to call this function.
135f3db62a7SRichard Tran Mills 
13620f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMLocalToLocalEndDefaultShell()`
137f3db62a7SRichard Tran Mills @*/
138d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalBeginDefaultShell(DM dm, Vec g, InsertMode mode, Vec l)
139d71ae5a4SJacob Faibussowitsch {
140f3db62a7SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
141f3db62a7SRichard Tran Mills 
142f3db62a7SRichard Tran Mills   PetscFunctionBegin;
1437a8be351SBarry Smith   PetscCheck(shell->ltol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToLocalVecScatter()");
1449566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->ltol, g, l, mode, SCATTER_FORWARD));
1453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
146f3db62a7SRichard Tran Mills }
147f3db62a7SRichard Tran Mills 
148f3db62a7SRichard Tran Mills /*@
14920f4b53cSBarry Smith    DMLocalToLocalEndDefaultShell - Uses the LocalToLocal `VecScatter` context set by the user to end a local to local scatter
150f3db62a7SRichard Tran Mills    Collective
151f3db62a7SRichard Tran Mills 
1524165533cSJose E. Roman    Input Parameters:
15320f4b53cSBarry Smith +  dm - `DMSHELL`
154f3db62a7SRichard Tran Mills .  g - the original local vector
15520f4b53cSBarry Smith -  mode - `InsertMode`
156f3db62a7SRichard Tran Mills 
157f3db62a7SRichard Tran Mills    Output Parameter:
158f3db62a7SRichard Tran Mills .  l  - the local vector with correct ghost values
159f3db62a7SRichard Tran Mills 
160f3db62a7SRichard Tran Mills    Level: advanced
161f3db62a7SRichard Tran Mills 
16220f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMLocalToLocalBeginDefaultShell()`
163f3db62a7SRichard Tran Mills @*/
164d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalEndDefaultShell(DM dm, Vec g, InsertMode mode, Vec l)
165d71ae5a4SJacob Faibussowitsch {
166f3db62a7SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
167f3db62a7SRichard Tran Mills 
168f3db62a7SRichard Tran Mills   PetscFunctionBegin;
1697a8be351SBarry Smith   PetscCheck(shell->ltol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
1709566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->ltol, g, l, mode, SCATTER_FORWARD));
1713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
172f3db62a7SRichard Tran Mills }
173c5076b69SRichard Tran Mills 
174d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCreateMatrix_Shell(DM dm, Mat *J)
175d71ae5a4SJacob Faibussowitsch {
176fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
177fe1899a2SJed Brown   Mat       A;
178fe1899a2SJed Brown 
179fe1899a2SJed Brown   PetscFunctionBegin;
180fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
181064a246eSJacob Faibussowitsch   PetscValidPointer(J, 2);
1827bde9f88SJed Brown   if (!shell->A) {
1837bde9f88SJed Brown     if (shell->Xglobal) {
1847bde9f88SJed Brown       PetscInt m, M;
1859566063dSJacob Faibussowitsch       PetscCall(PetscInfo(dm, "Naively creating matrix using global vector distribution without preallocation\n"));
1869566063dSJacob Faibussowitsch       PetscCall(VecGetSize(shell->Xglobal, &M));
1879566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(shell->Xglobal, &m));
1889566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)dm), &shell->A));
1899566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(shell->A, m, m, M, M));
1909566063dSJacob Faibussowitsch       PetscCall(MatSetType(shell->A, dm->mattype));
1919566063dSJacob Faibussowitsch       PetscCall(MatSetUp(shell->A));
192ce94432eSBarry Smith     } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector");
1937bde9f88SJed Brown   }
194fe1899a2SJed Brown   A = shell->A;
1959566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(A, MAT_SHARE_NONZERO_PATTERN, J));
1969566063dSJacob Faibussowitsch   PetscCall(MatSetDM(*J, dm));
1973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
198fe1899a2SJed Brown }
199fe1899a2SJed Brown 
200d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateGlobalVector_Shell(DM dm, Vec *gvec)
201d71ae5a4SJacob Faibussowitsch {
202fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
203fe1899a2SJed Brown   Vec       X;
204fe1899a2SJed Brown 
205fe1899a2SJed Brown   PetscFunctionBegin;
206fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
207fe1899a2SJed Brown   PetscValidPointer(gvec, 2);
208ea78f98cSLisandro Dalcin   *gvec = NULL;
209fe1899a2SJed Brown   X     = shell->Xglobal;
2107a8be351SBarry Smith   PetscCheck(X, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
21106f803f6SStefano Zampini   /* Need to create a copy in order to attach the DM to the vector */
2129566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(X, gvec));
2139566063dSJacob Faibussowitsch   PetscCall(VecZeroEntries(*gvec));
2149566063dSJacob Faibussowitsch   PetscCall(VecSetDM(*gvec, dm));
2153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
216fe1899a2SJed Brown }
217fe1899a2SJed Brown 
218d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLocalVector_Shell(DM dm, Vec *gvec)
219d71ae5a4SJacob Faibussowitsch {
220dc43b69eSJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
221dc43b69eSJed Brown   Vec       X;
222dc43b69eSJed Brown 
223dc43b69eSJed Brown   PetscFunctionBegin;
224dc43b69eSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
225dc43b69eSJed Brown   PetscValidPointer(gvec, 2);
226ea78f98cSLisandro Dalcin   *gvec = NULL;
227dc43b69eSJed Brown   X     = shell->Xlocal;
2287a8be351SBarry Smith   PetscCheck(X, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()");
22906f803f6SStefano Zampini   /* Need to create a copy in order to attach the DM to the vector */
2309566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(X, gvec));
2319566063dSJacob Faibussowitsch   PetscCall(VecZeroEntries(*gvec));
2329566063dSJacob Faibussowitsch   PetscCall(VecSetDM(*gvec, dm));
2333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
234dc43b69eSJed Brown }
235dc43b69eSJed Brown 
236fef3a512SBarry Smith /*@
23709904cd0SBarry Smith    DMShellSetDestroyContext - set a function that destroys the context provided with `DMShellSetContext()`
23809904cd0SBarry Smith 
23909904cd0SBarry Smith    Collective
24009904cd0SBarry Smith 
24109904cd0SBarry Smith    Input Parameters:
242*2fe279fdSBarry Smith +  dm - the `DM` to attach the `destroyctx()` function to
243*2fe279fdSBarry Smith -  destroyctx - the function that destroys the context
24409904cd0SBarry Smith 
24509904cd0SBarry Smith    Level: advanced
24609904cd0SBarry Smith 
24720f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetContext()`, `DMShellGetContext()`
24809904cd0SBarry Smith @*/
249d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetDestroyContext(DM dm, PetscErrorCode (*destroyctx)(void *))
250d71ae5a4SJacob Faibussowitsch {
25109904cd0SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
25209904cd0SBarry Smith   PetscBool isshell;
25309904cd0SBarry Smith 
25409904cd0SBarry Smith   PetscFunctionBegin;
25509904cd0SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
25609904cd0SBarry Smith   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
2573ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
25809904cd0SBarry Smith   shell->destroyctx = destroyctx;
2593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
26009904cd0SBarry Smith }
26109904cd0SBarry Smith 
26209904cd0SBarry Smith /*@
26320f4b53cSBarry Smith    DMShellSetContext - set some data to be usable by this `DMSHELL`
264fef3a512SBarry Smith 
265fef3a512SBarry Smith    Collective
266fef3a512SBarry Smith 
2674165533cSJose E. Roman    Input Parameters:
26820f4b53cSBarry Smith +  dm - `DMSHELL`
269fef3a512SBarry Smith -  ctx - the context
270fef3a512SBarry Smith 
271fef3a512SBarry Smith    Level: advanced
272fef3a512SBarry Smith 
27320f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateMatrix()`, `DMShellGetContext()`
274fef3a512SBarry Smith @*/
275d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetContext(DM dm, void *ctx)
276d71ae5a4SJacob Faibussowitsch {
277fef3a512SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
278fef3a512SBarry Smith   PetscBool isshell;
279fef3a512SBarry Smith 
280fef3a512SBarry Smith   PetscFunctionBegin;
281fef3a512SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2829566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
2833ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
284fef3a512SBarry Smith   shell->ctx = ctx;
2853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
286fef3a512SBarry Smith }
287fef3a512SBarry Smith 
288fef3a512SBarry Smith /*@
28920f4b53cSBarry Smith    DMShellGetContext - Returns the user-provided context associated to the `DMSHELL`
290fef3a512SBarry Smith 
291fef3a512SBarry Smith    Collective
292fef3a512SBarry Smith 
2934165533cSJose E. Roman    Input Parameter:
29420f4b53cSBarry Smith .  dm - `DMSHELL`
295fef3a512SBarry Smith 
2964165533cSJose E. Roman    Output Parameter:
297fef3a512SBarry Smith .  ctx - the context
298fef3a512SBarry Smith 
299fef3a512SBarry Smith    Level: advanced
300fef3a512SBarry Smith 
30120f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateMatrix()`, `DMShellSetContext()`
302fef3a512SBarry Smith @*/
303d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetContext(DM dm, void *ctx)
304d71ae5a4SJacob Faibussowitsch {
305fef3a512SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
306fef3a512SBarry Smith   PetscBool isshell;
307fef3a512SBarry Smith 
308fef3a512SBarry Smith   PetscFunctionBegin;
309fef3a512SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3109566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
3117a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
3123ec1f749SStefano Zampini   *(void **)ctx = shell->ctx;
3133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
314fef3a512SBarry Smith }
315fef3a512SBarry Smith 
316fe1899a2SJed Brown /*@
31720f4b53cSBarry Smith    DMShellSetMatrix - sets a template matrix associated with the `DMSHELL`
318fe1899a2SJed Brown 
319fe1899a2SJed Brown    Collective
320fe1899a2SJed Brown 
3214165533cSJose E. Roman    Input Parameters:
32220f4b53cSBarry Smith +  dm - `DMSHELL`
323fe1899a2SJed Brown -  J - template matrix
324fe1899a2SJed Brown 
325fe1899a2SJed Brown    Level: advanced
326fe1899a2SJed Brown 
327*2fe279fdSBarry Smith    Developer Note:
32820f4b53cSBarry Smith     To avoid circular references, if `J` is already associated to the same `DM`, then `MatDuplicate`(`SHARE_NONZERO_PATTERN`) is called, followed by removing the `DM` reference from the private template.
32906f803f6SStefano Zampini 
33020f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateMatrix()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
331fe1899a2SJed Brown @*/
332d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetMatrix(DM dm, Mat J)
333d71ae5a4SJacob Faibussowitsch {
334fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
3358c87107bSJed Brown   PetscBool isshell;
33606f803f6SStefano Zampini   DM        mdm;
337fe1899a2SJed Brown 
338fe1899a2SJed Brown   PetscFunctionBegin;
3398c87107bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3408c87107bSJed Brown   PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
3419566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
3423ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
3433ba16761SJacob Faibussowitsch   if (J == shell->A) PetscFunctionReturn(PETSC_SUCCESS);
3449566063dSJacob Faibussowitsch   PetscCall(MatGetDM(J, &mdm));
3459566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)J));
3469566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&shell->A));
34706f803f6SStefano Zampini   if (mdm == dm) {
3489566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(J, MAT_SHARE_NONZERO_PATTERN, &shell->A));
3499566063dSJacob Faibussowitsch     PetscCall(MatSetDM(shell->A, NULL));
35006f803f6SStefano Zampini   } else shell->A = J;
3513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
352fe1899a2SJed Brown }
353fe1899a2SJed Brown 
354fe1899a2SJed Brown /*@C
35520f4b53cSBarry Smith    DMShellSetCreateMatrix - sets the routine to create a matrix associated with the `DMSHELL`
356fe1899a2SJed Brown 
35720f4b53cSBarry Smith    Logically Collective
358fe1899a2SJed Brown 
3594165533cSJose E. Roman    Input Parameters:
36020f4b53cSBarry Smith +  dm - the `DMSHELL`
361fe1899a2SJed Brown -  func - the function to create a matrix
362fe1899a2SJed Brown 
363fe1899a2SJed Brown    Level: advanced
364fe1899a2SJed Brown 
36520f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateMatrix()`, `DMShellSetMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
366fe1899a2SJed Brown @*/
367d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateMatrix(DM dm, PetscErrorCode (*func)(DM, Mat *))
368d71ae5a4SJacob Faibussowitsch {
369fe1899a2SJed Brown   PetscFunctionBegin;
370fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
371fe1899a2SJed Brown   dm->ops->creatematrix = func;
3723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
373fe1899a2SJed Brown }
374fe1899a2SJed Brown 
375fe1899a2SJed Brown /*@
37620f4b53cSBarry Smith    DMShellSetGlobalVector - sets a template global vector associated with the `DMSHELL`
377fe1899a2SJed Brown 
37820f4b53cSBarry Smith    Logically Collective
379fe1899a2SJed Brown 
3804165533cSJose E. Roman    Input Parameters:
38120f4b53cSBarry Smith +  dm - `DMSHELL`
382fe1899a2SJed Brown -  X - template vector
383fe1899a2SJed Brown 
384fe1899a2SJed Brown    Level: advanced
385fe1899a2SJed Brown 
38620f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateGlobalVector()`, `DMShellSetMatrix()`, `DMShellSetCreateGlobalVector()`
387fe1899a2SJed Brown @*/
388d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetGlobalVector(DM dm, Vec X)
389d71ae5a4SJacob Faibussowitsch {
390fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
3918c87107bSJed Brown   PetscBool isshell;
392cca7ec1eSBarry Smith   DM        vdm;
393fe1899a2SJed Brown 
394fe1899a2SJed Brown   PetscFunctionBegin;
3958c87107bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3968c87107bSJed Brown   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
3979566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
3983ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
3999566063dSJacob Faibussowitsch   PetscCall(VecGetDM(X, &vdm));
400cca7ec1eSBarry Smith   /*
401cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
402cca7ec1eSBarry Smith       with the same DM then the current base global vector for the DM is ok and if we replace it with the new one
403cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
404cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
405cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
406cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
407cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
408cca7ec1eSBarry Smith       for pointing out the problem.
409cca7ec1eSBarry Smith    */
4103ba16761SJacob Faibussowitsch   if (vdm == dm) PetscFunctionReturn(PETSC_SUCCESS);
4119566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)X));
4129566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xglobal));
413fe1899a2SJed Brown   shell->Xglobal = X;
4143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
415fe1899a2SJed Brown }
416fe1899a2SJed Brown 
41704d741b1SMatthew G. Knepley /*@
41820f4b53cSBarry Smith   DMShellGetGlobalVector - Returns the template global vector associated with the `DMSHELL`, or `NULL` if it was not set
41904d741b1SMatthew G. Knepley 
42020f4b53cSBarry Smith    Not Collective
42104d741b1SMatthew G. Knepley 
4224165533cSJose E. Roman    Input Parameters:
42320f4b53cSBarry Smith +  dm - `DMSHELL`
42404d741b1SMatthew G. Knepley -  X - template vector
42504d741b1SMatthew G. Knepley 
42604d741b1SMatthew G. Knepley    Level: advanced
42704d741b1SMatthew G. Knepley 
42820f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetGlobalVector()`, `DMShellSetCreateGlobalVector()`, `DMCreateGlobalVector()`
42904d741b1SMatthew G. Knepley @*/
430d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetGlobalVector(DM dm, Vec *X)
431d71ae5a4SJacob Faibussowitsch {
43204d741b1SMatthew G. Knepley   DM_Shell *shell = (DM_Shell *)dm->data;
43304d741b1SMatthew G. Knepley   PetscBool isshell;
43404d741b1SMatthew G. Knepley 
43504d741b1SMatthew G. Knepley   PetscFunctionBegin;
43604d741b1SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
43704d741b1SMatthew G. Knepley   PetscValidPointer(X, 2);
4389566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
4393ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
44004d741b1SMatthew G. Knepley   *X = shell->Xglobal;
4413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
44204d741b1SMatthew G. Knepley }
44304d741b1SMatthew G. Knepley 
444fe1899a2SJed Brown /*@C
44520f4b53cSBarry Smith    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the `DMSHELL`
446fe1899a2SJed Brown 
447fe1899a2SJed Brown    Logically Collective
448fe1899a2SJed Brown 
4494165533cSJose E. Roman    Input Parameters:
45020f4b53cSBarry Smith +  dm - the `DMSHELL`
451fe1899a2SJed Brown -  func - the creation routine
452fe1899a2SJed Brown 
453fe1899a2SJed Brown    Level: advanced
454fe1899a2SJed Brown 
45520f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetGlobalVector()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
456fe1899a2SJed Brown @*/
457d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateGlobalVector(DM dm, PetscErrorCode (*func)(DM, Vec *))
458d71ae5a4SJacob Faibussowitsch {
459fe1899a2SJed Brown   PetscFunctionBegin;
460fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
461fe1899a2SJed Brown   dm->ops->createglobalvector = func;
4623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
463fe1899a2SJed Brown }
464fe1899a2SJed Brown 
465dc43b69eSJed Brown /*@
46620f4b53cSBarry Smith    DMShellSetLocalVector - sets a template local vector associated with the `DMSHELL`
467dc43b69eSJed Brown 
46820f4b53cSBarry Smith    Logically Collective
469dc43b69eSJed Brown 
4704165533cSJose E. Roman    Input Parameters:
47120f4b53cSBarry Smith +  dm - `DMSHELL`
472dc43b69eSJed Brown -  X - template vector
473dc43b69eSJed Brown 
474dc43b69eSJed Brown    Level: advanced
475dc43b69eSJed Brown 
47620f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateLocalVector()`, `DMShellSetMatrix()`, `DMShellSetCreateLocalVector()`
477dc43b69eSJed Brown @*/
478d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalVector(DM dm, Vec X)
479d71ae5a4SJacob Faibussowitsch {
480dc43b69eSJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
481dc43b69eSJed Brown   PetscBool isshell;
482cca7ec1eSBarry Smith   DM        vdm;
483dc43b69eSJed Brown 
484dc43b69eSJed Brown   PetscFunctionBegin;
485dc43b69eSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
486dc43b69eSJed Brown   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
4879566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
4883ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
4899566063dSJacob Faibussowitsch   PetscCall(VecGetDM(X, &vdm));
490cca7ec1eSBarry Smith   /*
491cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
492cca7ec1eSBarry Smith       with the same DM then the current base global vector for the DM is ok and if we replace it with the new one
493cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
494cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
495cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
496cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
497cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
498cca7ec1eSBarry Smith       for pointing out the problem.
499cca7ec1eSBarry Smith    */
5003ba16761SJacob Faibussowitsch   if (vdm == dm) PetscFunctionReturn(PETSC_SUCCESS);
5019566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)X));
5029566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xlocal));
503dc43b69eSJed Brown   shell->Xlocal = X;
5043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
505dc43b69eSJed Brown }
506dc43b69eSJed Brown 
507dc43b69eSJed Brown /*@C
50820f4b53cSBarry Smith    DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the `DMSHELL`
509dc43b69eSJed Brown 
510dc43b69eSJed Brown    Logically Collective
511dc43b69eSJed Brown 
5124165533cSJose E. Roman    Input Parameters:
51320f4b53cSBarry Smith +  dm - the `DMSHELL`
514dc43b69eSJed Brown -  func - the creation routine
515dc43b69eSJed Brown 
516dc43b69eSJed Brown    Level: advanced
517dc43b69eSJed Brown 
51820f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetLocalVector()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
519dc43b69eSJed Brown @*/
520d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateLocalVector(DM dm, PetscErrorCode (*func)(DM, Vec *))
521d71ae5a4SJacob Faibussowitsch {
522dc43b69eSJed Brown   PetscFunctionBegin;
523dc43b69eSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
524dc43b69eSJed Brown   dm->ops->createlocalvector = func;
5253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
526dc43b69eSJed Brown }
527dc43b69eSJed Brown 
5288339e6d0SRichard Tran Mills /*@C
5298339e6d0SRichard Tran Mills    DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter
5308339e6d0SRichard Tran Mills 
531d083f849SBarry Smith    Logically Collective on dm
5328339e6d0SRichard Tran Mills 
5334165533cSJose E. Roman    Input Parameters
53420f4b53cSBarry Smith +  dm - the `DMSHELL`
5358339e6d0SRichard Tran Mills .  begin - the routine that begins the global to local scatter
5368339e6d0SRichard Tran Mills -  end - the routine that ends the global to local scatter
5378339e6d0SRichard Tran Mills 
5388339e6d0SRichard Tran Mills    Level: advanced
5398339e6d0SRichard Tran Mills 
54020f4b53cSBarry Smith    Note:
54120f4b53cSBarry Smith     If these functions are not provided but `DMShellSetGlobalToLocalVecScatter()` is called then
54220f4b53cSBarry Smith    `DMGlobalToLocalBeginDefaultShell()`/`DMGlobalToLocalEndDefaultShell()` are used to to perform the transfers
54320f4b53cSBarry Smith 
54420f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetLocalToGlobal()`, `DMGlobalToLocalBeginDefaultShell()`, `DMGlobalToLocalEndDefaultShell()`
5458339e6d0SRichard Tran Mills @*/
546d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetGlobalToLocal(DM dm, PetscErrorCode (*begin)(DM, Vec, InsertMode, Vec), PetscErrorCode (*end)(DM, Vec, InsertMode, Vec))
547d71ae5a4SJacob Faibussowitsch {
5488339e6d0SRichard Tran Mills   PetscFunctionBegin;
5492d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5508339e6d0SRichard Tran Mills   dm->ops->globaltolocalbegin = begin;
5518339e6d0SRichard Tran Mills   dm->ops->globaltolocalend   = end;
5523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5538339e6d0SRichard Tran Mills }
5548339e6d0SRichard Tran Mills 
5558339e6d0SRichard Tran Mills /*@C
5568339e6d0SRichard Tran Mills    DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter
5578339e6d0SRichard Tran Mills 
558d083f849SBarry Smith    Logically Collective on dm
5598339e6d0SRichard Tran Mills 
5604165533cSJose E. Roman    Input Parameters
56120f4b53cSBarry Smith +  dm - the `DMSHELL`
5628339e6d0SRichard Tran Mills .  begin - the routine that begins the local to global scatter
5638339e6d0SRichard Tran Mills -  end - the routine that ends the local to global scatter
5648339e6d0SRichard Tran Mills 
5658339e6d0SRichard Tran Mills    Level: advanced
5668339e6d0SRichard Tran Mills 
56720f4b53cSBarry Smith    Note:
56820f4b53cSBarry Smith     If these functions are not provided but `DMShellSetLocalToGlobalVecScatter()` is called then
56920f4b53cSBarry Smith    `DMLocalToGlobalBeginDefaultShell()`/`DMLocalToGlobalEndDefaultShell()` are used to to perform the transfers
57020f4b53cSBarry Smith 
57120f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetGlobalToLocal()`
5728339e6d0SRichard Tran Mills @*/
573d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalToGlobal(DM dm, PetscErrorCode (*begin)(DM, Vec, InsertMode, Vec), PetscErrorCode (*end)(DM, Vec, InsertMode, Vec))
574d71ae5a4SJacob Faibussowitsch {
5758339e6d0SRichard Tran Mills   PetscFunctionBegin;
5762d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5778339e6d0SRichard Tran Mills   dm->ops->localtoglobalbegin = begin;
5788339e6d0SRichard Tran Mills   dm->ops->localtoglobalend   = end;
5793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5808339e6d0SRichard Tran Mills }
5818339e6d0SRichard Tran Mills 
582f3db62a7SRichard Tran Mills /*@C
583f3db62a7SRichard Tran Mills    DMShellSetLocalToLocal - Sets the routines used to perform a local to local scatter
584f3db62a7SRichard Tran Mills 
585d083f849SBarry Smith    Logically Collective on dm
586f3db62a7SRichard Tran Mills 
5874165533cSJose E. Roman    Input Parameters
58820f4b53cSBarry Smith +  dm - the `DMSHELL`
589f3db62a7SRichard Tran Mills .  begin - the routine that begins the local to local scatter
590f3db62a7SRichard Tran Mills -  end - the routine that ends the local to local scatter
591f3db62a7SRichard Tran Mills 
592f3db62a7SRichard Tran Mills    Level: advanced
593f3db62a7SRichard Tran Mills 
59420f4b53cSBarry Smith    Note:
59520f4b53cSBarry Smith     If these functions are not provided but `DMShellSetLocalToLocalVecScatter()` is called then
59620f4b53cSBarry Smith    `DMLocalToLocalBeginDefaultShell()`/`DMLocalToLocalEndDefaultShell()` are used to to perform the transfers
59720f4b53cSBarry Smith 
59820f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetGlobalToLocal()`, `DMLocalToLocalBeginDefaultShell()`, `DMLocalToLocalEndDefaultShell()`
599f3db62a7SRichard Tran Mills @*/
600d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalToLocal(DM dm, PetscErrorCode (*begin)(DM, Vec, InsertMode, Vec), PetscErrorCode (*end)(DM, Vec, InsertMode, Vec))
601d71ae5a4SJacob Faibussowitsch {
602f3db62a7SRichard Tran Mills   PetscFunctionBegin;
6032d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
604f3db62a7SRichard Tran Mills   dm->ops->localtolocalbegin = begin;
605f3db62a7SRichard Tran Mills   dm->ops->localtolocalend   = end;
6063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
607f3db62a7SRichard Tran Mills }
608f3db62a7SRichard Tran Mills 
60981634712SRichard Tran Mills /*@
61020f4b53cSBarry Smith    DMShellSetGlobalToLocalVecScatter - Sets a `VecScatter` context for global to local communication
61181634712SRichard Tran Mills 
612d083f849SBarry Smith    Logically Collective on dm
61381634712SRichard Tran Mills 
6144165533cSJose E. Roman    Input Parameters
61520f4b53cSBarry Smith +  dm - the `DMSHELL`
61620f4b53cSBarry Smith -  gtol - the global to local `VecScatter` context
61781634712SRichard Tran Mills 
61881634712SRichard Tran Mills    Level: advanced
61981634712SRichard Tran Mills 
62020f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetGlobalToLocal()`, `DMGlobalToLocalBeginDefaultShell()`, `DMGlobalToLocalEndDefaultShell()`
62181634712SRichard Tran Mills @*/
622d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter gtol)
623d71ae5a4SJacob Faibussowitsch {
62481634712SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
62581634712SRichard Tran Mills 
626b300e4a8SRichard Tran Mills   PetscFunctionBegin;
6272d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
62897929ea7SJunchao Zhang   PetscValidHeaderSpecific(gtol, PETSCSF_CLASSID, 2);
6299566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)gtol));
6309566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->gtol));
63181634712SRichard Tran Mills   shell->gtol = gtol;
6323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
63381634712SRichard Tran Mills }
63481634712SRichard Tran Mills 
635988ea7d6SRichard Tran Mills /*@
63620f4b53cSBarry Smith    DMShellSetLocalToGlobalVecScatter - Sets a` VecScatter` context for local to global communication
637988ea7d6SRichard Tran Mills 
638d083f849SBarry Smith    Logically Collective on dm
639988ea7d6SRichard Tran Mills 
6404165533cSJose E. Roman    Input Parameters
64120f4b53cSBarry Smith +  dm - the `DMSHELL`
64220f4b53cSBarry Smith -  ltog - the local to global `VecScatter` context
643988ea7d6SRichard Tran Mills 
644988ea7d6SRichard Tran Mills    Level: advanced
645988ea7d6SRichard Tran Mills 
64620f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetLocalToGlobal()`, `DMLocalToGlobalBeginDefaultShell()`, `DMLocalToGlobalEndDefaultShell()`
647988ea7d6SRichard Tran Mills @*/
648d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM dm, VecScatter ltog)
649d71ae5a4SJacob Faibussowitsch {
650988ea7d6SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
651988ea7d6SRichard Tran Mills 
652988ea7d6SRichard Tran Mills   PetscFunctionBegin;
6532d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
65497929ea7SJunchao Zhang   PetscValidHeaderSpecific(ltog, PETSCSF_CLASSID, 2);
6559566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)ltog));
6569566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltog));
657988ea7d6SRichard Tran Mills   shell->ltog = ltog;
6583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
659988ea7d6SRichard Tran Mills }
660988ea7d6SRichard Tran Mills 
661f3db62a7SRichard Tran Mills /*@
66220f4b53cSBarry Smith    DMShellSetLocalToLocalVecScatter - Sets a `VecScatter` context for local to local communication
663f3db62a7SRichard Tran Mills 
66420f4b53cSBarry Smith    Logically Collective
665f3db62a7SRichard Tran Mills 
6664165533cSJose E. Roman    Input Parameters
66720f4b53cSBarry Smith +  dm - the `DMSHELL`
66820f4b53cSBarry Smith -  ltol - the local to local `VecScatter` context
669f3db62a7SRichard Tran Mills 
670f3db62a7SRichard Tran Mills    Level: advanced
671f3db62a7SRichard Tran Mills 
67220f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetLocalToLocal()`, `DMLocalToLocalBeginDefaultShell()`, `DMLocalToLocalEndDefaultShell()`
673f3db62a7SRichard Tran Mills @*/
674d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalToLocalVecScatter(DM dm, VecScatter ltol)
675d71ae5a4SJacob Faibussowitsch {
676f3db62a7SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
677f3db62a7SRichard Tran Mills 
678f3db62a7SRichard Tran Mills   PetscFunctionBegin;
6792d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
68097929ea7SJunchao Zhang   PetscValidHeaderSpecific(ltol, PETSCSF_CLASSID, 2);
6819566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)ltol));
6829566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltol));
683f3db62a7SRichard Tran Mills   shell->ltol = ltol;
6843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
685f3db62a7SRichard Tran Mills }
686f3db62a7SRichard Tran Mills 
6879bf9660cSLawrence Mitchell /*@C
68820f4b53cSBarry Smith    DMShellSetCoarsen - Set the routine used to coarsen the `DMSHELL`
6899bf9660cSLawrence Mitchell 
69020f4b53cSBarry Smith    Logically Collective
6919bf9660cSLawrence Mitchell 
6924165533cSJose E. Roman    Input Parameters
69320f4b53cSBarry Smith +  dm - the `DMSHELL`
69420f4b53cSBarry Smith -  coarsen - the routine that coarsens the `DM`
6959bf9660cSLawrence Mitchell 
6969bf9660cSLawrence Mitchell    Level: advanced
6979bf9660cSLawrence Mitchell 
69820f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetRefine()`, `DMCoarsen()`, `DMShellGetCoarsen()`, `DMShellSetContext()`, `DMShellGetContext()`
6999bf9660cSLawrence Mitchell @*/
700d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCoarsen(DM dm, PetscErrorCode (*coarsen)(DM, MPI_Comm, DM *))
701d71ae5a4SJacob Faibussowitsch {
702f572501eSLawrence Mitchell   PetscBool isshell;
703f572501eSLawrence Mitchell 
704f572501eSLawrence Mitchell   PetscFunctionBegin;
705f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7069566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
7073ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
708f572501eSLawrence Mitchell   dm->ops->coarsen = coarsen;
7093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
710f572501eSLawrence Mitchell }
711f572501eSLawrence Mitchell 
7129bf9660cSLawrence Mitchell /*@C
71320f4b53cSBarry Smith    DMShellGetCoarsen - Get the routine used to coarsen the `DMSHELL`
7144363ddcaSBoris Boutkov 
71520f4b53cSBarry Smith    Logically Collective
7164363ddcaSBoris Boutkov 
7174165533cSJose E. Roman    Input Parameter:
71820f4b53cSBarry Smith .  dm - the `DMSHELL`
7194363ddcaSBoris Boutkov 
7204165533cSJose E. Roman    Output Parameter:
72120f4b53cSBarry Smith .  coarsen - the routine that coarsens the `DM`
7224363ddcaSBoris Boutkov 
7234363ddcaSBoris Boutkov    Level: advanced
7244363ddcaSBoris Boutkov 
72520f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCoarsen()`, `DMCoarsen()`, `DMShellSetRefine()`, `DMRefine()`
7264363ddcaSBoris Boutkov @*/
727d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCoarsen(DM dm, PetscErrorCode (**coarsen)(DM, MPI_Comm, DM *))
728d71ae5a4SJacob Faibussowitsch {
7294363ddcaSBoris Boutkov   PetscBool isshell;
7304363ddcaSBoris Boutkov 
7314363ddcaSBoris Boutkov   PetscFunctionBegin;
7324363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7339566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
7347a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
7354363ddcaSBoris Boutkov   *coarsen = dm->ops->coarsen;
7363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7374363ddcaSBoris Boutkov }
7384363ddcaSBoris Boutkov 
7394363ddcaSBoris Boutkov /*@C
74020f4b53cSBarry Smith    DMShellSetRefine - Set the routine used to refine the `DMSHELL`
7419bf9660cSLawrence Mitchell 
74220f4b53cSBarry Smith    Logically Collective
7439bf9660cSLawrence Mitchell 
7444165533cSJose E. Roman    Input Parameters
74520f4b53cSBarry Smith +  dm - the `DMSHELL`
74620f4b53cSBarry Smith -  refine - the routine that refines the `DM`
7479bf9660cSLawrence Mitchell 
7489bf9660cSLawrence Mitchell    Level: advanced
7499bf9660cSLawrence Mitchell 
75020f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCoarsen()`, `DMRefine()`, `DMShellGetRefine()`, `DMShellSetContext()`, `DMShellGetContext()`
7519bf9660cSLawrence Mitchell @*/
752d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetRefine(DM dm, PetscErrorCode (*refine)(DM, MPI_Comm, DM *))
753d71ae5a4SJacob Faibussowitsch {
754f572501eSLawrence Mitchell   PetscBool isshell;
755f572501eSLawrence Mitchell 
756f572501eSLawrence Mitchell   PetscFunctionBegin;
757f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7589566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
7593ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
760f572501eSLawrence Mitchell   dm->ops->refine = refine;
7613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
762f572501eSLawrence Mitchell }
763f572501eSLawrence Mitchell 
7649bf9660cSLawrence Mitchell /*@C
76520f4b53cSBarry Smith    DMShellGetRefine - Get the routine used to refine the `DMSHELL`
7664363ddcaSBoris Boutkov 
76720f4b53cSBarry Smith    Logically Collective
7684363ddcaSBoris Boutkov 
7694165533cSJose E. Roman    Input Parameter:
77020f4b53cSBarry Smith .  dm - the `DMSHELL`
7714363ddcaSBoris Boutkov 
7724165533cSJose E. Roman    Output Parameter:
77320f4b53cSBarry Smith .  refine - the routine that refines the `DM`
7744363ddcaSBoris Boutkov 
7754363ddcaSBoris Boutkov    Level: advanced
7764363ddcaSBoris Boutkov 
77720f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCoarsen()`, `DMCoarsen()`, `DMShellSetRefine()`, `DMRefine()`
7784363ddcaSBoris Boutkov @*/
779d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetRefine(DM dm, PetscErrorCode (**refine)(DM, MPI_Comm, DM *))
780d71ae5a4SJacob Faibussowitsch {
7814363ddcaSBoris Boutkov   PetscBool isshell;
7824363ddcaSBoris Boutkov 
7834363ddcaSBoris Boutkov   PetscFunctionBegin;
7844363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7859566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
7867a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
7874363ddcaSBoris Boutkov   *refine = dm->ops->refine;
7883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7894363ddcaSBoris Boutkov }
7904363ddcaSBoris Boutkov 
7914363ddcaSBoris Boutkov /*@C
7929bf9660cSLawrence Mitchell    DMShellSetCreateInterpolation - Set the routine used to create the interpolation operator
7939bf9660cSLawrence Mitchell 
79420f4b53cSBarry Smith    Logically Collective
7959bf9660cSLawrence Mitchell 
7964165533cSJose E. Roman    Input Parameters
79720f4b53cSBarry Smith +  dm - the `DMSHELL`
7989bf9660cSLawrence Mitchell -  interp - the routine to create the interpolation
7999bf9660cSLawrence Mitchell 
8009bf9660cSLawrence Mitchell    Level: advanced
8019bf9660cSLawrence Mitchell 
80220f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateInterpolation()`, `DMShellSetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
8039bf9660cSLawrence Mitchell @*/
804d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateInterpolation(DM dm, PetscErrorCode (*interp)(DM, DM, Mat *, Vec *))
805d71ae5a4SJacob Faibussowitsch {
806f572501eSLawrence Mitchell   PetscBool isshell;
807f572501eSLawrence Mitchell 
808f572501eSLawrence Mitchell   PetscFunctionBegin;
809f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8109566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
8113ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
812f572501eSLawrence Mitchell   dm->ops->createinterpolation = interp;
8133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
814f572501eSLawrence Mitchell }
815f572501eSLawrence Mitchell 
8163ad4599aSBarry Smith /*@C
8174363ddcaSBoris Boutkov    DMShellGetCreateInterpolation - Get the routine used to create the interpolation operator
8184363ddcaSBoris Boutkov 
81920f4b53cSBarry Smith    Logically Collective
8204363ddcaSBoris Boutkov 
8214165533cSJose E. Roman    Input Parameter:
82220f4b53cSBarry Smith .  dm - the `DMSHELL`
823a4a986ddSBoris Boutkov 
8244165533cSJose E. Roman    Output Parameter:
8254165533cSJose E. Roman .  interp - the routine to create the interpolation
8264363ddcaSBoris Boutkov 
8274363ddcaSBoris Boutkov    Level: advanced
8284363ddcaSBoris Boutkov 
82920f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellGetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
8304363ddcaSBoris Boutkov @*/
831d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCreateInterpolation(DM dm, PetscErrorCode (**interp)(DM, DM, Mat *, Vec *))
832d71ae5a4SJacob Faibussowitsch {
8334363ddcaSBoris Boutkov   PetscBool isshell;
8344363ddcaSBoris Boutkov 
8354363ddcaSBoris Boutkov   PetscFunctionBegin;
8364363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8379566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
8387a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
8394363ddcaSBoris Boutkov   *interp = dm->ops->createinterpolation;
8403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8414363ddcaSBoris Boutkov }
8424363ddcaSBoris Boutkov 
8434363ddcaSBoris Boutkov /*@C
8443ad4599aSBarry Smith    DMShellSetCreateRestriction - Set the routine used to create the restriction operator
8453ad4599aSBarry Smith 
84620f4b53cSBarry Smith    Logically Collective
8473ad4599aSBarry Smith 
8484165533cSJose E. Roman    Input Parameters
84920f4b53cSBarry Smith +  dm - the `DMSHELL`
8503ad4599aSBarry Smith -  striction- the routine to create the restriction
8513ad4599aSBarry Smith 
8523ad4599aSBarry Smith    Level: advanced
8533ad4599aSBarry Smith 
85420f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
8553ad4599aSBarry Smith @*/
856d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateRestriction(DM dm, PetscErrorCode (*restriction)(DM, DM, Mat *))
857d71ae5a4SJacob Faibussowitsch {
8583ad4599aSBarry Smith   PetscBool isshell;
8593ad4599aSBarry Smith 
8603ad4599aSBarry Smith   PetscFunctionBegin;
8613ad4599aSBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8629566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
8633ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
8643ad4599aSBarry Smith   dm->ops->createrestriction = restriction;
8653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8663ad4599aSBarry Smith }
8673ad4599aSBarry Smith 
8689bf9660cSLawrence Mitchell /*@C
8694363ddcaSBoris Boutkov    DMShellGetCreateRestriction - Get the routine used to create the restriction operator
8704363ddcaSBoris Boutkov 
87120f4b53cSBarry Smith    Logically Collective
8724363ddcaSBoris Boutkov 
8734165533cSJose E. Roman    Input Parameter:
87420f4b53cSBarry Smith .  dm - the `DMSHELL`
875a4a986ddSBoris Boutkov 
8764165533cSJose E. Roman    Output Parameter:
8774165533cSJose E. Roman .  restriction - the routine to create the restriction
8784363ddcaSBoris Boutkov 
8794363ddcaSBoris Boutkov    Level: advanced
8804363ddcaSBoris Boutkov 
88120f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellSetContext()`, `DMShellGetContext()`
8824363ddcaSBoris Boutkov @*/
883d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCreateRestriction(DM dm, PetscErrorCode (**restriction)(DM, DM, Mat *))
884d71ae5a4SJacob Faibussowitsch {
8854363ddcaSBoris Boutkov   PetscBool isshell;
8864363ddcaSBoris Boutkov 
8874363ddcaSBoris Boutkov   PetscFunctionBegin;
8884363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8899566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
8907a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
8914363ddcaSBoris Boutkov   *restriction = dm->ops->createrestriction;
8923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8934363ddcaSBoris Boutkov }
8944363ddcaSBoris Boutkov 
8954363ddcaSBoris Boutkov /*@C
8969bf9660cSLawrence Mitchell    DMShellSetCreateInjection - Set the routine used to create the injection operator
8979bf9660cSLawrence Mitchell 
89820f4b53cSBarry Smith    Logically Collective
8999bf9660cSLawrence Mitchell 
9004165533cSJose E. Roman    Input Parameters:
90120f4b53cSBarry Smith +  dm - the `DMSHELL`
9029bf9660cSLawrence Mitchell -  inject - the routine to create the injection
9039bf9660cSLawrence Mitchell 
9049bf9660cSLawrence Mitchell    Level: advanced
9059bf9660cSLawrence Mitchell 
90620f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCreateInterpolation()`, `DMCreateInjection()`, `DMShellGetCreateInjection()`, `DMShellSetContext()`, `DMShellGetContext()`
9079bf9660cSLawrence Mitchell @*/
908d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateInjection(DM dm, PetscErrorCode (*inject)(DM, DM, Mat *))
909d71ae5a4SJacob Faibussowitsch {
910f572501eSLawrence Mitchell   PetscBool isshell;
911f572501eSLawrence Mitchell 
912f572501eSLawrence Mitchell   PetscFunctionBegin;
913f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9149566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
9153ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
9165a84ad33SLisandro Dalcin   dm->ops->createinjection = inject;
9173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
918f572501eSLawrence Mitchell }
919f572501eSLawrence Mitchell 
9204363ddcaSBoris Boutkov /*@C
9214363ddcaSBoris Boutkov    DMShellGetCreateInjection - Get the routine used to create the injection operator
9224363ddcaSBoris Boutkov 
92320f4b53cSBarry Smith    Logically Collective
9244363ddcaSBoris Boutkov 
9254165533cSJose E. Roman    Input Parameter:
92620f4b53cSBarry Smith .  dm - the `DMSHELL`
927a4a986ddSBoris Boutkov 
9284165533cSJose E. Roman    Output Parameter:
9294165533cSJose E. Roman .  inject - the routine to create the injection
9304363ddcaSBoris Boutkov 
9314363ddcaSBoris Boutkov    Level: advanced
9324363ddcaSBoris Boutkov 
93320f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellGetCreateInterpolation()`, `DMCreateInjection()`, `DMShellSetContext()`, `DMShellGetContext()`
9344363ddcaSBoris Boutkov @*/
935d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCreateInjection(DM dm, PetscErrorCode (**inject)(DM, DM, Mat *))
936d71ae5a4SJacob Faibussowitsch {
9374363ddcaSBoris Boutkov   PetscBool isshell;
9384363ddcaSBoris Boutkov 
9394363ddcaSBoris Boutkov   PetscFunctionBegin;
9404363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9419566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
9427a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
9435a84ad33SLisandro Dalcin   *inject = dm->ops->createinjection;
9443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9454363ddcaSBoris Boutkov }
9464363ddcaSBoris Boutkov 
9479bf9660cSLawrence Mitchell /*@C
94820f4b53cSBarry Smith    DMShellSetCreateFieldDecomposition - Set the routine used to create a decomposition of fields for the `DMSHELL`
9499bf9660cSLawrence Mitchell 
95020f4b53cSBarry Smith    Logically Collective
9519bf9660cSLawrence Mitchell 
9524165533cSJose E. Roman    Input Parameters:
95320f4b53cSBarry Smith +  dm - the `DMSHELL`
9549bf9660cSLawrence Mitchell -  decomp - the routine to create the decomposition
9559bf9660cSLawrence Mitchell 
9569bf9660cSLawrence Mitchell    Level: advanced
9579bf9660cSLawrence Mitchell 
95820f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateFieldDecomposition()`, `DMShellSetContext()`, `DMShellGetContext()`
9599bf9660cSLawrence Mitchell @*/
960d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateFieldDecomposition(DM dm, PetscErrorCode (*decomp)(DM, PetscInt *, char ***, IS **, DM **))
961d71ae5a4SJacob Faibussowitsch {
9625e2259d5SLawrence Mitchell   PetscBool isshell;
9635e2259d5SLawrence Mitchell 
9645e2259d5SLawrence Mitchell   PetscFunctionBegin;
9655e2259d5SLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9669566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
9673ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
9685e2259d5SLawrence Mitchell   dm->ops->createfielddecomposition = decomp;
9693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9705e2259d5SLawrence Mitchell }
9715e2259d5SLawrence Mitchell 
972c00061e5SLawrence Mitchell /*@C
97320f4b53cSBarry Smith    DMShellSetCreateDomainDecomposition - Set the routine used to create a domain decomposition for the `DMSHELL`
974e734121bSPatrick Farrell 
97520f4b53cSBarry Smith    Logically Collective
976e734121bSPatrick Farrell 
9774165533cSJose E. Roman    Input Parameters:
97820f4b53cSBarry Smith +  dm - the `DMSHELL`
979e734121bSPatrick Farrell -  decomp - the routine to create the decomposition
980e734121bSPatrick Farrell 
981e734121bSPatrick Farrell    Level: advanced
982e734121bSPatrick Farrell 
98320f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateDomainDecomposition()`, `DMShellSetContext()`, `DMShellGetContext()`
984e734121bSPatrick Farrell @*/
985d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateDomainDecomposition(DM dm, PetscErrorCode (*decomp)(DM, PetscInt *, char ***, IS **, IS **, DM **))
986d71ae5a4SJacob Faibussowitsch {
987e734121bSPatrick Farrell   PetscBool isshell;
988e734121bSPatrick Farrell 
989e734121bSPatrick Farrell   PetscFunctionBegin;
990e734121bSPatrick Farrell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9919566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
9923ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
993e734121bSPatrick Farrell   dm->ops->createdomaindecomposition = decomp;
9943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
995e734121bSPatrick Farrell }
996e734121bSPatrick Farrell 
997e734121bSPatrick Farrell /*@C
99820f4b53cSBarry Smith    DMShellSetCreateDomainDecompositionScatters - Set the routine used to create the scatter contexts for domain decomposition with a `DMSHELL`
999eef9d6cdSPatrick Farrell 
100020f4b53cSBarry Smith    Logically Collective
1001eef9d6cdSPatrick Farrell 
10024165533cSJose E. Roman    Input Parameters:
100320f4b53cSBarry Smith +  dm - the `DMSHELL`
1004eef9d6cdSPatrick Farrell -  scatter - the routine to create the scatters
1005eef9d6cdSPatrick Farrell 
1006eef9d6cdSPatrick Farrell    Level: advanced
1007eef9d6cdSPatrick Farrell 
100820f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateDomainDecompositionScatters()`, `DMShellSetContext()`, `DMShellGetContext()`
1009eef9d6cdSPatrick Farrell @*/
1010d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateDomainDecompositionScatters(DM dm, PetscErrorCode (*scatter)(DM, PetscInt, DM *, VecScatter **, VecScatter **, VecScatter **))
1011d71ae5a4SJacob Faibussowitsch {
1012eef9d6cdSPatrick Farrell   PetscBool isshell;
1013eef9d6cdSPatrick Farrell 
1014eef9d6cdSPatrick Farrell   PetscFunctionBegin;
1015eef9d6cdSPatrick Farrell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10169566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
10173ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
1018eef9d6cdSPatrick Farrell   dm->ops->createddscatters = scatter;
10193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1020eef9d6cdSPatrick Farrell }
1021eef9d6cdSPatrick Farrell 
1022eef9d6cdSPatrick Farrell /*@C
102320f4b53cSBarry Smith    DMShellSetCreateSubDM - Set the routine used to create a sub `DM` from the `DMSHELL`
1024c00061e5SLawrence Mitchell 
102520f4b53cSBarry Smith    Logically Collective
1026c00061e5SLawrence Mitchell 
10274165533cSJose E. Roman    Input Parameters:
102820f4b53cSBarry Smith +  dm - the `DMSHELL`
1029c00061e5SLawrence Mitchell -  subdm - the routine to create the decomposition
1030c00061e5SLawrence Mitchell 
1031c00061e5SLawrence Mitchell    Level: advanced
1032c00061e5SLawrence Mitchell 
103320f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateSubDM()`, `DMShellGetCreateSubDM()`, `DMShellSetContext()`, `DMShellGetContext()`
1034c00061e5SLawrence Mitchell @*/
1035d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateSubDM(DM dm, PetscErrorCode (*subdm)(DM, PetscInt, const PetscInt[], IS *, DM *))
1036d71ae5a4SJacob Faibussowitsch {
1037c00061e5SLawrence Mitchell   PetscBool isshell;
1038c00061e5SLawrence Mitchell 
1039c00061e5SLawrence Mitchell   PetscFunctionBegin;
1040c00061e5SLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10419566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
10423ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
1043c00061e5SLawrence Mitchell   dm->ops->createsubdm = subdm;
10443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1045c00061e5SLawrence Mitchell }
1046c00061e5SLawrence Mitchell 
10474363ddcaSBoris Boutkov /*@C
104820f4b53cSBarry Smith    DMShellGetCreateSubDM - Get the routine used to create a sub DM from the `DMSHELL`
10494363ddcaSBoris Boutkov 
105020f4b53cSBarry Smith    Logically Collective
10514363ddcaSBoris Boutkov 
10524165533cSJose E. Roman    Input Parameter:
105320f4b53cSBarry Smith .  dm - the `DMSHELL`
1054a4a986ddSBoris Boutkov 
10554165533cSJose E. Roman    Output Parameter:
10564165533cSJose E. Roman .  subdm - the routine to create the decomposition
10574363ddcaSBoris Boutkov 
10584363ddcaSBoris Boutkov    Level: advanced
10594363ddcaSBoris Boutkov 
106020f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateSubDM()`, `DMShellSetCreateSubDM()`, `DMShellSetContext()`, `DMShellGetContext()`
10614363ddcaSBoris Boutkov @*/
1062d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCreateSubDM(DM dm, PetscErrorCode (**subdm)(DM, PetscInt, const PetscInt[], IS *, DM *))
1063d71ae5a4SJacob Faibussowitsch {
10644363ddcaSBoris Boutkov   PetscBool isshell;
10654363ddcaSBoris Boutkov 
10664363ddcaSBoris Boutkov   PetscFunctionBegin;
10674363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10689566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
10697a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
10704363ddcaSBoris Boutkov   *subdm = dm->ops->createsubdm;
10713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10724363ddcaSBoris Boutkov }
10734363ddcaSBoris Boutkov 
1074d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDestroy_Shell(DM dm)
1075d71ae5a4SJacob Faibussowitsch {
1076fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
1077fe1899a2SJed Brown 
1078fe1899a2SJed Brown   PetscFunctionBegin;
107909904cd0SBarry Smith   if (shell->destroyctx) PetscCallBack("Destroy Context", (*shell->destroyctx)(shell->ctx));
10809566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&shell->A));
10819566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xglobal));
10829566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xlocal));
10839566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->gtol));
10849566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltog));
10859566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltol));
10867b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
10879566063dSJacob Faibussowitsch   PetscCall(PetscFree(shell));
10883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1089fe1899a2SJed Brown }
1090fe1899a2SJed Brown 
1091d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMView_Shell(DM dm, PetscViewer v)
1092d71ae5a4SJacob Faibussowitsch {
10932d53ad75SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
10942d53ad75SBarry Smith 
10952d53ad75SBarry Smith   PetscFunctionBegin;
109601f8681bSStefano Zampini   if (shell->Xglobal) PetscCall(VecView(shell->Xglobal, v));
10973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10982d53ad75SBarry Smith }
10992d53ad75SBarry Smith 
1100d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLoad_Shell(DM dm, PetscViewer v)
1101d71ae5a4SJacob Faibussowitsch {
11022d53ad75SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
11032d53ad75SBarry Smith 
11042d53ad75SBarry Smith   PetscFunctionBegin;
11059566063dSJacob Faibussowitsch   PetscCall(VecCreate(PetscObjectComm((PetscObject)dm), &shell->Xglobal));
11069566063dSJacob Faibussowitsch   PetscCall(VecLoad(shell->Xglobal, v));
11073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11082d53ad75SBarry Smith }
1109fe1899a2SJed Brown 
1110d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSubDM_Shell(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm)
1111d71ae5a4SJacob Faibussowitsch {
11126e44b4cfSMatthew G. Knepley   PetscFunctionBegin;
11139566063dSJacob Faibussowitsch   if (subdm) PetscCall(DMShellCreate(PetscObjectComm((PetscObject)dm), subdm));
11149566063dSJacob Faibussowitsch   PetscCall(DMCreateSectionSubDM(dm, numFields, fields, is, subdm));
11153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11166e44b4cfSMatthew G. Knepley }
11176e44b4cfSMatthew G. Knepley 
1118d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm)
1119d71ae5a4SJacob Faibussowitsch {
1120fe1899a2SJed Brown   DM_Shell *shell;
1121fe1899a2SJed Brown 
1122fe1899a2SJed Brown   PetscFunctionBegin;
11234dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&shell));
11248c87107bSJed Brown   dm->data = shell;
1125fe1899a2SJed Brown 
11268c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
11278c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
1128dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
11298c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
11302d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
11312d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
11327a108d1dSBarry Smith   dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell;
11337a108d1dSBarry Smith   dm->ops->globaltolocalend   = DMGlobalToLocalEndDefaultShell;
113455daaa54SRichard Tran Mills   dm->ops->localtoglobalbegin = DMLocalToGlobalBeginDefaultShell;
113555daaa54SRichard Tran Mills   dm->ops->localtoglobalend   = DMLocalToGlobalEndDefaultShell;
113663731094SRichard Tran Mills   dm->ops->localtolocalbegin  = DMLocalToLocalBeginDefaultShell;
113763731094SRichard Tran Mills   dm->ops->localtolocalend    = DMLocalToLocalEndDefaultShell;
11386e44b4cfSMatthew G. Knepley   dm->ops->createsubdm        = DMCreateSubDM_Shell;
11399566063dSJacob Faibussowitsch   PetscCall(DMSetMatType(dm, MATDENSE));
11403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1141fe1899a2SJed Brown }
1142fe1899a2SJed Brown 
1143fe1899a2SJed Brown /*@
114420f4b53cSBarry Smith     DMShellCreate - Creates a `DMSHELL` object, used to manage user-defined problem data
1145fe1899a2SJed Brown 
1146d083f849SBarry Smith     Collective
1147fe1899a2SJed Brown 
1148fe1899a2SJed Brown     Input Parameter:
1149fe1899a2SJed Brown .   comm - the processors that will share the global vector
1150fe1899a2SJed Brown 
1151*2fe279fdSBarry Smith     Output Parameter:
115220f4b53cSBarry Smith .   shell - the `DMSHELL`
1153fe1899a2SJed Brown 
1154fe1899a2SJed Brown     Level: advanced
1155fe1899a2SJed Brown 
1156db781477SPatrick Sanan .seealso `DMDestroy()`, `DMCreateGlobalVector()`, `DMCreateLocalVector()`, `DMShellSetContext()`, `DMShellGetContext()`
1157fe1899a2SJed Brown @*/
1158d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellCreate(MPI_Comm comm, DM *dm)
1159d71ae5a4SJacob Faibussowitsch {
1160fe1899a2SJed Brown   PetscFunctionBegin;
1161fe1899a2SJed Brown   PetscValidPointer(dm, 2);
11629566063dSJacob Faibussowitsch   PetscCall(DMCreate(comm, dm));
11639566063dSJacob Faibussowitsch   PetscCall(DMSetType(*dm, DMSHELL));
11649566063dSJacob Faibussowitsch   PetscCall(DMSetUp(*dm));
11653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1166fe1899a2SJed Brown }
1167