xref: /petsc/src/dm/impls/shell/dmshell.c (revision 3ba1676111f5c958fe6c2729b46ca4d523958bb3)
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 /*@
177a108d1dSBarry Smith    DMGlobalToLocalBeginDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to begin a global to local scatter
188d359177SBarry Smith    Collective
198d359177SBarry Smith 
204165533cSJose E. Roman    Input Parameters:
218d359177SBarry Smith +  dm - shell DM
228d359177SBarry Smith .  g - global vector
238d359177SBarry Smith .  mode - InsertMode
248d359177SBarry Smith -  l - local vector
258d359177SBarry Smith 
267a108d1dSBarry Smith    Level: advanced
278d359177SBarry Smith 
287a108d1dSBarry 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.
297a108d1dSBarry Smith 
30db781477SPatrick Sanan .seealso: `DMGlobalToLocalEndDefaultShell()`
318d359177SBarry Smith @*/
32d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalBeginDefaultShell(DM dm, Vec g, InsertMode mode, Vec l)
33d71ae5a4SJacob Faibussowitsch {
348d359177SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
358d359177SBarry Smith 
368d359177SBarry Smith   PetscFunctionBegin;
377a8be351SBarry Smith   PetscCheck(shell->gtol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
389566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->gtol, g, l, mode, SCATTER_FORWARD));
39*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
408d359177SBarry Smith }
418d359177SBarry Smith 
427a108d1dSBarry Smith /*@
437a108d1dSBarry Smith    DMGlobalToLocalEndDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to end a global to local scatter
448d359177SBarry Smith    Collective
458d359177SBarry Smith 
464165533cSJose E. Roman    Input Parameters:
478d359177SBarry Smith +  dm - shell DM
488d359177SBarry Smith .  g - global vector
498d359177SBarry Smith .  mode - InsertMode
508d359177SBarry Smith -  l - local vector
518d359177SBarry Smith 
527a108d1dSBarry Smith    Level: advanced
538d359177SBarry Smith 
54db781477SPatrick Sanan .seealso: `DMGlobalToLocalBeginDefaultShell()`
558d359177SBarry Smith @*/
56d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalEndDefaultShell(DM dm, Vec g, InsertMode mode, Vec l)
57d71ae5a4SJacob Faibussowitsch {
588d359177SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
598d359177SBarry Smith 
608d359177SBarry Smith   PetscFunctionBegin;
617a8be351SBarry Smith   PetscCheck(shell->gtol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
629566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->gtol, g, l, mode, SCATTER_FORWARD));
63*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
648d359177SBarry Smith }
658d359177SBarry Smith 
66c5076b69SRichard Tran Mills /*@
67c5076b69SRichard Tran Mills    DMLocalToGlobalBeginDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to begin a local to global scatter
68c5076b69SRichard Tran Mills    Collective
69c5076b69SRichard Tran Mills 
704165533cSJose E. Roman    Input Parameters:
71c5076b69SRichard Tran Mills +  dm - shell DM
72c5076b69SRichard Tran Mills .  l - local vector
73c5076b69SRichard Tran Mills .  mode - InsertMode
74c5076b69SRichard Tran Mills -  g - global vector
75c5076b69SRichard Tran Mills 
76c5076b69SRichard Tran Mills    Level: advanced
77c5076b69SRichard Tran Mills 
78c5076b69SRichard 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.
79c5076b69SRichard Tran Mills 
80db781477SPatrick Sanan .seealso: `DMLocalToGlobalEndDefaultShell()`
81c5076b69SRichard Tran Mills @*/
82d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalBeginDefaultShell(DM dm, Vec l, InsertMode mode, Vec g)
83d71ae5a4SJacob Faibussowitsch {
84c5076b69SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
85c5076b69SRichard Tran Mills 
86c5076b69SRichard Tran Mills   PetscFunctionBegin;
877a8be351SBarry Smith   PetscCheck(shell->ltog, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
889566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->ltog, l, g, mode, SCATTER_FORWARD));
89*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
90c5076b69SRichard Tran Mills }
91c5076b69SRichard Tran Mills 
92c5076b69SRichard Tran Mills /*@
93c5076b69SRichard Tran Mills    DMLocalToGlobalEndDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to end a local to global scatter
94c5076b69SRichard Tran Mills    Collective
95c5076b69SRichard Tran Mills 
964165533cSJose E. Roman    Input Parameters:
97c5076b69SRichard Tran Mills +  dm - shell DM
98c5076b69SRichard Tran Mills .  l - local vector
99c5076b69SRichard Tran Mills .  mode - InsertMode
100c5076b69SRichard Tran Mills -  g - global vector
101c5076b69SRichard Tran Mills 
102c5076b69SRichard Tran Mills    Level: advanced
103c5076b69SRichard Tran Mills 
104db781477SPatrick Sanan .seealso: `DMLocalToGlobalBeginDefaultShell()`
105c5076b69SRichard Tran Mills @*/
106d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalEndDefaultShell(DM dm, Vec l, InsertMode mode, Vec g)
107d71ae5a4SJacob Faibussowitsch {
108c5076b69SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
109c5076b69SRichard Tran Mills 
110c5076b69SRichard Tran Mills   PetscFunctionBegin;
1117a8be351SBarry Smith   PetscCheck(shell->ltog, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
1129566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->ltog, l, g, mode, SCATTER_FORWARD));
113*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
114c5076b69SRichard Tran Mills }
115c5076b69SRichard Tran Mills 
116f3db62a7SRichard Tran Mills /*@
117f3db62a7SRichard Tran Mills    DMLocalToLocalBeginDefaultShell - Uses the LocalToLocal VecScatter context set by the user to begin a local to local scatter
118f3db62a7SRichard Tran Mills    Collective
119f3db62a7SRichard Tran Mills 
1204165533cSJose E. Roman    Input Parameters:
121f3db62a7SRichard Tran Mills +  dm - shell DM
122f3db62a7SRichard Tran Mills .  g - the original local vector
123f3db62a7SRichard Tran Mills -  mode - InsertMode
124f3db62a7SRichard Tran Mills 
125f3db62a7SRichard Tran Mills    Output Parameter:
126f3db62a7SRichard Tran Mills .  l  - the local vector with correct ghost values
127f3db62a7SRichard Tran Mills 
128f3db62a7SRichard Tran Mills    Level: advanced
129f3db62a7SRichard Tran Mills 
130f3db62a7SRichard 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.
131f3db62a7SRichard Tran Mills 
132db781477SPatrick Sanan .seealso: `DMLocalToLocalEndDefaultShell()`
133f3db62a7SRichard Tran Mills @*/
134d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalBeginDefaultShell(DM dm, Vec g, InsertMode mode, Vec l)
135d71ae5a4SJacob Faibussowitsch {
136f3db62a7SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
137f3db62a7SRichard Tran Mills 
138f3db62a7SRichard Tran Mills   PetscFunctionBegin;
1397a8be351SBarry Smith   PetscCheck(shell->ltol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToLocalVecScatter()");
1409566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->ltol, g, l, mode, SCATTER_FORWARD));
141*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
142f3db62a7SRichard Tran Mills }
143f3db62a7SRichard Tran Mills 
144f3db62a7SRichard Tran Mills /*@
145f3db62a7SRichard Tran Mills    DMLocalToLocalEndDefaultShell - Uses the LocalToLocal VecScatter context set by the user to end a local to local scatter
146f3db62a7SRichard Tran Mills    Collective
147f3db62a7SRichard Tran Mills 
1484165533cSJose E. Roman    Input Parameters:
149f3db62a7SRichard Tran Mills +  dm - shell DM
150f3db62a7SRichard Tran Mills .  g - the original local vector
151f3db62a7SRichard Tran Mills -  mode - InsertMode
152f3db62a7SRichard Tran Mills 
153f3db62a7SRichard Tran Mills    Output Parameter:
154f3db62a7SRichard Tran Mills .  l  - the local vector with correct ghost values
155f3db62a7SRichard Tran Mills 
156f3db62a7SRichard Tran Mills    Level: advanced
157f3db62a7SRichard Tran Mills 
158db781477SPatrick Sanan .seealso: `DMLocalToLocalBeginDefaultShell()`
159f3db62a7SRichard Tran Mills @*/
160d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalEndDefaultShell(DM dm, Vec g, InsertMode mode, Vec l)
161d71ae5a4SJacob Faibussowitsch {
162f3db62a7SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
163f3db62a7SRichard Tran Mills 
164f3db62a7SRichard Tran Mills   PetscFunctionBegin;
1657a8be351SBarry Smith   PetscCheck(shell->ltol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
1669566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->ltol, g, l, mode, SCATTER_FORWARD));
167*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
168f3db62a7SRichard Tran Mills }
169c5076b69SRichard Tran Mills 
170d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCreateMatrix_Shell(DM dm, Mat *J)
171d71ae5a4SJacob Faibussowitsch {
172fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
173fe1899a2SJed Brown   Mat       A;
174fe1899a2SJed Brown 
175fe1899a2SJed Brown   PetscFunctionBegin;
176fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
177064a246eSJacob Faibussowitsch   PetscValidPointer(J, 2);
1787bde9f88SJed Brown   if (!shell->A) {
1797bde9f88SJed Brown     if (shell->Xglobal) {
1807bde9f88SJed Brown       PetscInt m, M;
1819566063dSJacob Faibussowitsch       PetscCall(PetscInfo(dm, "Naively creating matrix using global vector distribution without preallocation\n"));
1829566063dSJacob Faibussowitsch       PetscCall(VecGetSize(shell->Xglobal, &M));
1839566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(shell->Xglobal, &m));
1849566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)dm), &shell->A));
1859566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(shell->A, m, m, M, M));
1869566063dSJacob Faibussowitsch       PetscCall(MatSetType(shell->A, dm->mattype));
1879566063dSJacob Faibussowitsch       PetscCall(MatSetUp(shell->A));
188ce94432eSBarry Smith     } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector");
1897bde9f88SJed Brown   }
190fe1899a2SJed Brown   A = shell->A;
1919566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(A, MAT_SHARE_NONZERO_PATTERN, J));
1929566063dSJacob Faibussowitsch   PetscCall(MatSetDM(*J, dm));
193*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
194fe1899a2SJed Brown }
195fe1899a2SJed Brown 
196d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateGlobalVector_Shell(DM dm, Vec *gvec)
197d71ae5a4SJacob Faibussowitsch {
198fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
199fe1899a2SJed Brown   Vec       X;
200fe1899a2SJed Brown 
201fe1899a2SJed Brown   PetscFunctionBegin;
202fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
203fe1899a2SJed Brown   PetscValidPointer(gvec, 2);
204ea78f98cSLisandro Dalcin   *gvec = NULL;
205fe1899a2SJed Brown   X     = shell->Xglobal;
2067a8be351SBarry Smith   PetscCheck(X, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
20706f803f6SStefano Zampini   /* Need to create a copy in order to attach the DM to the vector */
2089566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(X, gvec));
2099566063dSJacob Faibussowitsch   PetscCall(VecZeroEntries(*gvec));
2109566063dSJacob Faibussowitsch   PetscCall(VecSetDM(*gvec, dm));
211*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
212fe1899a2SJed Brown }
213fe1899a2SJed Brown 
214d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLocalVector_Shell(DM dm, Vec *gvec)
215d71ae5a4SJacob Faibussowitsch {
216dc43b69eSJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
217dc43b69eSJed Brown   Vec       X;
218dc43b69eSJed Brown 
219dc43b69eSJed Brown   PetscFunctionBegin;
220dc43b69eSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
221dc43b69eSJed Brown   PetscValidPointer(gvec, 2);
222ea78f98cSLisandro Dalcin   *gvec = NULL;
223dc43b69eSJed Brown   X     = shell->Xlocal;
2247a8be351SBarry Smith   PetscCheck(X, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()");
22506f803f6SStefano Zampini   /* Need to create a copy in order to attach the DM to the vector */
2269566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(X, gvec));
2279566063dSJacob Faibussowitsch   PetscCall(VecZeroEntries(*gvec));
2289566063dSJacob Faibussowitsch   PetscCall(VecSetDM(*gvec, dm));
229*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
230dc43b69eSJed Brown }
231dc43b69eSJed Brown 
232fef3a512SBarry Smith /*@
23309904cd0SBarry Smith    DMShellSetDestroyContext - set a function that destroys the context provided with `DMShellSetContext()`
23409904cd0SBarry Smith 
23509904cd0SBarry Smith    Collective
23609904cd0SBarry Smith 
23709904cd0SBarry Smith    Input Parameters:
23809904cd0SBarry Smith .  ctx - the context
23909904cd0SBarry Smith 
24009904cd0SBarry Smith    Level: advanced
24109904cd0SBarry Smith 
24209904cd0SBarry Smith .seealso: `DMShellSetContext()`, `DMShellGetContext()`
24309904cd0SBarry Smith @*/
244d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetDestroyContext(DM dm, PetscErrorCode (*destroyctx)(void *))
245d71ae5a4SJacob Faibussowitsch {
24609904cd0SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
24709904cd0SBarry Smith   PetscBool isshell;
24809904cd0SBarry Smith 
24909904cd0SBarry Smith   PetscFunctionBegin;
25009904cd0SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
25109904cd0SBarry Smith   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
252*3ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
25309904cd0SBarry Smith   shell->destroyctx = destroyctx;
254*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
25509904cd0SBarry Smith }
25609904cd0SBarry Smith 
25709904cd0SBarry Smith /*@
258fef3a512SBarry Smith    DMShellSetContext - set some data to be usable by this DM
259fef3a512SBarry Smith 
260fef3a512SBarry Smith    Collective
261fef3a512SBarry Smith 
2624165533cSJose E. Roman    Input Parameters:
263fef3a512SBarry Smith +  dm - shell DM
264fef3a512SBarry Smith -  ctx - the context
265fef3a512SBarry Smith 
266fef3a512SBarry Smith    Level: advanced
267fef3a512SBarry Smith 
268db781477SPatrick Sanan .seealso: `DMCreateMatrix()`, `DMShellGetContext()`
269fef3a512SBarry Smith @*/
270d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetContext(DM dm, void *ctx)
271d71ae5a4SJacob Faibussowitsch {
272fef3a512SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
273fef3a512SBarry Smith   PetscBool isshell;
274fef3a512SBarry Smith 
275fef3a512SBarry Smith   PetscFunctionBegin;
276fef3a512SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2779566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
278*3ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
279fef3a512SBarry Smith   shell->ctx = ctx;
280*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
281fef3a512SBarry Smith }
282fef3a512SBarry Smith 
283fef3a512SBarry Smith /*@
284bf890c61SBoris Boutkov    DMShellGetContext - Returns the user-provided context associated to the DM
285fef3a512SBarry Smith 
286fef3a512SBarry Smith    Collective
287fef3a512SBarry Smith 
2884165533cSJose E. Roman    Input Parameter:
289fef3a512SBarry Smith .  dm - shell DM
290fef3a512SBarry Smith 
2914165533cSJose E. Roman    Output Parameter:
292fef3a512SBarry Smith .  ctx - the context
293fef3a512SBarry Smith 
294fef3a512SBarry Smith    Level: advanced
295fef3a512SBarry Smith 
296db781477SPatrick Sanan .seealso: `DMCreateMatrix()`, `DMShellSetContext()`
297fef3a512SBarry Smith @*/
298d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetContext(DM dm, void *ctx)
299d71ae5a4SJacob Faibussowitsch {
300fef3a512SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
301fef3a512SBarry Smith   PetscBool isshell;
302fef3a512SBarry Smith 
303fef3a512SBarry Smith   PetscFunctionBegin;
304fef3a512SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3059566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
3067a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
3073ec1f749SStefano Zampini   *(void **)ctx = shell->ctx;
308*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
309fef3a512SBarry Smith }
310fef3a512SBarry Smith 
311fe1899a2SJed Brown /*@
312fe1899a2SJed Brown    DMShellSetMatrix - sets a template matrix associated with the DMShell
313fe1899a2SJed Brown 
314fe1899a2SJed Brown    Collective
315fe1899a2SJed Brown 
3164165533cSJose E. Roman    Input Parameters:
317fe1899a2SJed Brown +  dm - shell DM
318fe1899a2SJed Brown -  J - template matrix
319fe1899a2SJed Brown 
320fe1899a2SJed Brown    Level: advanced
321fe1899a2SJed Brown 
32206f803f6SStefano Zampini    Developer Notes:
32306f803f6SStefano 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.
32406f803f6SStefano Zampini 
325db781477SPatrick Sanan .seealso: `DMCreateMatrix()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
326fe1899a2SJed Brown @*/
327d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetMatrix(DM dm, Mat J)
328d71ae5a4SJacob Faibussowitsch {
329fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
3308c87107bSJed Brown   PetscBool isshell;
33106f803f6SStefano Zampini   DM        mdm;
332fe1899a2SJed Brown 
333fe1899a2SJed Brown   PetscFunctionBegin;
3348c87107bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3358c87107bSJed Brown   PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
3369566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
337*3ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
338*3ba16761SJacob Faibussowitsch   if (J == shell->A) PetscFunctionReturn(PETSC_SUCCESS);
3399566063dSJacob Faibussowitsch   PetscCall(MatGetDM(J, &mdm));
3409566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)J));
3419566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&shell->A));
34206f803f6SStefano Zampini   if (mdm == dm) {
3439566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(J, MAT_SHARE_NONZERO_PATTERN, &shell->A));
3449566063dSJacob Faibussowitsch     PetscCall(MatSetDM(shell->A, NULL));
34506f803f6SStefano Zampini   } else shell->A = J;
346*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
347fe1899a2SJed Brown }
348fe1899a2SJed Brown 
349fe1899a2SJed Brown /*@C
350fe1899a2SJed Brown    DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM
351fe1899a2SJed Brown 
352d083f849SBarry Smith    Logically Collective on dm
353fe1899a2SJed Brown 
3544165533cSJose E. Roman    Input Parameters:
355fe1899a2SJed Brown +  dm - the shell DM
356fe1899a2SJed Brown -  func - the function to create a matrix
357fe1899a2SJed Brown 
358fe1899a2SJed Brown    Level: advanced
359fe1899a2SJed Brown 
360db781477SPatrick Sanan .seealso: `DMCreateMatrix()`, `DMShellSetMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
361fe1899a2SJed Brown @*/
362d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateMatrix(DM dm, PetscErrorCode (*func)(DM, Mat *))
363d71ae5a4SJacob Faibussowitsch {
364fe1899a2SJed Brown   PetscFunctionBegin;
365fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
366fe1899a2SJed Brown   dm->ops->creatematrix = func;
367*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
368fe1899a2SJed Brown }
369fe1899a2SJed Brown 
370fe1899a2SJed Brown /*@
371fe1899a2SJed Brown    DMShellSetGlobalVector - sets a template global vector associated with the DMShell
372fe1899a2SJed Brown 
373d083f849SBarry Smith    Logically Collective on dm
374fe1899a2SJed Brown 
3754165533cSJose E. Roman    Input Parameters:
376fe1899a2SJed Brown +  dm - shell DM
377fe1899a2SJed Brown -  X - template vector
378fe1899a2SJed Brown 
379fe1899a2SJed Brown    Level: advanced
380fe1899a2SJed Brown 
381db781477SPatrick Sanan .seealso: `DMCreateGlobalVector()`, `DMShellSetMatrix()`, `DMShellSetCreateGlobalVector()`
382fe1899a2SJed Brown @*/
383d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetGlobalVector(DM dm, Vec X)
384d71ae5a4SJacob Faibussowitsch {
385fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
3868c87107bSJed Brown   PetscBool isshell;
387cca7ec1eSBarry Smith   DM        vdm;
388fe1899a2SJed Brown 
389fe1899a2SJed Brown   PetscFunctionBegin;
3908c87107bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3918c87107bSJed Brown   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
3929566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
393*3ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
3949566063dSJacob Faibussowitsch   PetscCall(VecGetDM(X, &vdm));
395cca7ec1eSBarry Smith   /*
396cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
397cca7ec1eSBarry 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
398cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
399cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
400cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
401cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
402cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
403cca7ec1eSBarry Smith       for pointing out the problem.
404cca7ec1eSBarry Smith    */
405*3ba16761SJacob Faibussowitsch   if (vdm == dm) PetscFunctionReturn(PETSC_SUCCESS);
4069566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)X));
4079566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xglobal));
408fe1899a2SJed Brown   shell->Xglobal = X;
409*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
410fe1899a2SJed Brown }
411fe1899a2SJed Brown 
41204d741b1SMatthew G. Knepley /*@
41304d741b1SMatthew G. Knepley   DMShellGetGlobalVector - Returns the template global vector associated with the DMShell, or NULL if it was not set
41404d741b1SMatthew G. Knepley 
41504d741b1SMatthew G. Knepley    Not collective
41604d741b1SMatthew G. Knepley 
4174165533cSJose E. Roman    Input Parameters:
41804d741b1SMatthew G. Knepley +  dm - shell DM
41904d741b1SMatthew G. Knepley -  X - template vector
42004d741b1SMatthew G. Knepley 
42104d741b1SMatthew G. Knepley    Level: advanced
42204d741b1SMatthew G. Knepley 
423db781477SPatrick Sanan .seealso: `DMShellSetGlobalVector()`, `DMShellSetCreateGlobalVector()`, `DMCreateGlobalVector()`
42404d741b1SMatthew G. Knepley @*/
425d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetGlobalVector(DM dm, Vec *X)
426d71ae5a4SJacob Faibussowitsch {
42704d741b1SMatthew G. Knepley   DM_Shell *shell = (DM_Shell *)dm->data;
42804d741b1SMatthew G. Knepley   PetscBool isshell;
42904d741b1SMatthew G. Knepley 
43004d741b1SMatthew G. Knepley   PetscFunctionBegin;
43104d741b1SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
43204d741b1SMatthew G. Knepley   PetscValidPointer(X, 2);
4339566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
434*3ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
43504d741b1SMatthew G. Knepley   *X = shell->Xglobal;
436*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
43704d741b1SMatthew G. Knepley }
43804d741b1SMatthew G. Knepley 
439fe1899a2SJed Brown /*@C
440fe1899a2SJed Brown    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM
441fe1899a2SJed Brown 
442fe1899a2SJed Brown    Logically Collective
443fe1899a2SJed Brown 
4444165533cSJose E. Roman    Input Parameters:
445fe1899a2SJed Brown +  dm - the shell DM
446fe1899a2SJed Brown -  func - the creation routine
447fe1899a2SJed Brown 
448fe1899a2SJed Brown    Level: advanced
449fe1899a2SJed Brown 
450db781477SPatrick Sanan .seealso: `DMShellSetGlobalVector()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
451fe1899a2SJed Brown @*/
452d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateGlobalVector(DM dm, PetscErrorCode (*func)(DM, Vec *))
453d71ae5a4SJacob Faibussowitsch {
454fe1899a2SJed Brown   PetscFunctionBegin;
455fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
456fe1899a2SJed Brown   dm->ops->createglobalvector = func;
457*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
458fe1899a2SJed Brown }
459fe1899a2SJed Brown 
460dc43b69eSJed Brown /*@
461dc43b69eSJed Brown    DMShellSetLocalVector - sets a template local vector associated with the DMShell
462dc43b69eSJed Brown 
463d083f849SBarry Smith    Logically Collective on dm
464dc43b69eSJed Brown 
4654165533cSJose E. Roman    Input Parameters:
466dc43b69eSJed Brown +  dm - shell DM
467dc43b69eSJed Brown -  X - template vector
468dc43b69eSJed Brown 
469dc43b69eSJed Brown    Level: advanced
470dc43b69eSJed Brown 
471db781477SPatrick Sanan .seealso: `DMCreateLocalVector()`, `DMShellSetMatrix()`, `DMShellSetCreateLocalVector()`
472dc43b69eSJed Brown @*/
473d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalVector(DM dm, Vec X)
474d71ae5a4SJacob Faibussowitsch {
475dc43b69eSJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
476dc43b69eSJed Brown   PetscBool isshell;
477cca7ec1eSBarry Smith   DM        vdm;
478dc43b69eSJed Brown 
479dc43b69eSJed Brown   PetscFunctionBegin;
480dc43b69eSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
481dc43b69eSJed Brown   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
4829566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
483*3ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
4849566063dSJacob Faibussowitsch   PetscCall(VecGetDM(X, &vdm));
485cca7ec1eSBarry Smith   /*
486cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
487cca7ec1eSBarry 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
488cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
489cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
490cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
491cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
492cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
493cca7ec1eSBarry Smith       for pointing out the problem.
494cca7ec1eSBarry Smith    */
495*3ba16761SJacob Faibussowitsch   if (vdm == dm) PetscFunctionReturn(PETSC_SUCCESS);
4969566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)X));
4979566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xlocal));
498dc43b69eSJed Brown   shell->Xlocal = X;
499*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
500dc43b69eSJed Brown }
501dc43b69eSJed Brown 
502dc43b69eSJed Brown /*@C
503dc43b69eSJed Brown    DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM
504dc43b69eSJed Brown 
505dc43b69eSJed Brown    Logically Collective
506dc43b69eSJed Brown 
5074165533cSJose E. Roman    Input Parameters:
508dc43b69eSJed Brown +  dm - the shell DM
509dc43b69eSJed Brown -  func - the creation routine
510dc43b69eSJed Brown 
511dc43b69eSJed Brown    Level: advanced
512dc43b69eSJed Brown 
513db781477SPatrick Sanan .seealso: `DMShellSetLocalVector()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
514dc43b69eSJed Brown @*/
515d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateLocalVector(DM dm, PetscErrorCode (*func)(DM, Vec *))
516d71ae5a4SJacob Faibussowitsch {
517dc43b69eSJed Brown   PetscFunctionBegin;
518dc43b69eSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
519dc43b69eSJed Brown   dm->ops->createlocalvector = func;
520*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
521dc43b69eSJed Brown }
522dc43b69eSJed Brown 
5238339e6d0SRichard Tran Mills /*@C
5248339e6d0SRichard Tran Mills    DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter
5258339e6d0SRichard Tran Mills 
526d083f849SBarry Smith    Logically Collective on dm
5278339e6d0SRichard Tran Mills 
5284165533cSJose E. Roman    Input Parameters
5298339e6d0SRichard Tran Mills +  dm - the shell DM
5308339e6d0SRichard Tran Mills .  begin - the routine that begins the global to local scatter
5318339e6d0SRichard Tran Mills -  end - the routine that ends the global to local scatter
5328339e6d0SRichard Tran Mills 
53395452b02SPatrick Sanan    Notes:
53495452b02SPatrick Sanan     If these functions are not provided but DMShellSetGlobalToLocalVecScatter() is called then
535f3db62a7SRichard Tran Mills    DMGlobalToLocalBeginDefaultShell()/DMGlobalToLocalEndDefaultShell() are used to to perform the transfers
5367a108d1dSBarry Smith 
5378339e6d0SRichard Tran Mills    Level: advanced
5388339e6d0SRichard Tran Mills 
539db781477SPatrick Sanan .seealso: `DMShellSetLocalToGlobal()`, `DMGlobalToLocalBeginDefaultShell()`, `DMGlobalToLocalEndDefaultShell()`
5408339e6d0SRichard Tran Mills @*/
541d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetGlobalToLocal(DM dm, PetscErrorCode (*begin)(DM, Vec, InsertMode, Vec), PetscErrorCode (*end)(DM, Vec, InsertMode, Vec))
542d71ae5a4SJacob Faibussowitsch {
5438339e6d0SRichard Tran Mills   PetscFunctionBegin;
5442d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5458339e6d0SRichard Tran Mills   dm->ops->globaltolocalbegin = begin;
5468339e6d0SRichard Tran Mills   dm->ops->globaltolocalend   = end;
547*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5488339e6d0SRichard Tran Mills }
5498339e6d0SRichard Tran Mills 
5508339e6d0SRichard Tran Mills /*@C
5518339e6d0SRichard Tran Mills    DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter
5528339e6d0SRichard Tran Mills 
553d083f849SBarry Smith    Logically Collective on dm
5548339e6d0SRichard Tran Mills 
5554165533cSJose E. Roman    Input Parameters
5568339e6d0SRichard Tran Mills +  dm - the shell DM
5578339e6d0SRichard Tran Mills .  begin - the routine that begins the local to global scatter
5588339e6d0SRichard Tran Mills -  end - the routine that ends the local to global scatter
5598339e6d0SRichard Tran Mills 
56095452b02SPatrick Sanan    Notes:
56195452b02SPatrick Sanan     If these functions are not provided but DMShellSetLocalToGlobalVecScatter() is called then
562f3db62a7SRichard Tran Mills    DMLocalToGlobalBeginDefaultShell()/DMLocalToGlobalEndDefaultShell() are used to to perform the transfers
563f3db62a7SRichard Tran Mills 
5648339e6d0SRichard Tran Mills    Level: advanced
5658339e6d0SRichard Tran Mills 
566db781477SPatrick Sanan .seealso: `DMShellSetGlobalToLocal()`
5678339e6d0SRichard Tran Mills @*/
568d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalToGlobal(DM dm, PetscErrorCode (*begin)(DM, Vec, InsertMode, Vec), PetscErrorCode (*end)(DM, Vec, InsertMode, Vec))
569d71ae5a4SJacob Faibussowitsch {
5708339e6d0SRichard Tran Mills   PetscFunctionBegin;
5712d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5728339e6d0SRichard Tran Mills   dm->ops->localtoglobalbegin = begin;
5738339e6d0SRichard Tran Mills   dm->ops->localtoglobalend   = end;
574*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5758339e6d0SRichard Tran Mills }
5768339e6d0SRichard Tran Mills 
577f3db62a7SRichard Tran Mills /*@C
578f3db62a7SRichard Tran Mills    DMShellSetLocalToLocal - Sets the routines used to perform a local to local scatter
579f3db62a7SRichard Tran Mills 
580d083f849SBarry Smith    Logically Collective on dm
581f3db62a7SRichard Tran Mills 
5824165533cSJose E. Roman    Input Parameters
583f3db62a7SRichard Tran Mills +  dm - the shell DM
584f3db62a7SRichard Tran Mills .  begin - the routine that begins the local to local scatter
585f3db62a7SRichard Tran Mills -  end - the routine that ends the local to local scatter
586f3db62a7SRichard Tran Mills 
58795452b02SPatrick Sanan    Notes:
58895452b02SPatrick Sanan     If these functions are not provided but DMShellSetLocalToLocalVecScatter() is called then
589f3db62a7SRichard Tran Mills    DMLocalToLocalBeginDefaultShell()/DMLocalToLocalEndDefaultShell() are used to to perform the transfers
590f3db62a7SRichard Tran Mills 
591f3db62a7SRichard Tran Mills    Level: advanced
592f3db62a7SRichard Tran Mills 
593db781477SPatrick Sanan .seealso: `DMShellSetGlobalToLocal()`, `DMLocalToLocalBeginDefaultShell()`, `DMLocalToLocalEndDefaultShell()`
594f3db62a7SRichard Tran Mills @*/
595d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalToLocal(DM dm, PetscErrorCode (*begin)(DM, Vec, InsertMode, Vec), PetscErrorCode (*end)(DM, Vec, InsertMode, Vec))
596d71ae5a4SJacob Faibussowitsch {
597f3db62a7SRichard Tran Mills   PetscFunctionBegin;
5982d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
599f3db62a7SRichard Tran Mills   dm->ops->localtolocalbegin = begin;
600f3db62a7SRichard Tran Mills   dm->ops->localtolocalend   = end;
601*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
602f3db62a7SRichard Tran Mills }
603f3db62a7SRichard Tran Mills 
60481634712SRichard Tran Mills /*@
60581634712SRichard Tran Mills    DMShellSetGlobalToLocalVecScatter - Sets a VecScatter context for global to local communication
60681634712SRichard Tran Mills 
607d083f849SBarry Smith    Logically Collective on dm
60881634712SRichard Tran Mills 
6094165533cSJose E. Roman    Input Parameters
61081634712SRichard Tran Mills +  dm - the shell DM
61181634712SRichard Tran Mills -  gtol - the global to local VecScatter context
61281634712SRichard Tran Mills 
61381634712SRichard Tran Mills    Level: advanced
61481634712SRichard Tran Mills 
615db781477SPatrick Sanan .seealso: `DMShellSetGlobalToLocal()`, `DMGlobalToLocalBeginDefaultShell()`, `DMGlobalToLocalEndDefaultShell()`
61681634712SRichard Tran Mills @*/
617d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter gtol)
618d71ae5a4SJacob Faibussowitsch {
61981634712SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
62081634712SRichard Tran Mills 
621b300e4a8SRichard Tran Mills   PetscFunctionBegin;
6222d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
62397929ea7SJunchao Zhang   PetscValidHeaderSpecific(gtol, PETSCSF_CLASSID, 2);
6249566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)gtol));
6259566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->gtol));
62681634712SRichard Tran Mills   shell->gtol = gtol;
627*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
62881634712SRichard Tran Mills }
62981634712SRichard Tran Mills 
630988ea7d6SRichard Tran Mills /*@
631988ea7d6SRichard Tran Mills    DMShellSetLocalToGlobalVecScatter - Sets a VecScatter context for local to global communication
632988ea7d6SRichard Tran Mills 
633d083f849SBarry Smith    Logically Collective on dm
634988ea7d6SRichard Tran Mills 
6354165533cSJose E. Roman    Input Parameters
636988ea7d6SRichard Tran Mills +  dm - the shell DM
637988ea7d6SRichard Tran Mills -  ltog - the local to global VecScatter context
638988ea7d6SRichard Tran Mills 
639988ea7d6SRichard Tran Mills    Level: advanced
640988ea7d6SRichard Tran Mills 
641db781477SPatrick Sanan .seealso: `DMShellSetLocalToGlobal()`, `DMLocalToGlobalBeginDefaultShell()`, `DMLocalToGlobalEndDefaultShell()`
642988ea7d6SRichard Tran Mills @*/
643d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM dm, VecScatter ltog)
644d71ae5a4SJacob Faibussowitsch {
645988ea7d6SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
646988ea7d6SRichard Tran Mills 
647988ea7d6SRichard Tran Mills   PetscFunctionBegin;
6482d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
64997929ea7SJunchao Zhang   PetscValidHeaderSpecific(ltog, PETSCSF_CLASSID, 2);
6509566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)ltog));
6519566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltog));
652988ea7d6SRichard Tran Mills   shell->ltog = ltog;
653*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
654988ea7d6SRichard Tran Mills }
655988ea7d6SRichard Tran Mills 
656f3db62a7SRichard Tran Mills /*@
657f3db62a7SRichard Tran Mills    DMShellSetLocalToLocalVecScatter - Sets a VecScatter context for local to local communication
658f3db62a7SRichard Tran Mills 
659d083f849SBarry Smith    Logically Collective on dm
660f3db62a7SRichard Tran Mills 
6614165533cSJose E. Roman    Input Parameters
662f3db62a7SRichard Tran Mills +  dm - the shell DM
663f3db62a7SRichard Tran Mills -  ltol - the local to local VecScatter context
664f3db62a7SRichard Tran Mills 
665f3db62a7SRichard Tran Mills    Level: advanced
666f3db62a7SRichard Tran Mills 
667db781477SPatrick Sanan .seealso: `DMShellSetLocalToLocal()`, `DMLocalToLocalBeginDefaultShell()`, `DMLocalToLocalEndDefaultShell()`
668f3db62a7SRichard Tran Mills @*/
669d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalToLocalVecScatter(DM dm, VecScatter ltol)
670d71ae5a4SJacob Faibussowitsch {
671f3db62a7SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
672f3db62a7SRichard Tran Mills 
673f3db62a7SRichard Tran Mills   PetscFunctionBegin;
6742d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
67597929ea7SJunchao Zhang   PetscValidHeaderSpecific(ltol, PETSCSF_CLASSID, 2);
6769566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)ltol));
6779566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltol));
678f3db62a7SRichard Tran Mills   shell->ltol = ltol;
679*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
680f3db62a7SRichard Tran Mills }
681f3db62a7SRichard Tran Mills 
6829bf9660cSLawrence Mitchell /*@C
6839bf9660cSLawrence Mitchell    DMShellSetCoarsen - Set the routine used to coarsen 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 -  coarsen - the routine that coarsens the DM
6909bf9660cSLawrence Mitchell 
6919bf9660cSLawrence Mitchell    Level: advanced
6929bf9660cSLawrence Mitchell 
693db781477SPatrick Sanan .seealso: `DMShellSetRefine()`, `DMCoarsen()`, `DMShellGetCoarsen()`, `DMShellSetContext()`, `DMShellGetContext()`
6949bf9660cSLawrence Mitchell @*/
695d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCoarsen(DM dm, PetscErrorCode (*coarsen)(DM, MPI_Comm, DM *))
696d71ae5a4SJacob Faibussowitsch {
697f572501eSLawrence Mitchell   PetscBool isshell;
698f572501eSLawrence Mitchell 
699f572501eSLawrence Mitchell   PetscFunctionBegin;
700f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7019566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
702*3ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
703f572501eSLawrence Mitchell   dm->ops->coarsen = coarsen;
704*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
705f572501eSLawrence Mitchell }
706f572501eSLawrence Mitchell 
7079bf9660cSLawrence Mitchell /*@C
7084363ddcaSBoris Boutkov    DMShellGetCoarsen - Get the routine used to coarsen the shell DM
7094363ddcaSBoris Boutkov 
710d083f849SBarry Smith    Logically Collective on dm
7114363ddcaSBoris Boutkov 
7124165533cSJose E. Roman    Input Parameter:
7134363ddcaSBoris Boutkov .  dm - the shell DM
7144363ddcaSBoris Boutkov 
7154165533cSJose E. Roman    Output Parameter:
7164363ddcaSBoris Boutkov .  coarsen - the routine that coarsens the DM
7174363ddcaSBoris Boutkov 
7184363ddcaSBoris Boutkov    Level: advanced
7194363ddcaSBoris Boutkov 
720db781477SPatrick Sanan .seealso: `DMShellSetCoarsen()`, `DMCoarsen()`, `DMShellSetRefine()`, `DMRefine()`
7214363ddcaSBoris Boutkov @*/
722d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCoarsen(DM dm, PetscErrorCode (**coarsen)(DM, MPI_Comm, DM *))
723d71ae5a4SJacob Faibussowitsch {
7244363ddcaSBoris Boutkov   PetscBool isshell;
7254363ddcaSBoris Boutkov 
7264363ddcaSBoris Boutkov   PetscFunctionBegin;
7274363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7289566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
7297a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
7304363ddcaSBoris Boutkov   *coarsen = dm->ops->coarsen;
731*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7324363ddcaSBoris Boutkov }
7334363ddcaSBoris Boutkov 
7344363ddcaSBoris Boutkov /*@C
7359bf9660cSLawrence Mitchell    DMShellSetRefine - Set the routine used to refine the shell DM
7369bf9660cSLawrence Mitchell 
737d083f849SBarry Smith    Logically Collective on dm
7389bf9660cSLawrence Mitchell 
7394165533cSJose E. Roman    Input Parameters
7409bf9660cSLawrence Mitchell +  dm - the shell DM
7419bf9660cSLawrence Mitchell -  refine - the routine that refines the DM
7429bf9660cSLawrence Mitchell 
7439bf9660cSLawrence Mitchell    Level: advanced
7449bf9660cSLawrence Mitchell 
745db781477SPatrick Sanan .seealso: `DMShellSetCoarsen()`, `DMRefine()`, `DMShellGetRefine()`, `DMShellSetContext()`, `DMShellGetContext()`
7469bf9660cSLawrence Mitchell @*/
747d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetRefine(DM dm, PetscErrorCode (*refine)(DM, MPI_Comm, DM *))
748d71ae5a4SJacob Faibussowitsch {
749f572501eSLawrence Mitchell   PetscBool isshell;
750f572501eSLawrence Mitchell 
751f572501eSLawrence Mitchell   PetscFunctionBegin;
752f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7539566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
754*3ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
755f572501eSLawrence Mitchell   dm->ops->refine = refine;
756*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
757f572501eSLawrence Mitchell }
758f572501eSLawrence Mitchell 
7599bf9660cSLawrence Mitchell /*@C
7604363ddcaSBoris Boutkov    DMShellGetRefine - Get the routine used to refine the shell DM
7614363ddcaSBoris Boutkov 
762d083f849SBarry Smith    Logically Collective on dm
7634363ddcaSBoris Boutkov 
7644165533cSJose E. Roman    Input Parameter:
7654363ddcaSBoris Boutkov .  dm - the shell DM
7664363ddcaSBoris Boutkov 
7674165533cSJose E. Roman    Output Parameter:
7684363ddcaSBoris Boutkov .  refine - the routine that refines the DM
7694363ddcaSBoris Boutkov 
7704363ddcaSBoris Boutkov    Level: advanced
7714363ddcaSBoris Boutkov 
772db781477SPatrick Sanan .seealso: `DMShellSetCoarsen()`, `DMCoarsen()`, `DMShellSetRefine()`, `DMRefine()`
7734363ddcaSBoris Boutkov @*/
774d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetRefine(DM dm, PetscErrorCode (**refine)(DM, MPI_Comm, DM *))
775d71ae5a4SJacob Faibussowitsch {
7764363ddcaSBoris Boutkov   PetscBool isshell;
7774363ddcaSBoris Boutkov 
7784363ddcaSBoris Boutkov   PetscFunctionBegin;
7794363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7809566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
7817a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
7824363ddcaSBoris Boutkov   *refine = dm->ops->refine;
783*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7844363ddcaSBoris Boutkov }
7854363ddcaSBoris Boutkov 
7864363ddcaSBoris Boutkov /*@C
7879bf9660cSLawrence Mitchell    DMShellSetCreateInterpolation - Set the routine used to create the interpolation operator
7889bf9660cSLawrence Mitchell 
789d083f849SBarry Smith    Logically Collective on dm
7909bf9660cSLawrence Mitchell 
7914165533cSJose E. Roman    Input Parameters
7929bf9660cSLawrence Mitchell +  dm - the shell DM
7939bf9660cSLawrence Mitchell -  interp - the routine to create the interpolation
7949bf9660cSLawrence Mitchell 
7959bf9660cSLawrence Mitchell    Level: advanced
7969bf9660cSLawrence Mitchell 
797db781477SPatrick Sanan .seealso: `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateInterpolation()`, `DMShellSetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
7989bf9660cSLawrence Mitchell @*/
799d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateInterpolation(DM dm, PetscErrorCode (*interp)(DM, DM, Mat *, Vec *))
800d71ae5a4SJacob Faibussowitsch {
801f572501eSLawrence Mitchell   PetscBool isshell;
802f572501eSLawrence Mitchell 
803f572501eSLawrence Mitchell   PetscFunctionBegin;
804f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8059566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
806*3ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
807f572501eSLawrence Mitchell   dm->ops->createinterpolation = interp;
808*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
809f572501eSLawrence Mitchell }
810f572501eSLawrence Mitchell 
8113ad4599aSBarry Smith /*@C
8124363ddcaSBoris Boutkov    DMShellGetCreateInterpolation - Get the routine used to create the interpolation operator
8134363ddcaSBoris Boutkov 
814d083f849SBarry Smith    Logically Collective on dm
8154363ddcaSBoris Boutkov 
8164165533cSJose E. Roman    Input Parameter:
8174165533cSJose E. Roman .  dm - the shell DM
818a4a986ddSBoris Boutkov 
8194165533cSJose E. Roman    Output Parameter:
8204165533cSJose E. Roman .  interp - the routine to create the interpolation
8214363ddcaSBoris Boutkov 
8224363ddcaSBoris Boutkov    Level: advanced
8234363ddcaSBoris Boutkov 
824db781477SPatrick Sanan .seealso: `DMShellGetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
8254363ddcaSBoris Boutkov @*/
826d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCreateInterpolation(DM dm, PetscErrorCode (**interp)(DM, DM, Mat *, Vec *))
827d71ae5a4SJacob Faibussowitsch {
8284363ddcaSBoris Boutkov   PetscBool isshell;
8294363ddcaSBoris Boutkov 
8304363ddcaSBoris Boutkov   PetscFunctionBegin;
8314363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8329566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
8337a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
8344363ddcaSBoris Boutkov   *interp = dm->ops->createinterpolation;
835*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8364363ddcaSBoris Boutkov }
8374363ddcaSBoris Boutkov 
8384363ddcaSBoris Boutkov /*@C
8393ad4599aSBarry Smith    DMShellSetCreateRestriction - Set the routine used to create the restriction operator
8403ad4599aSBarry Smith 
841d083f849SBarry Smith    Logically Collective on dm
8423ad4599aSBarry Smith 
8434165533cSJose E. Roman    Input Parameters
8443ad4599aSBarry Smith +  dm - the shell DM
8453ad4599aSBarry Smith -  striction- the routine to create the restriction
8463ad4599aSBarry Smith 
8473ad4599aSBarry Smith    Level: advanced
8483ad4599aSBarry Smith 
849db781477SPatrick Sanan .seealso: `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
8503ad4599aSBarry Smith @*/
851d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateRestriction(DM dm, PetscErrorCode (*restriction)(DM, DM, Mat *))
852d71ae5a4SJacob Faibussowitsch {
8533ad4599aSBarry Smith   PetscBool isshell;
8543ad4599aSBarry Smith 
8553ad4599aSBarry Smith   PetscFunctionBegin;
8563ad4599aSBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8579566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
858*3ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
8593ad4599aSBarry Smith   dm->ops->createrestriction = restriction;
860*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8613ad4599aSBarry Smith }
8623ad4599aSBarry Smith 
8639bf9660cSLawrence Mitchell /*@C
8644363ddcaSBoris Boutkov    DMShellGetCreateRestriction - Get the routine used to create the restriction operator
8654363ddcaSBoris Boutkov 
866d083f849SBarry Smith    Logically Collective on dm
8674363ddcaSBoris Boutkov 
8684165533cSJose E. Roman    Input Parameter:
8694165533cSJose E. Roman .  dm - the shell DM
870a4a986ddSBoris Boutkov 
8714165533cSJose E. Roman    Output Parameter:
8724165533cSJose E. Roman .  restriction - the routine to create the restriction
8734363ddcaSBoris Boutkov 
8744363ddcaSBoris Boutkov    Level: advanced
8754363ddcaSBoris Boutkov 
876db781477SPatrick Sanan .seealso: `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellSetContext()`, `DMShellGetContext()`
8774363ddcaSBoris Boutkov @*/
878d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCreateRestriction(DM dm, PetscErrorCode (**restriction)(DM, DM, Mat *))
879d71ae5a4SJacob Faibussowitsch {
8804363ddcaSBoris Boutkov   PetscBool isshell;
8814363ddcaSBoris Boutkov 
8824363ddcaSBoris Boutkov   PetscFunctionBegin;
8834363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8849566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
8857a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
8864363ddcaSBoris Boutkov   *restriction = dm->ops->createrestriction;
887*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8884363ddcaSBoris Boutkov }
8894363ddcaSBoris Boutkov 
8904363ddcaSBoris Boutkov /*@C
8919bf9660cSLawrence Mitchell    DMShellSetCreateInjection - Set the routine used to create the injection operator
8929bf9660cSLawrence Mitchell 
893d083f849SBarry Smith    Logically Collective on dm
8949bf9660cSLawrence Mitchell 
8954165533cSJose E. Roman    Input Parameters:
8969bf9660cSLawrence Mitchell +  dm - the shell DM
8979bf9660cSLawrence Mitchell -  inject - the routine to create the injection
8989bf9660cSLawrence Mitchell 
8999bf9660cSLawrence Mitchell    Level: advanced
9009bf9660cSLawrence Mitchell 
901db781477SPatrick Sanan .seealso: `DMShellSetCreateInterpolation()`, `DMCreateInjection()`, `DMShellGetCreateInjection()`, `DMShellSetContext()`, `DMShellGetContext()`
9029bf9660cSLawrence Mitchell @*/
903d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateInjection(DM dm, PetscErrorCode (*inject)(DM, DM, Mat *))
904d71ae5a4SJacob Faibussowitsch {
905f572501eSLawrence Mitchell   PetscBool isshell;
906f572501eSLawrence Mitchell 
907f572501eSLawrence Mitchell   PetscFunctionBegin;
908f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9099566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
910*3ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
9115a84ad33SLisandro Dalcin   dm->ops->createinjection = inject;
912*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
913f572501eSLawrence Mitchell }
914f572501eSLawrence Mitchell 
9154363ddcaSBoris Boutkov /*@C
9164363ddcaSBoris Boutkov    DMShellGetCreateInjection - Get the routine used to create the injection operator
9174363ddcaSBoris Boutkov 
918d083f849SBarry Smith    Logically Collective on dm
9194363ddcaSBoris Boutkov 
9204165533cSJose E. Roman    Input Parameter:
9214165533cSJose E. Roman .  dm - the shell DM
922a4a986ddSBoris Boutkov 
9234165533cSJose E. Roman    Output Parameter:
9244165533cSJose E. Roman .  inject - the routine to create the injection
9254363ddcaSBoris Boutkov 
9264363ddcaSBoris Boutkov    Level: advanced
9274363ddcaSBoris Boutkov 
928db781477SPatrick Sanan .seealso: `DMShellGetCreateInterpolation()`, `DMCreateInjection()`, `DMShellSetContext()`, `DMShellGetContext()`
9294363ddcaSBoris Boutkov @*/
930d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCreateInjection(DM dm, PetscErrorCode (**inject)(DM, DM, Mat *))
931d71ae5a4SJacob Faibussowitsch {
9324363ddcaSBoris Boutkov   PetscBool isshell;
9334363ddcaSBoris Boutkov 
9344363ddcaSBoris Boutkov   PetscFunctionBegin;
9354363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9369566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
9377a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
9385a84ad33SLisandro Dalcin   *inject = dm->ops->createinjection;
939*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9404363ddcaSBoris Boutkov }
9414363ddcaSBoris Boutkov 
9429bf9660cSLawrence Mitchell /*@C
9439bf9660cSLawrence Mitchell    DMShellSetCreateFieldDecomposition - Set the routine used to create a decomposition of fields for the shell DM
9449bf9660cSLawrence Mitchell 
945d083f849SBarry Smith    Logically Collective on dm
9469bf9660cSLawrence Mitchell 
9474165533cSJose E. Roman    Input Parameters:
9489bf9660cSLawrence Mitchell +  dm - the shell DM
9499bf9660cSLawrence Mitchell -  decomp - the routine to create the decomposition
9509bf9660cSLawrence Mitchell 
9519bf9660cSLawrence Mitchell    Level: advanced
9529bf9660cSLawrence Mitchell 
953db781477SPatrick Sanan .seealso: `DMCreateFieldDecomposition()`, `DMShellSetContext()`, `DMShellGetContext()`
9549bf9660cSLawrence Mitchell @*/
955d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateFieldDecomposition(DM dm, PetscErrorCode (*decomp)(DM, PetscInt *, char ***, IS **, DM **))
956d71ae5a4SJacob Faibussowitsch {
9575e2259d5SLawrence Mitchell   PetscBool isshell;
9585e2259d5SLawrence Mitchell 
9595e2259d5SLawrence Mitchell   PetscFunctionBegin;
9605e2259d5SLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9619566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
962*3ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
9635e2259d5SLawrence Mitchell   dm->ops->createfielddecomposition = decomp;
964*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9655e2259d5SLawrence Mitchell }
9665e2259d5SLawrence Mitchell 
967c00061e5SLawrence Mitchell /*@C
968e734121bSPatrick Farrell    DMShellSetCreateDomainDecomposition - Set the routine used to create a domain decomposition for the shell DM
969e734121bSPatrick Farrell 
970d083f849SBarry Smith    Logically Collective on dm
971e734121bSPatrick Farrell 
9724165533cSJose E. Roman    Input Parameters:
973e734121bSPatrick Farrell +  dm - the shell DM
974e734121bSPatrick Farrell -  decomp - the routine to create the decomposition
975e734121bSPatrick Farrell 
976e734121bSPatrick Farrell    Level: advanced
977e734121bSPatrick Farrell 
978db781477SPatrick Sanan .seealso: `DMCreateDomainDecomposition()`, `DMShellSetContext()`, `DMShellGetContext()`
979e734121bSPatrick Farrell @*/
980d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateDomainDecomposition(DM dm, PetscErrorCode (*decomp)(DM, PetscInt *, char ***, IS **, IS **, DM **))
981d71ae5a4SJacob Faibussowitsch {
982e734121bSPatrick Farrell   PetscBool isshell;
983e734121bSPatrick Farrell 
984e734121bSPatrick Farrell   PetscFunctionBegin;
985e734121bSPatrick Farrell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9869566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
987*3ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
988e734121bSPatrick Farrell   dm->ops->createdomaindecomposition = decomp;
989*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
990e734121bSPatrick Farrell }
991e734121bSPatrick Farrell 
992e734121bSPatrick Farrell /*@C
993eef9d6cdSPatrick Farrell    DMShellSetCreateDomainDecompositionScatters - Set the routine used to create the scatter contexts for domain decomposition with a shell DM
994eef9d6cdSPatrick Farrell 
995d083f849SBarry Smith    Logically Collective on dm
996eef9d6cdSPatrick Farrell 
9974165533cSJose E. Roman    Input Parameters:
998eef9d6cdSPatrick Farrell +  dm - the shell DM
999eef9d6cdSPatrick Farrell -  scatter - the routine to create the scatters
1000eef9d6cdSPatrick Farrell 
1001eef9d6cdSPatrick Farrell    Level: advanced
1002eef9d6cdSPatrick Farrell 
1003db781477SPatrick Sanan .seealso: `DMCreateDomainDecompositionScatters()`, `DMShellSetContext()`, `DMShellGetContext()`
1004eef9d6cdSPatrick Farrell @*/
1005d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateDomainDecompositionScatters(DM dm, PetscErrorCode (*scatter)(DM, PetscInt, DM *, VecScatter **, VecScatter **, VecScatter **))
1006d71ae5a4SJacob Faibussowitsch {
1007eef9d6cdSPatrick Farrell   PetscBool isshell;
1008eef9d6cdSPatrick Farrell 
1009eef9d6cdSPatrick Farrell   PetscFunctionBegin;
1010eef9d6cdSPatrick Farrell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10119566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
1012*3ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
1013eef9d6cdSPatrick Farrell   dm->ops->createddscatters = scatter;
1014*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1015eef9d6cdSPatrick Farrell }
1016eef9d6cdSPatrick Farrell 
1017eef9d6cdSPatrick Farrell /*@C
1018c00061e5SLawrence Mitchell    DMShellSetCreateSubDM - Set the routine used to create a sub DM from the shell DM
1019c00061e5SLawrence Mitchell 
1020d083f849SBarry Smith    Logically Collective on dm
1021c00061e5SLawrence Mitchell 
10224165533cSJose E. Roman    Input Parameters:
1023c00061e5SLawrence Mitchell +  dm - the shell DM
1024c00061e5SLawrence Mitchell -  subdm - the routine to create the decomposition
1025c00061e5SLawrence Mitchell 
1026c00061e5SLawrence Mitchell    Level: advanced
1027c00061e5SLawrence Mitchell 
1028db781477SPatrick Sanan .seealso: `DMCreateSubDM()`, `DMShellGetCreateSubDM()`, `DMShellSetContext()`, `DMShellGetContext()`
1029c00061e5SLawrence Mitchell @*/
1030d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateSubDM(DM dm, PetscErrorCode (*subdm)(DM, PetscInt, const PetscInt[], IS *, DM *))
1031d71ae5a4SJacob Faibussowitsch {
1032c00061e5SLawrence Mitchell   PetscBool isshell;
1033c00061e5SLawrence Mitchell 
1034c00061e5SLawrence Mitchell   PetscFunctionBegin;
1035c00061e5SLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10369566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
1037*3ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
1038c00061e5SLawrence Mitchell   dm->ops->createsubdm = subdm;
1039*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1040c00061e5SLawrence Mitchell }
1041c00061e5SLawrence Mitchell 
10424363ddcaSBoris Boutkov /*@C
10434363ddcaSBoris Boutkov    DMShellGetCreateSubDM - Get the routine used to create a sub DM from the shell DM
10444363ddcaSBoris Boutkov 
1045d083f849SBarry Smith    Logically Collective on dm
10464363ddcaSBoris Boutkov 
10474165533cSJose E. Roman    Input Parameter:
10484165533cSJose E. Roman .  dm - the shell DM
1049a4a986ddSBoris Boutkov 
10504165533cSJose E. Roman    Output Parameter:
10514165533cSJose E. Roman .  subdm - the routine to create the decomposition
10524363ddcaSBoris Boutkov 
10534363ddcaSBoris Boutkov    Level: advanced
10544363ddcaSBoris Boutkov 
1055db781477SPatrick Sanan .seealso: `DMCreateSubDM()`, `DMShellSetCreateSubDM()`, `DMShellSetContext()`, `DMShellGetContext()`
10564363ddcaSBoris Boutkov @*/
1057d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCreateSubDM(DM dm, PetscErrorCode (**subdm)(DM, PetscInt, const PetscInt[], IS *, DM *))
1058d71ae5a4SJacob Faibussowitsch {
10594363ddcaSBoris Boutkov   PetscBool isshell;
10604363ddcaSBoris Boutkov 
10614363ddcaSBoris Boutkov   PetscFunctionBegin;
10624363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10639566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
10647a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
10654363ddcaSBoris Boutkov   *subdm = dm->ops->createsubdm;
1066*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10674363ddcaSBoris Boutkov }
10684363ddcaSBoris Boutkov 
1069d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDestroy_Shell(DM dm)
1070d71ae5a4SJacob Faibussowitsch {
1071fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
1072fe1899a2SJed Brown 
1073fe1899a2SJed Brown   PetscFunctionBegin;
107409904cd0SBarry Smith   if (shell->destroyctx) PetscCallBack("Destroy Context", (*shell->destroyctx)(shell->ctx));
10759566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&shell->A));
10769566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xglobal));
10779566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xlocal));
10789566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->gtol));
10799566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltog));
10809566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltol));
10817b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
10829566063dSJacob Faibussowitsch   PetscCall(PetscFree(shell));
1083*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1084fe1899a2SJed Brown }
1085fe1899a2SJed Brown 
1086d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMView_Shell(DM dm, PetscViewer v)
1087d71ae5a4SJacob Faibussowitsch {
10882d53ad75SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
10892d53ad75SBarry Smith 
10902d53ad75SBarry Smith   PetscFunctionBegin;
109101f8681bSStefano Zampini   if (shell->Xglobal) PetscCall(VecView(shell->Xglobal, v));
1092*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10932d53ad75SBarry Smith }
10942d53ad75SBarry Smith 
1095d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLoad_Shell(DM dm, PetscViewer v)
1096d71ae5a4SJacob Faibussowitsch {
10972d53ad75SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
10982d53ad75SBarry Smith 
10992d53ad75SBarry Smith   PetscFunctionBegin;
11009566063dSJacob Faibussowitsch   PetscCall(VecCreate(PetscObjectComm((PetscObject)dm), &shell->Xglobal));
11019566063dSJacob Faibussowitsch   PetscCall(VecLoad(shell->Xglobal, v));
1102*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11032d53ad75SBarry Smith }
1104fe1899a2SJed Brown 
1105d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSubDM_Shell(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm)
1106d71ae5a4SJacob Faibussowitsch {
11076e44b4cfSMatthew G. Knepley   PetscFunctionBegin;
11089566063dSJacob Faibussowitsch   if (subdm) PetscCall(DMShellCreate(PetscObjectComm((PetscObject)dm), subdm));
11099566063dSJacob Faibussowitsch   PetscCall(DMCreateSectionSubDM(dm, numFields, fields, is, subdm));
1110*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11116e44b4cfSMatthew G. Knepley }
11126e44b4cfSMatthew G. Knepley 
1113d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm)
1114d71ae5a4SJacob Faibussowitsch {
1115fe1899a2SJed Brown   DM_Shell *shell;
1116fe1899a2SJed Brown 
1117fe1899a2SJed Brown   PetscFunctionBegin;
11184dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&shell));
11198c87107bSJed Brown   dm->data = shell;
1120fe1899a2SJed Brown 
11218c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
11228c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
1123dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
11248c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
11252d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
11262d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
11277a108d1dSBarry Smith   dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell;
11287a108d1dSBarry Smith   dm->ops->globaltolocalend   = DMGlobalToLocalEndDefaultShell;
112955daaa54SRichard Tran Mills   dm->ops->localtoglobalbegin = DMLocalToGlobalBeginDefaultShell;
113055daaa54SRichard Tran Mills   dm->ops->localtoglobalend   = DMLocalToGlobalEndDefaultShell;
113163731094SRichard Tran Mills   dm->ops->localtolocalbegin  = DMLocalToLocalBeginDefaultShell;
113263731094SRichard Tran Mills   dm->ops->localtolocalend    = DMLocalToLocalEndDefaultShell;
11336e44b4cfSMatthew G. Knepley   dm->ops->createsubdm        = DMCreateSubDM_Shell;
11349566063dSJacob Faibussowitsch   PetscCall(DMSetMatType(dm, MATDENSE));
1135*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1136fe1899a2SJed Brown }
1137fe1899a2SJed Brown 
1138fe1899a2SJed Brown /*@
1139fe1899a2SJed Brown     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
1140fe1899a2SJed Brown 
1141d083f849SBarry Smith     Collective
1142fe1899a2SJed Brown 
1143fe1899a2SJed Brown     Input Parameter:
1144fe1899a2SJed Brown .   comm - the processors that will share the global vector
1145fe1899a2SJed Brown 
1146fe1899a2SJed Brown     Output Parameters:
1147fe1899a2SJed Brown .   shell - the shell DM
1148fe1899a2SJed Brown 
1149fe1899a2SJed Brown     Level: advanced
1150fe1899a2SJed Brown 
1151db781477SPatrick Sanan .seealso `DMDestroy()`, `DMCreateGlobalVector()`, `DMCreateLocalVector()`, `DMShellSetContext()`, `DMShellGetContext()`
1152fe1899a2SJed Brown @*/
1153d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellCreate(MPI_Comm comm, DM *dm)
1154d71ae5a4SJacob Faibussowitsch {
1155fe1899a2SJed Brown   PetscFunctionBegin;
1156fe1899a2SJed Brown   PetscValidPointer(dm, 2);
11579566063dSJacob Faibussowitsch   PetscCall(DMCreate(comm, dm));
11589566063dSJacob Faibussowitsch   PetscCall(DMSetType(*dm, DMSHELL));
11599566063dSJacob Faibussowitsch   PetscCall(DMSetUp(*dm));
1160*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1161fe1899a2SJed Brown }
1162