xref: /petsc/src/dm/impls/shell/dmshell.c (revision 9371c9d470a9602b6d10a8bf50c9b2280a79e45a)
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;
13fe1899a2SJed Brown } DM_Shell;
14fe1899a2SJed Brown 
157a108d1dSBarry Smith /*@
167a108d1dSBarry Smith    DMGlobalToLocalBeginDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to begin a global to local scatter
178d359177SBarry Smith    Collective
188d359177SBarry Smith 
194165533cSJose E. Roman    Input Parameters:
208d359177SBarry Smith +  dm - shell DM
218d359177SBarry Smith .  g - global vector
228d359177SBarry Smith .  mode - InsertMode
238d359177SBarry Smith -  l - local vector
248d359177SBarry Smith 
257a108d1dSBarry Smith    Level: advanced
268d359177SBarry Smith 
277a108d1dSBarry Smith    Note:  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.
287a108d1dSBarry Smith 
29db781477SPatrick Sanan .seealso: `DMGlobalToLocalEndDefaultShell()`
308d359177SBarry Smith @*/
31*9371c9d4SSatish Balay PetscErrorCode DMGlobalToLocalBeginDefaultShell(DM dm, Vec g, InsertMode mode, Vec l) {
328d359177SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
338d359177SBarry Smith 
348d359177SBarry Smith   PetscFunctionBegin;
357a8be351SBarry Smith   PetscCheck(shell->gtol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
369566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->gtol, g, l, mode, SCATTER_FORWARD));
378d359177SBarry Smith   PetscFunctionReturn(0);
388d359177SBarry Smith }
398d359177SBarry Smith 
407a108d1dSBarry Smith /*@
417a108d1dSBarry Smith    DMGlobalToLocalEndDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to end a global to local scatter
428d359177SBarry Smith    Collective
438d359177SBarry Smith 
444165533cSJose E. Roman    Input Parameters:
458d359177SBarry Smith +  dm - shell DM
468d359177SBarry Smith .  g - global vector
478d359177SBarry Smith .  mode - InsertMode
488d359177SBarry Smith -  l - local vector
498d359177SBarry Smith 
507a108d1dSBarry Smith    Level: advanced
518d359177SBarry Smith 
52db781477SPatrick Sanan .seealso: `DMGlobalToLocalBeginDefaultShell()`
538d359177SBarry Smith @*/
54*9371c9d4SSatish Balay PetscErrorCode DMGlobalToLocalEndDefaultShell(DM dm, Vec g, InsertMode mode, Vec l) {
558d359177SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
568d359177SBarry Smith 
578d359177SBarry Smith   PetscFunctionBegin;
587a8be351SBarry Smith   PetscCheck(shell->gtol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
599566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->gtol, g, l, mode, SCATTER_FORWARD));
608d359177SBarry Smith   PetscFunctionReturn(0);
618d359177SBarry Smith }
628d359177SBarry Smith 
63c5076b69SRichard Tran Mills /*@
64c5076b69SRichard Tran Mills    DMLocalToGlobalBeginDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to begin a local to global scatter
65c5076b69SRichard Tran Mills    Collective
66c5076b69SRichard Tran Mills 
674165533cSJose E. Roman    Input Parameters:
68c5076b69SRichard Tran Mills +  dm - shell DM
69c5076b69SRichard Tran Mills .  l - local vector
70c5076b69SRichard Tran Mills .  mode - InsertMode
71c5076b69SRichard Tran Mills -  g - global vector
72c5076b69SRichard Tran Mills 
73c5076b69SRichard Tran Mills    Level: advanced
74c5076b69SRichard Tran Mills 
75c5076b69SRichard Tran Mills    Note:  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.
76c5076b69SRichard Tran Mills 
77db781477SPatrick Sanan .seealso: `DMLocalToGlobalEndDefaultShell()`
78c5076b69SRichard Tran Mills @*/
79*9371c9d4SSatish Balay PetscErrorCode DMLocalToGlobalBeginDefaultShell(DM dm, Vec l, InsertMode mode, Vec g) {
80c5076b69SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
81c5076b69SRichard Tran Mills 
82c5076b69SRichard Tran Mills   PetscFunctionBegin;
837a8be351SBarry Smith   PetscCheck(shell->ltog, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
849566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->ltog, l, g, mode, SCATTER_FORWARD));
85c5076b69SRichard Tran Mills   PetscFunctionReturn(0);
86c5076b69SRichard Tran Mills }
87c5076b69SRichard Tran Mills 
88c5076b69SRichard Tran Mills /*@
89c5076b69SRichard Tran Mills    DMLocalToGlobalEndDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to end a local to global scatter
90c5076b69SRichard Tran Mills    Collective
91c5076b69SRichard Tran Mills 
924165533cSJose E. Roman    Input Parameters:
93c5076b69SRichard Tran Mills +  dm - shell DM
94c5076b69SRichard Tran Mills .  l - local vector
95c5076b69SRichard Tran Mills .  mode - InsertMode
96c5076b69SRichard Tran Mills -  g - global vector
97c5076b69SRichard Tran Mills 
98c5076b69SRichard Tran Mills    Level: advanced
99c5076b69SRichard Tran Mills 
100db781477SPatrick Sanan .seealso: `DMLocalToGlobalBeginDefaultShell()`
101c5076b69SRichard Tran Mills @*/
102*9371c9d4SSatish Balay PetscErrorCode DMLocalToGlobalEndDefaultShell(DM dm, Vec l, InsertMode mode, Vec g) {
103c5076b69SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
104c5076b69SRichard Tran Mills 
105c5076b69SRichard Tran Mills   PetscFunctionBegin;
1067a8be351SBarry Smith   PetscCheck(shell->ltog, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
1079566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->ltog, l, g, mode, SCATTER_FORWARD));
108c5076b69SRichard Tran Mills   PetscFunctionReturn(0);
109c5076b69SRichard Tran Mills }
110c5076b69SRichard Tran Mills 
111f3db62a7SRichard Tran Mills /*@
112f3db62a7SRichard Tran Mills    DMLocalToLocalBeginDefaultShell - Uses the LocalToLocal VecScatter context set by the user to begin a local to local scatter
113f3db62a7SRichard Tran Mills    Collective
114f3db62a7SRichard Tran Mills 
1154165533cSJose E. Roman    Input Parameters:
116f3db62a7SRichard Tran Mills +  dm - shell DM
117f3db62a7SRichard Tran Mills .  g - the original local vector
118f3db62a7SRichard Tran Mills -  mode - InsertMode
119f3db62a7SRichard Tran Mills 
120f3db62a7SRichard Tran Mills    Output Parameter:
121f3db62a7SRichard Tran Mills .  l  - the local vector with correct ghost values
122f3db62a7SRichard Tran Mills 
123f3db62a7SRichard Tran Mills    Level: advanced
124f3db62a7SRichard Tran Mills 
125f3db62a7SRichard Tran Mills    Note:  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.
126f3db62a7SRichard Tran Mills 
127db781477SPatrick Sanan .seealso: `DMLocalToLocalEndDefaultShell()`
128f3db62a7SRichard Tran Mills @*/
129*9371c9d4SSatish Balay PetscErrorCode DMLocalToLocalBeginDefaultShell(DM dm, Vec g, InsertMode mode, Vec l) {
130f3db62a7SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
131f3db62a7SRichard Tran Mills 
132f3db62a7SRichard Tran Mills   PetscFunctionBegin;
1337a8be351SBarry Smith   PetscCheck(shell->ltol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToLocalVecScatter()");
1349566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->ltol, g, l, mode, SCATTER_FORWARD));
135f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
136f3db62a7SRichard Tran Mills }
137f3db62a7SRichard Tran Mills 
138f3db62a7SRichard Tran Mills /*@
139f3db62a7SRichard Tran Mills    DMLocalToLocalEndDefaultShell - Uses the LocalToLocal VecScatter context set by the user to end a local to local scatter
140f3db62a7SRichard Tran Mills    Collective
141f3db62a7SRichard Tran Mills 
1424165533cSJose E. Roman    Input Parameters:
143f3db62a7SRichard Tran Mills +  dm - shell DM
144f3db62a7SRichard Tran Mills .  g - the original local vector
145f3db62a7SRichard Tran Mills -  mode - InsertMode
146f3db62a7SRichard Tran Mills 
147f3db62a7SRichard Tran Mills    Output Parameter:
148f3db62a7SRichard Tran Mills .  l  - the local vector with correct ghost values
149f3db62a7SRichard Tran Mills 
150f3db62a7SRichard Tran Mills    Level: advanced
151f3db62a7SRichard Tran Mills 
152db781477SPatrick Sanan .seealso: `DMLocalToLocalBeginDefaultShell()`
153f3db62a7SRichard Tran Mills @*/
154*9371c9d4SSatish Balay PetscErrorCode DMLocalToLocalEndDefaultShell(DM dm, Vec g, InsertMode mode, Vec l) {
155f3db62a7SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
156f3db62a7SRichard Tran Mills 
157f3db62a7SRichard Tran Mills   PetscFunctionBegin;
1587a8be351SBarry Smith   PetscCheck(shell->ltol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
1599566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->ltol, g, l, mode, SCATTER_FORWARD));
160f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
161f3db62a7SRichard Tran Mills }
162c5076b69SRichard Tran Mills 
163*9371c9d4SSatish Balay static PetscErrorCode DMCreateMatrix_Shell(DM dm, Mat *J) {
164fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
165fe1899a2SJed Brown   Mat       A;
166fe1899a2SJed Brown 
167fe1899a2SJed Brown   PetscFunctionBegin;
168fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
169064a246eSJacob Faibussowitsch   PetscValidPointer(J, 2);
1707bde9f88SJed Brown   if (!shell->A) {
1717bde9f88SJed Brown     if (shell->Xglobal) {
1727bde9f88SJed Brown       PetscInt m, M;
1739566063dSJacob Faibussowitsch       PetscCall(PetscInfo(dm, "Naively creating matrix using global vector distribution without preallocation\n"));
1749566063dSJacob Faibussowitsch       PetscCall(VecGetSize(shell->Xglobal, &M));
1759566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(shell->Xglobal, &m));
1769566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)dm), &shell->A));
1779566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(shell->A, m, m, M, M));
1789566063dSJacob Faibussowitsch       PetscCall(MatSetType(shell->A, dm->mattype));
1799566063dSJacob Faibussowitsch       PetscCall(MatSetUp(shell->A));
180ce94432eSBarry Smith     } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector");
1817bde9f88SJed Brown   }
182fe1899a2SJed Brown   A = shell->A;
1839566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(A, MAT_SHARE_NONZERO_PATTERN, J));
1849566063dSJacob Faibussowitsch   PetscCall(MatSetDM(*J, dm));
185fe1899a2SJed Brown   PetscFunctionReturn(0);
186fe1899a2SJed Brown }
187fe1899a2SJed Brown 
188*9371c9d4SSatish Balay PetscErrorCode DMCreateGlobalVector_Shell(DM dm, Vec *gvec) {
189fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
190fe1899a2SJed Brown   Vec       X;
191fe1899a2SJed Brown 
192fe1899a2SJed Brown   PetscFunctionBegin;
193fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
194fe1899a2SJed Brown   PetscValidPointer(gvec, 2);
195ea78f98cSLisandro Dalcin   *gvec = NULL;
196fe1899a2SJed Brown   X     = shell->Xglobal;
1977a8be351SBarry Smith   PetscCheck(X, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
19806f803f6SStefano Zampini   /* Need to create a copy in order to attach the DM to the vector */
1999566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(X, gvec));
2009566063dSJacob Faibussowitsch   PetscCall(VecZeroEntries(*gvec));
2019566063dSJacob Faibussowitsch   PetscCall(VecSetDM(*gvec, dm));
202fe1899a2SJed Brown   PetscFunctionReturn(0);
203fe1899a2SJed Brown }
204fe1899a2SJed Brown 
205*9371c9d4SSatish Balay PetscErrorCode DMCreateLocalVector_Shell(DM dm, Vec *gvec) {
206dc43b69eSJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
207dc43b69eSJed Brown   Vec       X;
208dc43b69eSJed Brown 
209dc43b69eSJed Brown   PetscFunctionBegin;
210dc43b69eSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
211dc43b69eSJed Brown   PetscValidPointer(gvec, 2);
212ea78f98cSLisandro Dalcin   *gvec = NULL;
213dc43b69eSJed Brown   X     = shell->Xlocal;
2147a8be351SBarry Smith   PetscCheck(X, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()");
21506f803f6SStefano Zampini   /* Need to create a copy in order to attach the DM to the vector */
2169566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(X, gvec));
2179566063dSJacob Faibussowitsch   PetscCall(VecZeroEntries(*gvec));
2189566063dSJacob Faibussowitsch   PetscCall(VecSetDM(*gvec, dm));
219dc43b69eSJed Brown   PetscFunctionReturn(0);
220dc43b69eSJed Brown }
221dc43b69eSJed Brown 
222fef3a512SBarry Smith /*@
223fef3a512SBarry Smith    DMShellSetContext - set some data to be usable by this DM
224fef3a512SBarry Smith 
225fef3a512SBarry Smith    Collective
226fef3a512SBarry Smith 
2274165533cSJose E. Roman    Input Parameters:
228fef3a512SBarry Smith +  dm - shell DM
229fef3a512SBarry Smith -  ctx - the context
230fef3a512SBarry Smith 
231fef3a512SBarry Smith    Level: advanced
232fef3a512SBarry Smith 
233db781477SPatrick Sanan .seealso: `DMCreateMatrix()`, `DMShellGetContext()`
234fef3a512SBarry Smith @*/
235*9371c9d4SSatish Balay PetscErrorCode DMShellSetContext(DM dm, void *ctx) {
236fef3a512SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
237fef3a512SBarry Smith   PetscBool isshell;
238fef3a512SBarry Smith 
239fef3a512SBarry Smith   PetscFunctionBegin;
240fef3a512SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2419566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
242fef3a512SBarry Smith   if (!isshell) PetscFunctionReturn(0);
243fef3a512SBarry Smith   shell->ctx = ctx;
244fef3a512SBarry Smith   PetscFunctionReturn(0);
245fef3a512SBarry Smith }
246fef3a512SBarry Smith 
247fef3a512SBarry Smith /*@
248bf890c61SBoris Boutkov    DMShellGetContext - Returns the user-provided context associated to the DM
249fef3a512SBarry Smith 
250fef3a512SBarry Smith    Collective
251fef3a512SBarry Smith 
2524165533cSJose E. Roman    Input Parameter:
253fef3a512SBarry Smith .  dm - shell DM
254fef3a512SBarry Smith 
2554165533cSJose E. Roman    Output Parameter:
256fef3a512SBarry Smith .  ctx - the context
257fef3a512SBarry Smith 
258fef3a512SBarry Smith    Level: advanced
259fef3a512SBarry Smith 
260db781477SPatrick Sanan .seealso: `DMCreateMatrix()`, `DMShellSetContext()`
261fef3a512SBarry Smith @*/
262*9371c9d4SSatish Balay PetscErrorCode DMShellGetContext(DM dm, void *ctx) {
263fef3a512SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
264fef3a512SBarry Smith   PetscBool isshell;
265fef3a512SBarry Smith 
266fef3a512SBarry Smith   PetscFunctionBegin;
267fef3a512SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2689566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
2697a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
2703ec1f749SStefano Zampini   *(void **)ctx = shell->ctx;
271fef3a512SBarry Smith   PetscFunctionReturn(0);
272fef3a512SBarry Smith }
273fef3a512SBarry Smith 
274fe1899a2SJed Brown /*@
275fe1899a2SJed Brown    DMShellSetMatrix - sets a template matrix associated with the DMShell
276fe1899a2SJed Brown 
277fe1899a2SJed Brown    Collective
278fe1899a2SJed Brown 
2794165533cSJose E. Roman    Input Parameters:
280fe1899a2SJed Brown +  dm - shell DM
281fe1899a2SJed Brown -  J - template matrix
282fe1899a2SJed Brown 
283fe1899a2SJed Brown    Level: advanced
284fe1899a2SJed Brown 
28506f803f6SStefano Zampini    Developer Notes:
28606f803f6SStefano Zampini     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.
28706f803f6SStefano Zampini 
288db781477SPatrick Sanan .seealso: `DMCreateMatrix()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
289fe1899a2SJed Brown @*/
290*9371c9d4SSatish Balay PetscErrorCode DMShellSetMatrix(DM dm, Mat J) {
291fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
2928c87107bSJed Brown   PetscBool isshell;
29306f803f6SStefano Zampini   DM        mdm;
294fe1899a2SJed Brown 
295fe1899a2SJed Brown   PetscFunctionBegin;
2968c87107bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2978c87107bSJed Brown   PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
2989566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
2998c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
30006f803f6SStefano Zampini   if (J == shell->A) PetscFunctionReturn(0);
3019566063dSJacob Faibussowitsch   PetscCall(MatGetDM(J, &mdm));
3029566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)J));
3039566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&shell->A));
30406f803f6SStefano Zampini   if (mdm == dm) {
3059566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(J, MAT_SHARE_NONZERO_PATTERN, &shell->A));
3069566063dSJacob Faibussowitsch     PetscCall(MatSetDM(shell->A, NULL));
30706f803f6SStefano Zampini   } else shell->A = J;
308fe1899a2SJed Brown   PetscFunctionReturn(0);
309fe1899a2SJed Brown }
310fe1899a2SJed Brown 
311fe1899a2SJed Brown /*@C
312fe1899a2SJed Brown    DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM
313fe1899a2SJed Brown 
314d083f849SBarry Smith    Logically Collective on dm
315fe1899a2SJed Brown 
3164165533cSJose E. Roman    Input Parameters:
317fe1899a2SJed Brown +  dm - the shell DM
318fe1899a2SJed Brown -  func - the function to create a matrix
319fe1899a2SJed Brown 
320fe1899a2SJed Brown    Level: advanced
321fe1899a2SJed Brown 
322db781477SPatrick Sanan .seealso: `DMCreateMatrix()`, `DMShellSetMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
323fe1899a2SJed Brown @*/
324*9371c9d4SSatish Balay PetscErrorCode DMShellSetCreateMatrix(DM dm, PetscErrorCode (*func)(DM, Mat *)) {
325fe1899a2SJed Brown   PetscFunctionBegin;
326fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
327fe1899a2SJed Brown   dm->ops->creatematrix = func;
328fe1899a2SJed Brown   PetscFunctionReturn(0);
329fe1899a2SJed Brown }
330fe1899a2SJed Brown 
331fe1899a2SJed Brown /*@
332fe1899a2SJed Brown    DMShellSetGlobalVector - sets a template global vector associated with the DMShell
333fe1899a2SJed Brown 
334d083f849SBarry Smith    Logically Collective on dm
335fe1899a2SJed Brown 
3364165533cSJose E. Roman    Input Parameters:
337fe1899a2SJed Brown +  dm - shell DM
338fe1899a2SJed Brown -  X - template vector
339fe1899a2SJed Brown 
340fe1899a2SJed Brown    Level: advanced
341fe1899a2SJed Brown 
342db781477SPatrick Sanan .seealso: `DMCreateGlobalVector()`, `DMShellSetMatrix()`, `DMShellSetCreateGlobalVector()`
343fe1899a2SJed Brown @*/
344*9371c9d4SSatish Balay PetscErrorCode DMShellSetGlobalVector(DM dm, Vec X) {
345fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
3468c87107bSJed Brown   PetscBool isshell;
347cca7ec1eSBarry Smith   DM        vdm;
348fe1899a2SJed Brown 
349fe1899a2SJed Brown   PetscFunctionBegin;
3508c87107bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3518c87107bSJed Brown   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
3529566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
3538c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
3549566063dSJacob Faibussowitsch   PetscCall(VecGetDM(X, &vdm));
355cca7ec1eSBarry Smith   /*
356cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
357cca7ec1eSBarry 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
358cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
359cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
360cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
361cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
362cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
363cca7ec1eSBarry Smith       for pointing out the problem.
364cca7ec1eSBarry Smith    */
365cca7ec1eSBarry Smith   if (vdm == dm) PetscFunctionReturn(0);
3669566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)X));
3679566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xglobal));
368fe1899a2SJed Brown   shell->Xglobal = X;
369fe1899a2SJed Brown   PetscFunctionReturn(0);
370fe1899a2SJed Brown }
371fe1899a2SJed Brown 
37204d741b1SMatthew G. Knepley /*@
37304d741b1SMatthew G. Knepley   DMShellGetGlobalVector - Returns the template global vector associated with the DMShell, or NULL if it was not set
37404d741b1SMatthew G. Knepley 
37504d741b1SMatthew G. Knepley    Not collective
37604d741b1SMatthew G. Knepley 
3774165533cSJose E. Roman    Input Parameters:
37804d741b1SMatthew G. Knepley +  dm - shell DM
37904d741b1SMatthew G. Knepley -  X - template vector
38004d741b1SMatthew G. Knepley 
38104d741b1SMatthew G. Knepley    Level: advanced
38204d741b1SMatthew G. Knepley 
383db781477SPatrick Sanan .seealso: `DMShellSetGlobalVector()`, `DMShellSetCreateGlobalVector()`, `DMCreateGlobalVector()`
38404d741b1SMatthew G. Knepley @*/
385*9371c9d4SSatish Balay PetscErrorCode DMShellGetGlobalVector(DM dm, Vec *X) {
38604d741b1SMatthew G. Knepley   DM_Shell *shell = (DM_Shell *)dm->data;
38704d741b1SMatthew G. Knepley   PetscBool isshell;
38804d741b1SMatthew G. Knepley 
38904d741b1SMatthew G. Knepley   PetscFunctionBegin;
39004d741b1SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
39104d741b1SMatthew G. Knepley   PetscValidPointer(X, 2);
3929566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
39304d741b1SMatthew G. Knepley   if (!isshell) PetscFunctionReturn(0);
39404d741b1SMatthew G. Knepley   *X = shell->Xglobal;
39504d741b1SMatthew G. Knepley   PetscFunctionReturn(0);
39604d741b1SMatthew G. Knepley }
39704d741b1SMatthew G. Knepley 
398fe1899a2SJed Brown /*@C
399fe1899a2SJed Brown    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM
400fe1899a2SJed Brown 
401fe1899a2SJed Brown    Logically Collective
402fe1899a2SJed Brown 
4034165533cSJose E. Roman    Input Parameters:
404fe1899a2SJed Brown +  dm - the shell DM
405fe1899a2SJed Brown -  func - the creation routine
406fe1899a2SJed Brown 
407fe1899a2SJed Brown    Level: advanced
408fe1899a2SJed Brown 
409db781477SPatrick Sanan .seealso: `DMShellSetGlobalVector()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
410fe1899a2SJed Brown @*/
411*9371c9d4SSatish Balay PetscErrorCode DMShellSetCreateGlobalVector(DM dm, PetscErrorCode (*func)(DM, Vec *)) {
412fe1899a2SJed Brown   PetscFunctionBegin;
413fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
414fe1899a2SJed Brown   dm->ops->createglobalvector = func;
415fe1899a2SJed Brown   PetscFunctionReturn(0);
416fe1899a2SJed Brown }
417fe1899a2SJed Brown 
418dc43b69eSJed Brown /*@
419dc43b69eSJed Brown    DMShellSetLocalVector - sets a template local vector associated with the DMShell
420dc43b69eSJed Brown 
421d083f849SBarry Smith    Logically Collective on dm
422dc43b69eSJed Brown 
4234165533cSJose E. Roman    Input Parameters:
424dc43b69eSJed Brown +  dm - shell DM
425dc43b69eSJed Brown -  X - template vector
426dc43b69eSJed Brown 
427dc43b69eSJed Brown    Level: advanced
428dc43b69eSJed Brown 
429db781477SPatrick Sanan .seealso: `DMCreateLocalVector()`, `DMShellSetMatrix()`, `DMShellSetCreateLocalVector()`
430dc43b69eSJed Brown @*/
431*9371c9d4SSatish Balay PetscErrorCode DMShellSetLocalVector(DM dm, Vec X) {
432dc43b69eSJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
433dc43b69eSJed Brown   PetscBool isshell;
434cca7ec1eSBarry Smith   DM        vdm;
435dc43b69eSJed Brown 
436dc43b69eSJed Brown   PetscFunctionBegin;
437dc43b69eSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
438dc43b69eSJed Brown   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
4399566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
440dc43b69eSJed Brown   if (!isshell) PetscFunctionReturn(0);
4419566063dSJacob Faibussowitsch   PetscCall(VecGetDM(X, &vdm));
442cca7ec1eSBarry Smith   /*
443cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
444cca7ec1eSBarry 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
445cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
446cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
447cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
448cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
449cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
450cca7ec1eSBarry Smith       for pointing out the problem.
451cca7ec1eSBarry Smith    */
452cca7ec1eSBarry Smith   if (vdm == dm) PetscFunctionReturn(0);
4539566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)X));
4549566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xlocal));
455dc43b69eSJed Brown   shell->Xlocal = X;
456dc43b69eSJed Brown   PetscFunctionReturn(0);
457dc43b69eSJed Brown }
458dc43b69eSJed Brown 
459dc43b69eSJed Brown /*@C
460dc43b69eSJed Brown    DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM
461dc43b69eSJed Brown 
462dc43b69eSJed Brown    Logically Collective
463dc43b69eSJed Brown 
4644165533cSJose E. Roman    Input Parameters:
465dc43b69eSJed Brown +  dm - the shell DM
466dc43b69eSJed Brown -  func - the creation routine
467dc43b69eSJed Brown 
468dc43b69eSJed Brown    Level: advanced
469dc43b69eSJed Brown 
470db781477SPatrick Sanan .seealso: `DMShellSetLocalVector()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
471dc43b69eSJed Brown @*/
472*9371c9d4SSatish Balay PetscErrorCode DMShellSetCreateLocalVector(DM dm, PetscErrorCode (*func)(DM, Vec *)) {
473dc43b69eSJed Brown   PetscFunctionBegin;
474dc43b69eSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
475dc43b69eSJed Brown   dm->ops->createlocalvector = func;
476dc43b69eSJed Brown   PetscFunctionReturn(0);
477dc43b69eSJed Brown }
478dc43b69eSJed Brown 
4798339e6d0SRichard Tran Mills /*@C
4808339e6d0SRichard Tran Mills    DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter
4818339e6d0SRichard Tran Mills 
482d083f849SBarry Smith    Logically Collective on dm
4838339e6d0SRichard Tran Mills 
4844165533cSJose E. Roman    Input Parameters
4858339e6d0SRichard Tran Mills +  dm - the shell DM
4868339e6d0SRichard Tran Mills .  begin - the routine that begins the global to local scatter
4878339e6d0SRichard Tran Mills -  end - the routine that ends the global to local scatter
4888339e6d0SRichard Tran Mills 
48995452b02SPatrick Sanan    Notes:
49095452b02SPatrick Sanan     If these functions are not provided but DMShellSetGlobalToLocalVecScatter() is called then
491f3db62a7SRichard Tran Mills    DMGlobalToLocalBeginDefaultShell()/DMGlobalToLocalEndDefaultShell() are used to to perform the transfers
4927a108d1dSBarry Smith 
4938339e6d0SRichard Tran Mills    Level: advanced
4948339e6d0SRichard Tran Mills 
495db781477SPatrick Sanan .seealso: `DMShellSetLocalToGlobal()`, `DMGlobalToLocalBeginDefaultShell()`, `DMGlobalToLocalEndDefaultShell()`
4968339e6d0SRichard Tran Mills @*/
497*9371c9d4SSatish Balay PetscErrorCode DMShellSetGlobalToLocal(DM dm, PetscErrorCode (*begin)(DM, Vec, InsertMode, Vec), PetscErrorCode (*end)(DM, Vec, InsertMode, Vec)) {
4988339e6d0SRichard Tran Mills   PetscFunctionBegin;
4992d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5008339e6d0SRichard Tran Mills   dm->ops->globaltolocalbegin = begin;
5018339e6d0SRichard Tran Mills   dm->ops->globaltolocalend   = end;
5028339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
5038339e6d0SRichard Tran Mills }
5048339e6d0SRichard Tran Mills 
5058339e6d0SRichard Tran Mills /*@C
5068339e6d0SRichard Tran Mills    DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter
5078339e6d0SRichard Tran Mills 
508d083f849SBarry Smith    Logically Collective on dm
5098339e6d0SRichard Tran Mills 
5104165533cSJose E. Roman    Input Parameters
5118339e6d0SRichard Tran Mills +  dm - the shell DM
5128339e6d0SRichard Tran Mills .  begin - the routine that begins the local to global scatter
5138339e6d0SRichard Tran Mills -  end - the routine that ends the local to global scatter
5148339e6d0SRichard Tran Mills 
51595452b02SPatrick Sanan    Notes:
51695452b02SPatrick Sanan     If these functions are not provided but DMShellSetLocalToGlobalVecScatter() is called then
517f3db62a7SRichard Tran Mills    DMLocalToGlobalBeginDefaultShell()/DMLocalToGlobalEndDefaultShell() are used to to perform the transfers
518f3db62a7SRichard Tran Mills 
5198339e6d0SRichard Tran Mills    Level: advanced
5208339e6d0SRichard Tran Mills 
521db781477SPatrick Sanan .seealso: `DMShellSetGlobalToLocal()`
5228339e6d0SRichard Tran Mills @*/
523*9371c9d4SSatish Balay PetscErrorCode DMShellSetLocalToGlobal(DM dm, PetscErrorCode (*begin)(DM, Vec, InsertMode, Vec), PetscErrorCode (*end)(DM, Vec, InsertMode, Vec)) {
5248339e6d0SRichard Tran Mills   PetscFunctionBegin;
5252d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5268339e6d0SRichard Tran Mills   dm->ops->localtoglobalbegin = begin;
5278339e6d0SRichard Tran Mills   dm->ops->localtoglobalend   = end;
5288339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
5298339e6d0SRichard Tran Mills }
5308339e6d0SRichard Tran Mills 
531f3db62a7SRichard Tran Mills /*@C
532f3db62a7SRichard Tran Mills    DMShellSetLocalToLocal - Sets the routines used to perform a local to local scatter
533f3db62a7SRichard Tran Mills 
534d083f849SBarry Smith    Logically Collective on dm
535f3db62a7SRichard Tran Mills 
5364165533cSJose E. Roman    Input Parameters
537f3db62a7SRichard Tran Mills +  dm - the shell DM
538f3db62a7SRichard Tran Mills .  begin - the routine that begins the local to local scatter
539f3db62a7SRichard Tran Mills -  end - the routine that ends the local to local scatter
540f3db62a7SRichard Tran Mills 
54195452b02SPatrick Sanan    Notes:
54295452b02SPatrick Sanan     If these functions are not provided but DMShellSetLocalToLocalVecScatter() is called then
543f3db62a7SRichard Tran Mills    DMLocalToLocalBeginDefaultShell()/DMLocalToLocalEndDefaultShell() are used to to perform the transfers
544f3db62a7SRichard Tran Mills 
545f3db62a7SRichard Tran Mills    Level: advanced
546f3db62a7SRichard Tran Mills 
547db781477SPatrick Sanan .seealso: `DMShellSetGlobalToLocal()`, `DMLocalToLocalBeginDefaultShell()`, `DMLocalToLocalEndDefaultShell()`
548f3db62a7SRichard Tran Mills @*/
549*9371c9d4SSatish Balay PetscErrorCode DMShellSetLocalToLocal(DM dm, PetscErrorCode (*begin)(DM, Vec, InsertMode, Vec), PetscErrorCode (*end)(DM, Vec, InsertMode, Vec)) {
550f3db62a7SRichard Tran Mills   PetscFunctionBegin;
5512d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
552f3db62a7SRichard Tran Mills   dm->ops->localtolocalbegin = begin;
553f3db62a7SRichard Tran Mills   dm->ops->localtolocalend   = end;
554f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
555f3db62a7SRichard Tran Mills }
556f3db62a7SRichard Tran Mills 
55781634712SRichard Tran Mills /*@
55881634712SRichard Tran Mills    DMShellSetGlobalToLocalVecScatter - Sets a VecScatter context for global to local communication
55981634712SRichard Tran Mills 
560d083f849SBarry Smith    Logically Collective on dm
56181634712SRichard Tran Mills 
5624165533cSJose E. Roman    Input Parameters
56381634712SRichard Tran Mills +  dm - the shell DM
56481634712SRichard Tran Mills -  gtol - the global to local VecScatter context
56581634712SRichard Tran Mills 
56681634712SRichard Tran Mills    Level: advanced
56781634712SRichard Tran Mills 
568db781477SPatrick Sanan .seealso: `DMShellSetGlobalToLocal()`, `DMGlobalToLocalBeginDefaultShell()`, `DMGlobalToLocalEndDefaultShell()`
56981634712SRichard Tran Mills @*/
570*9371c9d4SSatish Balay PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter gtol) {
57181634712SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
57281634712SRichard Tran Mills 
573b300e4a8SRichard Tran Mills   PetscFunctionBegin;
5742d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
57597929ea7SJunchao Zhang   PetscValidHeaderSpecific(gtol, PETSCSF_CLASSID, 2);
5769566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)gtol));
5779566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->gtol));
57881634712SRichard Tran Mills   shell->gtol = gtol;
57981634712SRichard Tran Mills   PetscFunctionReturn(0);
58081634712SRichard Tran Mills }
58181634712SRichard Tran Mills 
582988ea7d6SRichard Tran Mills /*@
583988ea7d6SRichard Tran Mills    DMShellSetLocalToGlobalVecScatter - Sets a VecScatter context for local to global communication
584988ea7d6SRichard Tran Mills 
585d083f849SBarry Smith    Logically Collective on dm
586988ea7d6SRichard Tran Mills 
5874165533cSJose E. Roman    Input Parameters
588988ea7d6SRichard Tran Mills +  dm - the shell DM
589988ea7d6SRichard Tran Mills -  ltog - the local to global VecScatter context
590988ea7d6SRichard Tran Mills 
591988ea7d6SRichard Tran Mills    Level: advanced
592988ea7d6SRichard Tran Mills 
593db781477SPatrick Sanan .seealso: `DMShellSetLocalToGlobal()`, `DMLocalToGlobalBeginDefaultShell()`, `DMLocalToGlobalEndDefaultShell()`
594988ea7d6SRichard Tran Mills @*/
595*9371c9d4SSatish Balay PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM dm, VecScatter ltog) {
596988ea7d6SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
597988ea7d6SRichard Tran Mills 
598988ea7d6SRichard Tran Mills   PetscFunctionBegin;
5992d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
60097929ea7SJunchao Zhang   PetscValidHeaderSpecific(ltog, PETSCSF_CLASSID, 2);
6019566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)ltog));
6029566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltog));
603988ea7d6SRichard Tran Mills   shell->ltog = ltog;
604988ea7d6SRichard Tran Mills   PetscFunctionReturn(0);
605988ea7d6SRichard Tran Mills }
606988ea7d6SRichard Tran Mills 
607f3db62a7SRichard Tran Mills /*@
608f3db62a7SRichard Tran Mills    DMShellSetLocalToLocalVecScatter - Sets a VecScatter context for local to local communication
609f3db62a7SRichard Tran Mills 
610d083f849SBarry Smith    Logically Collective on dm
611f3db62a7SRichard Tran Mills 
6124165533cSJose E. Roman    Input Parameters
613f3db62a7SRichard Tran Mills +  dm - the shell DM
614f3db62a7SRichard Tran Mills -  ltol - the local to local VecScatter context
615f3db62a7SRichard Tran Mills 
616f3db62a7SRichard Tran Mills    Level: advanced
617f3db62a7SRichard Tran Mills 
618db781477SPatrick Sanan .seealso: `DMShellSetLocalToLocal()`, `DMLocalToLocalBeginDefaultShell()`, `DMLocalToLocalEndDefaultShell()`
619f3db62a7SRichard Tran Mills @*/
620*9371c9d4SSatish Balay PetscErrorCode DMShellSetLocalToLocalVecScatter(DM dm, VecScatter ltol) {
621f3db62a7SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
622f3db62a7SRichard Tran Mills 
623f3db62a7SRichard Tran Mills   PetscFunctionBegin;
6242d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
62597929ea7SJunchao Zhang   PetscValidHeaderSpecific(ltol, PETSCSF_CLASSID, 2);
6269566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)ltol));
6279566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltol));
628f3db62a7SRichard Tran Mills   shell->ltol = ltol;
629f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
630f3db62a7SRichard Tran Mills }
631f3db62a7SRichard Tran Mills 
6329bf9660cSLawrence Mitchell /*@C
6339bf9660cSLawrence Mitchell    DMShellSetCoarsen - Set the routine used to coarsen the shell DM
6349bf9660cSLawrence Mitchell 
635d083f849SBarry Smith    Logically Collective on dm
6369bf9660cSLawrence Mitchell 
6374165533cSJose E. Roman    Input Parameters
6389bf9660cSLawrence Mitchell +  dm - the shell DM
6399bf9660cSLawrence Mitchell -  coarsen - the routine that coarsens the DM
6409bf9660cSLawrence Mitchell 
6419bf9660cSLawrence Mitchell    Level: advanced
6429bf9660cSLawrence Mitchell 
643db781477SPatrick Sanan .seealso: `DMShellSetRefine()`, `DMCoarsen()`, `DMShellGetCoarsen()`, `DMShellSetContext()`, `DMShellGetContext()`
6449bf9660cSLawrence Mitchell @*/
645*9371c9d4SSatish Balay PetscErrorCode DMShellSetCoarsen(DM dm, PetscErrorCode (*coarsen)(DM, MPI_Comm, DM *)) {
646f572501eSLawrence Mitchell   PetscBool isshell;
647f572501eSLawrence Mitchell 
648f572501eSLawrence Mitchell   PetscFunctionBegin;
649f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6509566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
651f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
652f572501eSLawrence Mitchell   dm->ops->coarsen = coarsen;
653f572501eSLawrence Mitchell   PetscFunctionReturn(0);
654f572501eSLawrence Mitchell }
655f572501eSLawrence Mitchell 
6569bf9660cSLawrence Mitchell /*@C
6574363ddcaSBoris Boutkov    DMShellGetCoarsen - Get the routine used to coarsen the shell DM
6584363ddcaSBoris Boutkov 
659d083f849SBarry Smith    Logically Collective on dm
6604363ddcaSBoris Boutkov 
6614165533cSJose E. Roman    Input Parameter:
6624363ddcaSBoris Boutkov .  dm - the shell DM
6634363ddcaSBoris Boutkov 
6644165533cSJose E. Roman    Output Parameter:
6654363ddcaSBoris Boutkov .  coarsen - the routine that coarsens the DM
6664363ddcaSBoris Boutkov 
6674363ddcaSBoris Boutkov    Level: advanced
6684363ddcaSBoris Boutkov 
669db781477SPatrick Sanan .seealso: `DMShellSetCoarsen()`, `DMCoarsen()`, `DMShellSetRefine()`, `DMRefine()`
6704363ddcaSBoris Boutkov @*/
671*9371c9d4SSatish Balay PetscErrorCode DMShellGetCoarsen(DM dm, PetscErrorCode (**coarsen)(DM, MPI_Comm, DM *)) {
6724363ddcaSBoris Boutkov   PetscBool isshell;
6734363ddcaSBoris Boutkov 
6744363ddcaSBoris Boutkov   PetscFunctionBegin;
6754363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6769566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
6777a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
6784363ddcaSBoris Boutkov   *coarsen = dm->ops->coarsen;
6794363ddcaSBoris Boutkov   PetscFunctionReturn(0);
6804363ddcaSBoris Boutkov }
6814363ddcaSBoris Boutkov 
6824363ddcaSBoris Boutkov /*@C
6839bf9660cSLawrence Mitchell    DMShellSetRefine - Set the routine used to refine the shell DM
6849bf9660cSLawrence Mitchell 
685d083f849SBarry Smith    Logically Collective on dm
6869bf9660cSLawrence Mitchell 
6874165533cSJose E. Roman    Input Parameters
6889bf9660cSLawrence Mitchell +  dm - the shell DM
6899bf9660cSLawrence Mitchell -  refine - the routine that refines the DM
6909bf9660cSLawrence Mitchell 
6919bf9660cSLawrence Mitchell    Level: advanced
6929bf9660cSLawrence Mitchell 
693db781477SPatrick Sanan .seealso: `DMShellSetCoarsen()`, `DMRefine()`, `DMShellGetRefine()`, `DMShellSetContext()`, `DMShellGetContext()`
6949bf9660cSLawrence Mitchell @*/
695*9371c9d4SSatish Balay PetscErrorCode DMShellSetRefine(DM dm, PetscErrorCode (*refine)(DM, MPI_Comm, DM *)) {
696f572501eSLawrence Mitchell   PetscBool isshell;
697f572501eSLawrence Mitchell 
698f572501eSLawrence Mitchell   PetscFunctionBegin;
699f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7009566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
701f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
702f572501eSLawrence Mitchell   dm->ops->refine = refine;
703f572501eSLawrence Mitchell   PetscFunctionReturn(0);
704f572501eSLawrence Mitchell }
705f572501eSLawrence Mitchell 
7069bf9660cSLawrence Mitchell /*@C
7074363ddcaSBoris Boutkov    DMShellGetRefine - Get the routine used to refine the shell DM
7084363ddcaSBoris Boutkov 
709d083f849SBarry Smith    Logically Collective on dm
7104363ddcaSBoris Boutkov 
7114165533cSJose E. Roman    Input Parameter:
7124363ddcaSBoris Boutkov .  dm - the shell DM
7134363ddcaSBoris Boutkov 
7144165533cSJose E. Roman    Output Parameter:
7154363ddcaSBoris Boutkov .  refine - the routine that refines the DM
7164363ddcaSBoris Boutkov 
7174363ddcaSBoris Boutkov    Level: advanced
7184363ddcaSBoris Boutkov 
719db781477SPatrick Sanan .seealso: `DMShellSetCoarsen()`, `DMCoarsen()`, `DMShellSetRefine()`, `DMRefine()`
7204363ddcaSBoris Boutkov @*/
721*9371c9d4SSatish Balay PetscErrorCode DMShellGetRefine(DM dm, PetscErrorCode (**refine)(DM, MPI_Comm, DM *)) {
7224363ddcaSBoris Boutkov   PetscBool isshell;
7234363ddcaSBoris Boutkov 
7244363ddcaSBoris Boutkov   PetscFunctionBegin;
7254363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7269566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
7277a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
7284363ddcaSBoris Boutkov   *refine = dm->ops->refine;
7294363ddcaSBoris Boutkov   PetscFunctionReturn(0);
7304363ddcaSBoris Boutkov }
7314363ddcaSBoris Boutkov 
7324363ddcaSBoris Boutkov /*@C
7339bf9660cSLawrence Mitchell    DMShellSetCreateInterpolation - Set the routine used to create the interpolation operator
7349bf9660cSLawrence Mitchell 
735d083f849SBarry Smith    Logically Collective on dm
7369bf9660cSLawrence Mitchell 
7374165533cSJose E. Roman    Input Parameters
7389bf9660cSLawrence Mitchell +  dm - the shell DM
7399bf9660cSLawrence Mitchell -  interp - the routine to create the interpolation
7409bf9660cSLawrence Mitchell 
7419bf9660cSLawrence Mitchell    Level: advanced
7429bf9660cSLawrence Mitchell 
743db781477SPatrick Sanan .seealso: `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateInterpolation()`, `DMShellSetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
7449bf9660cSLawrence Mitchell @*/
745*9371c9d4SSatish Balay PetscErrorCode DMShellSetCreateInterpolation(DM dm, PetscErrorCode (*interp)(DM, DM, Mat *, Vec *)) {
746f572501eSLawrence Mitchell   PetscBool isshell;
747f572501eSLawrence Mitchell 
748f572501eSLawrence Mitchell   PetscFunctionBegin;
749f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7509566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
751f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
752f572501eSLawrence Mitchell   dm->ops->createinterpolation = interp;
753f572501eSLawrence Mitchell   PetscFunctionReturn(0);
754f572501eSLawrence Mitchell }
755f572501eSLawrence Mitchell 
7563ad4599aSBarry Smith /*@C
7574363ddcaSBoris Boutkov    DMShellGetCreateInterpolation - Get the routine used to create the interpolation operator
7584363ddcaSBoris Boutkov 
759d083f849SBarry Smith    Logically Collective on dm
7604363ddcaSBoris Boutkov 
7614165533cSJose E. Roman    Input Parameter:
7624165533cSJose E. Roman .  dm - the shell DM
763a4a986ddSBoris Boutkov 
7644165533cSJose E. Roman    Output Parameter:
7654165533cSJose E. Roman .  interp - the routine to create the interpolation
7664363ddcaSBoris Boutkov 
7674363ddcaSBoris Boutkov    Level: advanced
7684363ddcaSBoris Boutkov 
769db781477SPatrick Sanan .seealso: `DMShellGetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
7704363ddcaSBoris Boutkov @*/
771*9371c9d4SSatish Balay PetscErrorCode DMShellGetCreateInterpolation(DM dm, PetscErrorCode (**interp)(DM, DM, Mat *, Vec *)) {
7724363ddcaSBoris Boutkov   PetscBool isshell;
7734363ddcaSBoris Boutkov 
7744363ddcaSBoris Boutkov   PetscFunctionBegin;
7754363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7769566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
7777a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
7784363ddcaSBoris Boutkov   *interp = dm->ops->createinterpolation;
7794363ddcaSBoris Boutkov   PetscFunctionReturn(0);
7804363ddcaSBoris Boutkov }
7814363ddcaSBoris Boutkov 
7824363ddcaSBoris Boutkov /*@C
7833ad4599aSBarry Smith    DMShellSetCreateRestriction - Set the routine used to create the restriction operator
7843ad4599aSBarry Smith 
785d083f849SBarry Smith    Logically Collective on dm
7863ad4599aSBarry Smith 
7874165533cSJose E. Roman    Input Parameters
7883ad4599aSBarry Smith +  dm - the shell DM
7893ad4599aSBarry Smith -  striction- the routine to create the restriction
7903ad4599aSBarry Smith 
7913ad4599aSBarry Smith    Level: advanced
7923ad4599aSBarry Smith 
793db781477SPatrick Sanan .seealso: `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
7943ad4599aSBarry Smith @*/
795*9371c9d4SSatish Balay PetscErrorCode DMShellSetCreateRestriction(DM dm, PetscErrorCode (*restriction)(DM, DM, Mat *)) {
7963ad4599aSBarry Smith   PetscBool isshell;
7973ad4599aSBarry Smith 
7983ad4599aSBarry Smith   PetscFunctionBegin;
7993ad4599aSBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8009566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
8013ad4599aSBarry Smith   if (!isshell) PetscFunctionReturn(0);
8023ad4599aSBarry Smith   dm->ops->createrestriction = restriction;
8033ad4599aSBarry Smith   PetscFunctionReturn(0);
8043ad4599aSBarry Smith }
8053ad4599aSBarry Smith 
8069bf9660cSLawrence Mitchell /*@C
8074363ddcaSBoris Boutkov    DMShellGetCreateRestriction - Get the routine used to create the restriction operator
8084363ddcaSBoris Boutkov 
809d083f849SBarry Smith    Logically Collective on dm
8104363ddcaSBoris Boutkov 
8114165533cSJose E. Roman    Input Parameter:
8124165533cSJose E. Roman .  dm - the shell DM
813a4a986ddSBoris Boutkov 
8144165533cSJose E. Roman    Output Parameter:
8154165533cSJose E. Roman .  restriction - the routine to create the restriction
8164363ddcaSBoris Boutkov 
8174363ddcaSBoris Boutkov    Level: advanced
8184363ddcaSBoris Boutkov 
819db781477SPatrick Sanan .seealso: `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellSetContext()`, `DMShellGetContext()`
8204363ddcaSBoris Boutkov @*/
821*9371c9d4SSatish Balay PetscErrorCode DMShellGetCreateRestriction(DM dm, PetscErrorCode (**restriction)(DM, DM, Mat *)) {
8224363ddcaSBoris Boutkov   PetscBool isshell;
8234363ddcaSBoris Boutkov 
8244363ddcaSBoris Boutkov   PetscFunctionBegin;
8254363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8269566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
8277a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
8284363ddcaSBoris Boutkov   *restriction = dm->ops->createrestriction;
8294363ddcaSBoris Boutkov   PetscFunctionReturn(0);
8304363ddcaSBoris Boutkov }
8314363ddcaSBoris Boutkov 
8324363ddcaSBoris Boutkov /*@C
8339bf9660cSLawrence Mitchell    DMShellSetCreateInjection - Set the routine used to create the injection operator
8349bf9660cSLawrence Mitchell 
835d083f849SBarry Smith    Logically Collective on dm
8369bf9660cSLawrence Mitchell 
8374165533cSJose E. Roman    Input Parameters:
8389bf9660cSLawrence Mitchell +  dm - the shell DM
8399bf9660cSLawrence Mitchell -  inject - the routine to create the injection
8409bf9660cSLawrence Mitchell 
8419bf9660cSLawrence Mitchell    Level: advanced
8429bf9660cSLawrence Mitchell 
843db781477SPatrick Sanan .seealso: `DMShellSetCreateInterpolation()`, `DMCreateInjection()`, `DMShellGetCreateInjection()`, `DMShellSetContext()`, `DMShellGetContext()`
8449bf9660cSLawrence Mitchell @*/
845*9371c9d4SSatish Balay PetscErrorCode DMShellSetCreateInjection(DM dm, PetscErrorCode (*inject)(DM, DM, Mat *)) {
846f572501eSLawrence Mitchell   PetscBool isshell;
847f572501eSLawrence Mitchell 
848f572501eSLawrence Mitchell   PetscFunctionBegin;
849f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8509566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
851f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
8525a84ad33SLisandro Dalcin   dm->ops->createinjection = inject;
853f572501eSLawrence Mitchell   PetscFunctionReturn(0);
854f572501eSLawrence Mitchell }
855f572501eSLawrence Mitchell 
8564363ddcaSBoris Boutkov /*@C
8574363ddcaSBoris Boutkov    DMShellGetCreateInjection - Get the routine used to create the injection operator
8584363ddcaSBoris Boutkov 
859d083f849SBarry Smith    Logically Collective on dm
8604363ddcaSBoris Boutkov 
8614165533cSJose E. Roman    Input Parameter:
8624165533cSJose E. Roman .  dm - the shell DM
863a4a986ddSBoris Boutkov 
8644165533cSJose E. Roman    Output Parameter:
8654165533cSJose E. Roman .  inject - the routine to create the injection
8664363ddcaSBoris Boutkov 
8674363ddcaSBoris Boutkov    Level: advanced
8684363ddcaSBoris Boutkov 
869db781477SPatrick Sanan .seealso: `DMShellGetCreateInterpolation()`, `DMCreateInjection()`, `DMShellSetContext()`, `DMShellGetContext()`
8704363ddcaSBoris Boutkov @*/
871*9371c9d4SSatish Balay PetscErrorCode DMShellGetCreateInjection(DM dm, PetscErrorCode (**inject)(DM, DM, Mat *)) {
8724363ddcaSBoris Boutkov   PetscBool isshell;
8734363ddcaSBoris Boutkov 
8744363ddcaSBoris Boutkov   PetscFunctionBegin;
8754363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8769566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
8777a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
8785a84ad33SLisandro Dalcin   *inject = dm->ops->createinjection;
8794363ddcaSBoris Boutkov   PetscFunctionReturn(0);
8804363ddcaSBoris Boutkov }
8814363ddcaSBoris Boutkov 
8829bf9660cSLawrence Mitchell /*@C
8839bf9660cSLawrence Mitchell    DMShellSetCreateFieldDecomposition - Set the routine used to create a decomposition of fields for the shell DM
8849bf9660cSLawrence Mitchell 
885d083f849SBarry Smith    Logically Collective on dm
8869bf9660cSLawrence Mitchell 
8874165533cSJose E. Roman    Input Parameters:
8889bf9660cSLawrence Mitchell +  dm - the shell DM
8899bf9660cSLawrence Mitchell -  decomp - the routine to create the decomposition
8909bf9660cSLawrence Mitchell 
8919bf9660cSLawrence Mitchell    Level: advanced
8929bf9660cSLawrence Mitchell 
893db781477SPatrick Sanan .seealso: `DMCreateFieldDecomposition()`, `DMShellSetContext()`, `DMShellGetContext()`
8949bf9660cSLawrence Mitchell @*/
895*9371c9d4SSatish Balay PetscErrorCode DMShellSetCreateFieldDecomposition(DM dm, PetscErrorCode (*decomp)(DM, PetscInt *, char ***, IS **, DM **)) {
8965e2259d5SLawrence Mitchell   PetscBool isshell;
8975e2259d5SLawrence Mitchell 
8985e2259d5SLawrence Mitchell   PetscFunctionBegin;
8995e2259d5SLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9009566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
9015e2259d5SLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
9025e2259d5SLawrence Mitchell   dm->ops->createfielddecomposition = decomp;
9035e2259d5SLawrence Mitchell   PetscFunctionReturn(0);
9045e2259d5SLawrence Mitchell }
9055e2259d5SLawrence Mitchell 
906c00061e5SLawrence Mitchell /*@C
907e734121bSPatrick Farrell    DMShellSetCreateDomainDecomposition - Set the routine used to create a domain decomposition for the shell DM
908e734121bSPatrick Farrell 
909d083f849SBarry Smith    Logically Collective on dm
910e734121bSPatrick Farrell 
9114165533cSJose E. Roman    Input Parameters:
912e734121bSPatrick Farrell +  dm - the shell DM
913e734121bSPatrick Farrell -  decomp - the routine to create the decomposition
914e734121bSPatrick Farrell 
915e734121bSPatrick Farrell    Level: advanced
916e734121bSPatrick Farrell 
917db781477SPatrick Sanan .seealso: `DMCreateDomainDecomposition()`, `DMShellSetContext()`, `DMShellGetContext()`
918e734121bSPatrick Farrell @*/
919*9371c9d4SSatish Balay PetscErrorCode DMShellSetCreateDomainDecomposition(DM dm, PetscErrorCode (*decomp)(DM, PetscInt *, char ***, IS **, IS **, DM **)) {
920e734121bSPatrick Farrell   PetscBool isshell;
921e734121bSPatrick Farrell 
922e734121bSPatrick Farrell   PetscFunctionBegin;
923e734121bSPatrick Farrell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9249566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
925e734121bSPatrick Farrell   if (!isshell) PetscFunctionReturn(0);
926e734121bSPatrick Farrell   dm->ops->createdomaindecomposition = decomp;
927e734121bSPatrick Farrell   PetscFunctionReturn(0);
928e734121bSPatrick Farrell }
929e734121bSPatrick Farrell 
930e734121bSPatrick Farrell /*@C
931eef9d6cdSPatrick Farrell    DMShellSetCreateDomainDecompositionScatters - Set the routine used to create the scatter contexts for domain decomposition with a shell DM
932eef9d6cdSPatrick Farrell 
933d083f849SBarry Smith    Logically Collective on dm
934eef9d6cdSPatrick Farrell 
9354165533cSJose E. Roman    Input Parameters:
936eef9d6cdSPatrick Farrell +  dm - the shell DM
937eef9d6cdSPatrick Farrell -  scatter - the routine to create the scatters
938eef9d6cdSPatrick Farrell 
939eef9d6cdSPatrick Farrell    Level: advanced
940eef9d6cdSPatrick Farrell 
941db781477SPatrick Sanan .seealso: `DMCreateDomainDecompositionScatters()`, `DMShellSetContext()`, `DMShellGetContext()`
942eef9d6cdSPatrick Farrell @*/
943*9371c9d4SSatish Balay PetscErrorCode DMShellSetCreateDomainDecompositionScatters(DM dm, PetscErrorCode (*scatter)(DM, PetscInt, DM *, VecScatter **, VecScatter **, VecScatter **)) {
944eef9d6cdSPatrick Farrell   PetscBool isshell;
945eef9d6cdSPatrick Farrell 
946eef9d6cdSPatrick Farrell   PetscFunctionBegin;
947eef9d6cdSPatrick Farrell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9489566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
949eef9d6cdSPatrick Farrell   if (!isshell) PetscFunctionReturn(0);
950eef9d6cdSPatrick Farrell   dm->ops->createddscatters = scatter;
951eef9d6cdSPatrick Farrell   PetscFunctionReturn(0);
952eef9d6cdSPatrick Farrell }
953eef9d6cdSPatrick Farrell 
954eef9d6cdSPatrick Farrell /*@C
955c00061e5SLawrence Mitchell    DMShellSetCreateSubDM - Set the routine used to create a sub DM from the shell DM
956c00061e5SLawrence Mitchell 
957d083f849SBarry Smith    Logically Collective on dm
958c00061e5SLawrence Mitchell 
9594165533cSJose E. Roman    Input Parameters:
960c00061e5SLawrence Mitchell +  dm - the shell DM
961c00061e5SLawrence Mitchell -  subdm - the routine to create the decomposition
962c00061e5SLawrence Mitchell 
963c00061e5SLawrence Mitchell    Level: advanced
964c00061e5SLawrence Mitchell 
965db781477SPatrick Sanan .seealso: `DMCreateSubDM()`, `DMShellGetCreateSubDM()`, `DMShellSetContext()`, `DMShellGetContext()`
966c00061e5SLawrence Mitchell @*/
967*9371c9d4SSatish Balay PetscErrorCode DMShellSetCreateSubDM(DM dm, PetscErrorCode (*subdm)(DM, PetscInt, const PetscInt[], IS *, DM *)) {
968c00061e5SLawrence Mitchell   PetscBool isshell;
969c00061e5SLawrence Mitchell 
970c00061e5SLawrence Mitchell   PetscFunctionBegin;
971c00061e5SLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9729566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
973c00061e5SLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
974c00061e5SLawrence Mitchell   dm->ops->createsubdm = subdm;
975c00061e5SLawrence Mitchell   PetscFunctionReturn(0);
976c00061e5SLawrence Mitchell }
977c00061e5SLawrence Mitchell 
9784363ddcaSBoris Boutkov /*@C
9794363ddcaSBoris Boutkov    DMShellGetCreateSubDM - Get the routine used to create a sub DM from the shell DM
9804363ddcaSBoris Boutkov 
981d083f849SBarry Smith    Logically Collective on dm
9824363ddcaSBoris Boutkov 
9834165533cSJose E. Roman    Input Parameter:
9844165533cSJose E. Roman .  dm - the shell DM
985a4a986ddSBoris Boutkov 
9864165533cSJose E. Roman    Output Parameter:
9874165533cSJose E. Roman .  subdm - the routine to create the decomposition
9884363ddcaSBoris Boutkov 
9894363ddcaSBoris Boutkov    Level: advanced
9904363ddcaSBoris Boutkov 
991db781477SPatrick Sanan .seealso: `DMCreateSubDM()`, `DMShellSetCreateSubDM()`, `DMShellSetContext()`, `DMShellGetContext()`
9924363ddcaSBoris Boutkov @*/
993*9371c9d4SSatish Balay PetscErrorCode DMShellGetCreateSubDM(DM dm, PetscErrorCode (**subdm)(DM, PetscInt, const PetscInt[], IS *, DM *)) {
9944363ddcaSBoris Boutkov   PetscBool isshell;
9954363ddcaSBoris Boutkov 
9964363ddcaSBoris Boutkov   PetscFunctionBegin;
9974363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9989566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
9997a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
10004363ddcaSBoris Boutkov   *subdm = dm->ops->createsubdm;
10014363ddcaSBoris Boutkov   PetscFunctionReturn(0);
10024363ddcaSBoris Boutkov }
10034363ddcaSBoris Boutkov 
1004*9371c9d4SSatish Balay static PetscErrorCode DMDestroy_Shell(DM dm) {
1005fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
1006fe1899a2SJed Brown 
1007fe1899a2SJed Brown   PetscFunctionBegin;
10089566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&shell->A));
10099566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xglobal));
10109566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xlocal));
10119566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->gtol));
10129566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltog));
10139566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltol));
10147b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
10159566063dSJacob Faibussowitsch   PetscCall(PetscFree(shell));
1016fe1899a2SJed Brown   PetscFunctionReturn(0);
1017fe1899a2SJed Brown }
1018fe1899a2SJed Brown 
1019*9371c9d4SSatish Balay static PetscErrorCode DMView_Shell(DM dm, PetscViewer v) {
10202d53ad75SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
10212d53ad75SBarry Smith 
10222d53ad75SBarry Smith   PetscFunctionBegin;
102301f8681bSStefano Zampini   if (shell->Xglobal) PetscCall(VecView(shell->Xglobal, v));
10242d53ad75SBarry Smith   PetscFunctionReturn(0);
10252d53ad75SBarry Smith }
10262d53ad75SBarry Smith 
1027*9371c9d4SSatish Balay static PetscErrorCode DMLoad_Shell(DM dm, PetscViewer v) {
10282d53ad75SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
10292d53ad75SBarry Smith 
10302d53ad75SBarry Smith   PetscFunctionBegin;
10319566063dSJacob Faibussowitsch   PetscCall(VecCreate(PetscObjectComm((PetscObject)dm), &shell->Xglobal));
10329566063dSJacob Faibussowitsch   PetscCall(VecLoad(shell->Xglobal, v));
10332d53ad75SBarry Smith   PetscFunctionReturn(0);
10342d53ad75SBarry Smith }
1035fe1899a2SJed Brown 
1036*9371c9d4SSatish Balay PetscErrorCode DMCreateSubDM_Shell(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) {
10376e44b4cfSMatthew G. Knepley   PetscFunctionBegin;
10389566063dSJacob Faibussowitsch   if (subdm) PetscCall(DMShellCreate(PetscObjectComm((PetscObject)dm), subdm));
10399566063dSJacob Faibussowitsch   PetscCall(DMCreateSectionSubDM(dm, numFields, fields, is, subdm));
10406e44b4cfSMatthew G. Knepley   PetscFunctionReturn(0);
10416e44b4cfSMatthew G. Knepley }
10426e44b4cfSMatthew G. Knepley 
1043*9371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm) {
1044fe1899a2SJed Brown   DM_Shell *shell;
1045fe1899a2SJed Brown 
1046fe1899a2SJed Brown   PetscFunctionBegin;
10479566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(dm, &shell));
10488c87107bSJed Brown   dm->data = shell;
1049fe1899a2SJed Brown 
10508c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
10518c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
1052dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
10538c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
10542d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
10552d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
10567a108d1dSBarry Smith   dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell;
10577a108d1dSBarry Smith   dm->ops->globaltolocalend   = DMGlobalToLocalEndDefaultShell;
105855daaa54SRichard Tran Mills   dm->ops->localtoglobalbegin = DMLocalToGlobalBeginDefaultShell;
105955daaa54SRichard Tran Mills   dm->ops->localtoglobalend   = DMLocalToGlobalEndDefaultShell;
106063731094SRichard Tran Mills   dm->ops->localtolocalbegin  = DMLocalToLocalBeginDefaultShell;
106163731094SRichard Tran Mills   dm->ops->localtolocalend    = DMLocalToLocalEndDefaultShell;
10626e44b4cfSMatthew G. Knepley   dm->ops->createsubdm        = DMCreateSubDM_Shell;
10639566063dSJacob Faibussowitsch   PetscCall(DMSetMatType(dm, MATDENSE));
1064fe1899a2SJed Brown   PetscFunctionReturn(0);
1065fe1899a2SJed Brown }
1066fe1899a2SJed Brown 
1067fe1899a2SJed Brown /*@
1068fe1899a2SJed Brown     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
1069fe1899a2SJed Brown 
1070d083f849SBarry Smith     Collective
1071fe1899a2SJed Brown 
1072fe1899a2SJed Brown     Input Parameter:
1073fe1899a2SJed Brown .   comm - the processors that will share the global vector
1074fe1899a2SJed Brown 
1075fe1899a2SJed Brown     Output Parameters:
1076fe1899a2SJed Brown .   shell - the shell DM
1077fe1899a2SJed Brown 
1078fe1899a2SJed Brown     Level: advanced
1079fe1899a2SJed Brown 
1080db781477SPatrick Sanan .seealso `DMDestroy()`, `DMCreateGlobalVector()`, `DMCreateLocalVector()`, `DMShellSetContext()`, `DMShellGetContext()`
1081fe1899a2SJed Brown @*/
1082*9371c9d4SSatish Balay PetscErrorCode DMShellCreate(MPI_Comm comm, DM *dm) {
1083fe1899a2SJed Brown   PetscFunctionBegin;
1084fe1899a2SJed Brown   PetscValidPointer(dm, 2);
10859566063dSJacob Faibussowitsch   PetscCall(DMCreate(comm, dm));
10869566063dSJacob Faibussowitsch   PetscCall(DMSetType(*dm, DMSHELL));
10879566063dSJacob Faibussowitsch   PetscCall(DMSetUp(*dm));
1088fe1899a2SJed Brown   PetscFunctionReturn(0);
1089fe1899a2SJed Brown }
1090