xref: /petsc/src/dm/impls/shell/dmshell.c (revision 4e8208cbcbc709572b8abe32f33c78b69c819375)
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;
12*2a8381b2SBarry Smith   PetscCtx           ctx;
13e6aa7a3bSBarry Smith   PetscCtxDestroyFn *destroyctx;
14fe1899a2SJed Brown } DM_Shell;
15fe1899a2SJed Brown 
167a108d1dSBarry Smith /*@
1720f4b53cSBarry Smith   DMGlobalToLocalBeginDefaultShell - Uses the GlobalToLocal `VecScatter` context set by the user to begin a global to local scatter
1820f4b53cSBarry Smith 
198d359177SBarry Smith   Collective
208d359177SBarry Smith 
214165533cSJose E. Roman   Input Parameters:
2220f4b53cSBarry Smith + dm   - `DMSHELL`
238d359177SBarry Smith . g    - global vector
2420f4b53cSBarry Smith . mode - `InsertMode`
258d359177SBarry Smith - l    - local vector
268d359177SBarry Smith 
277a108d1dSBarry Smith   Level: advanced
288d359177SBarry Smith 
2920f4b53cSBarry Smith   Note:
3020f4b53cSBarry Smith   This is not normally called directly by user code, generally user code calls `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()`. If the user provides their own custom routines to `DMShellSetLocalToGlobal()` then those routines might have reason to call this function.
317a108d1dSBarry Smith 
3220f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMGlobalToLocalEndDefaultShell()`
338d359177SBarry Smith @*/
DMGlobalToLocalBeginDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)34d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalBeginDefaultShell(DM dm, Vec g, InsertMode mode, Vec l)
35d71ae5a4SJacob Faibussowitsch {
368d359177SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
378d359177SBarry Smith 
388d359177SBarry Smith   PetscFunctionBegin;
397a8be351SBarry Smith   PetscCheck(shell->gtol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
409566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->gtol, g, l, mode, SCATTER_FORWARD));
413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
428d359177SBarry Smith }
438d359177SBarry Smith 
447a108d1dSBarry Smith /*@
4520f4b53cSBarry Smith   DMGlobalToLocalEndDefaultShell - Uses the GlobalToLocal `VecScatter` context set by the user to end a global to local scatter
468d359177SBarry Smith   Collective
478d359177SBarry Smith 
484165533cSJose E. Roman   Input Parameters:
4920f4b53cSBarry Smith + dm   - `DMSHELL`
508d359177SBarry Smith . g    - global vector
5120f4b53cSBarry Smith . mode - `InsertMode`
528d359177SBarry Smith - l    - local vector
538d359177SBarry Smith 
547a108d1dSBarry Smith   Level: advanced
558d359177SBarry Smith 
5620f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMGlobalToLocalBeginDefaultShell()`
578d359177SBarry Smith @*/
DMGlobalToLocalEndDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)58d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalEndDefaultShell(DM dm, Vec g, InsertMode mode, Vec l)
59d71ae5a4SJacob Faibussowitsch {
608d359177SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
618d359177SBarry Smith 
628d359177SBarry Smith   PetscFunctionBegin;
637a8be351SBarry Smith   PetscCheck(shell->gtol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
649566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->gtol, g, l, mode, SCATTER_FORWARD));
653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
668d359177SBarry Smith }
678d359177SBarry Smith 
68c5076b69SRichard Tran Mills /*@
6920f4b53cSBarry Smith   DMLocalToGlobalBeginDefaultShell - Uses the LocalToGlobal `VecScatter` context set by the user to begin a local to global scatter
70c5076b69SRichard Tran Mills   Collective
71c5076b69SRichard Tran Mills 
724165533cSJose E. Roman   Input Parameters:
7320f4b53cSBarry Smith + dm   - `DMSHELL`
74c5076b69SRichard Tran Mills . l    - local vector
7520f4b53cSBarry Smith . mode - `InsertMode`
76c5076b69SRichard Tran Mills - g    - global vector
77c5076b69SRichard Tran Mills 
78c5076b69SRichard Tran Mills   Level: advanced
79c5076b69SRichard Tran Mills 
8020f4b53cSBarry Smith   Note:
8120f4b53cSBarry Smith   This is not normally called directly by user code, generally user code calls `DMLocalToGlobalBegin()` and `DMLocalToGlobalEnd()`. If the user provides their own custom routines to `DMShellSetLocalToGlobal()` then those routines might have reason to call this function.
82c5076b69SRichard Tran Mills 
8320f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMLocalToGlobalEndDefaultShell()`
84c5076b69SRichard Tran Mills @*/
DMLocalToGlobalBeginDefaultShell(DM dm,Vec l,InsertMode mode,Vec g)85d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalBeginDefaultShell(DM dm, Vec l, InsertMode mode, Vec g)
86d71ae5a4SJacob Faibussowitsch {
87c5076b69SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
88c5076b69SRichard Tran Mills 
89c5076b69SRichard Tran Mills   PetscFunctionBegin;
907a8be351SBarry Smith   PetscCheck(shell->ltog, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
919566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->ltog, l, g, mode, SCATTER_FORWARD));
923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
93c5076b69SRichard Tran Mills }
94c5076b69SRichard Tran Mills 
95c5076b69SRichard Tran Mills /*@
9620f4b53cSBarry Smith   DMLocalToGlobalEndDefaultShell - Uses the LocalToGlobal `VecScatter` context set by the user to end a local to global scatter
97c5076b69SRichard Tran Mills   Collective
98c5076b69SRichard Tran Mills 
994165533cSJose E. Roman   Input Parameters:
10020f4b53cSBarry Smith + dm   - `DMSHELL`
101c5076b69SRichard Tran Mills . l    - local vector
10220f4b53cSBarry Smith . mode - `InsertMode`
103c5076b69SRichard Tran Mills - g    - global vector
104c5076b69SRichard Tran Mills 
105c5076b69SRichard Tran Mills   Level: advanced
106c5076b69SRichard Tran Mills 
10720f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMLocalToGlobalBeginDefaultShell()`
108c5076b69SRichard Tran Mills @*/
DMLocalToGlobalEndDefaultShell(DM dm,Vec l,InsertMode mode,Vec g)109d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalEndDefaultShell(DM dm, Vec l, InsertMode mode, Vec g)
110d71ae5a4SJacob Faibussowitsch {
111c5076b69SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
112c5076b69SRichard Tran Mills 
113c5076b69SRichard Tran Mills   PetscFunctionBegin;
1147a8be351SBarry Smith   PetscCheck(shell->ltog, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
1159566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->ltog, l, g, mode, SCATTER_FORWARD));
1163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
117c5076b69SRichard Tran Mills }
118c5076b69SRichard Tran Mills 
119f3db62a7SRichard Tran Mills /*@
12020f4b53cSBarry Smith   DMLocalToLocalBeginDefaultShell - Uses the LocalToLocal `VecScatter` context set by the user to begin a local to local scatter
121f3db62a7SRichard Tran Mills   Collective
122f3db62a7SRichard Tran Mills 
1234165533cSJose E. Roman   Input Parameters:
12420f4b53cSBarry Smith + dm   - `DMSHELL`
125f3db62a7SRichard Tran Mills . g    - the original local vector
12620f4b53cSBarry Smith - mode - `InsertMode`
127f3db62a7SRichard Tran Mills 
128f3db62a7SRichard Tran Mills   Output Parameter:
129f3db62a7SRichard Tran Mills . l - the local vector with correct ghost values
130f3db62a7SRichard Tran Mills 
131f3db62a7SRichard Tran Mills   Level: advanced
132f3db62a7SRichard Tran Mills 
13320f4b53cSBarry Smith   Note:
13420f4b53cSBarry Smith   This is not normally called directly by user code, generally user code calls `DMLocalToLocalBegin()` and `DMLocalToLocalEnd()`. If the user provides their own custom routines to `DMShellSetLocalToLocal()` then those routines might have reason to call this function.
135f3db62a7SRichard Tran Mills 
13620f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMLocalToLocalEndDefaultShell()`
137f3db62a7SRichard Tran Mills @*/
DMLocalToLocalBeginDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)138d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalBeginDefaultShell(DM dm, Vec g, InsertMode mode, Vec l)
139d71ae5a4SJacob Faibussowitsch {
140f3db62a7SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
141f3db62a7SRichard Tran Mills 
142f3db62a7SRichard Tran Mills   PetscFunctionBegin;
1437a8be351SBarry Smith   PetscCheck(shell->ltol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToLocalVecScatter()");
1449566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->ltol, g, l, mode, SCATTER_FORWARD));
1453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
146f3db62a7SRichard Tran Mills }
147f3db62a7SRichard Tran Mills 
148f3db62a7SRichard Tran Mills /*@
14920f4b53cSBarry Smith   DMLocalToLocalEndDefaultShell - Uses the LocalToLocal `VecScatter` context set by the user to end a local to local scatter
150f3db62a7SRichard Tran Mills   Collective
151f3db62a7SRichard Tran Mills 
1524165533cSJose E. Roman   Input Parameters:
15320f4b53cSBarry Smith + dm   - `DMSHELL`
154f3db62a7SRichard Tran Mills . g    - the original local vector
15520f4b53cSBarry Smith - mode - `InsertMode`
156f3db62a7SRichard Tran Mills 
157f3db62a7SRichard Tran Mills   Output Parameter:
158f3db62a7SRichard Tran Mills . l - the local vector with correct ghost values
159f3db62a7SRichard Tran Mills 
160f3db62a7SRichard Tran Mills   Level: advanced
161f3db62a7SRichard Tran Mills 
16220f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMLocalToLocalBeginDefaultShell()`
163f3db62a7SRichard Tran Mills @*/
DMLocalToLocalEndDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)164d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalEndDefaultShell(DM dm, Vec g, InsertMode mode, Vec l)
165d71ae5a4SJacob Faibussowitsch {
166f3db62a7SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
167f3db62a7SRichard Tran Mills 
168f3db62a7SRichard Tran Mills   PetscFunctionBegin;
1697a8be351SBarry Smith   PetscCheck(shell->ltol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
1709566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->ltol, g, l, mode, SCATTER_FORWARD));
1713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
172f3db62a7SRichard Tran Mills }
173c5076b69SRichard Tran Mills 
DMCreateMatrix_Shell(DM dm,Mat * J)174d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCreateMatrix_Shell(DM dm, Mat *J)
175d71ae5a4SJacob Faibussowitsch {
176fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
177fe1899a2SJed Brown   Mat       A;
178fe1899a2SJed Brown 
179fe1899a2SJed Brown   PetscFunctionBegin;
180fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1814f572ea9SToby Isaac   PetscAssertPointer(J, 2);
1827bde9f88SJed Brown   if (!shell->A) {
1837bde9f88SJed Brown     PetscInt m, M;
184966bd95aSPierre Jolivet 
185966bd95aSPierre Jolivet     PetscCheck(shell->Xglobal, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector");
1869566063dSJacob Faibussowitsch     PetscCall(PetscInfo(dm, "Naively creating matrix using global vector distribution without preallocation\n"));
1879566063dSJacob Faibussowitsch     PetscCall(VecGetSize(shell->Xglobal, &M));
1889566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(shell->Xglobal, &m));
1899566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)dm), &shell->A));
1909566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(shell->A, m, m, M, M));
1919566063dSJacob Faibussowitsch     PetscCall(MatSetType(shell->A, dm->mattype));
1929566063dSJacob Faibussowitsch     PetscCall(MatSetUp(shell->A));
1937bde9f88SJed Brown   }
194fe1899a2SJed Brown   A = shell->A;
1959566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(A, MAT_SHARE_NONZERO_PATTERN, J));
1969566063dSJacob Faibussowitsch   PetscCall(MatSetDM(*J, dm));
1973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
198fe1899a2SJed Brown }
199fe1899a2SJed Brown 
DMCreateGlobalVector_Shell(DM dm,Vec * gvec)20066976f2fSJacob Faibussowitsch static PetscErrorCode DMCreateGlobalVector_Shell(DM dm, Vec *gvec)
201d71ae5a4SJacob Faibussowitsch {
202fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
203fe1899a2SJed Brown   Vec       X;
204fe1899a2SJed Brown 
205fe1899a2SJed Brown   PetscFunctionBegin;
206fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2074f572ea9SToby Isaac   PetscAssertPointer(gvec, 2);
208ea78f98cSLisandro Dalcin   *gvec = NULL;
209fe1899a2SJed Brown   X     = shell->Xglobal;
2107a8be351SBarry Smith   PetscCheck(X, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
21106f803f6SStefano Zampini   /* Need to create a copy in order to attach the DM to the vector */
2129566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(X, gvec));
2139566063dSJacob Faibussowitsch   PetscCall(VecZeroEntries(*gvec));
2149566063dSJacob Faibussowitsch   PetscCall(VecSetDM(*gvec, dm));
2153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
216fe1899a2SJed Brown }
217fe1899a2SJed Brown 
DMCreateLocalVector_Shell(DM dm,Vec * gvec)21866976f2fSJacob Faibussowitsch static PetscErrorCode DMCreateLocalVector_Shell(DM dm, Vec *gvec)
219d71ae5a4SJacob Faibussowitsch {
220dc43b69eSJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
221dc43b69eSJed Brown   Vec       X;
222dc43b69eSJed Brown 
223dc43b69eSJed Brown   PetscFunctionBegin;
224dc43b69eSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2254f572ea9SToby Isaac   PetscAssertPointer(gvec, 2);
226ea78f98cSLisandro Dalcin   *gvec = NULL;
227dc43b69eSJed Brown   X     = shell->Xlocal;
2287a8be351SBarry Smith   PetscCheck(X, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()");
22906f803f6SStefano Zampini   /* Need to create a copy in order to attach the DM to the vector */
2309566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(X, gvec));
2319566063dSJacob Faibussowitsch   PetscCall(VecZeroEntries(*gvec));
2329566063dSJacob Faibussowitsch   PetscCall(VecSetDM(*gvec, dm));
2333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
234dc43b69eSJed Brown }
235dc43b69eSJed Brown 
23660225df5SJacob Faibussowitsch /*@C
23709904cd0SBarry Smith   DMShellSetDestroyContext - set a function that destroys the context provided with `DMShellSetContext()`
23809904cd0SBarry Smith 
23909904cd0SBarry Smith   Collective
24009904cd0SBarry Smith 
24109904cd0SBarry Smith   Input Parameters:
2422fe279fdSBarry Smith + dm         - the `DM` to attach the `destroyctx()` function to
2432fe279fdSBarry Smith - destroyctx - the function that destroys the context
24409904cd0SBarry Smith 
24509904cd0SBarry Smith   Level: advanced
24609904cd0SBarry Smith 
24720f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetContext()`, `DMShellGetContext()`
24809904cd0SBarry Smith @*/
DMShellSetDestroyContext(DM dm,PetscCtxDestroyFn * destroyctx)249e6aa7a3bSBarry Smith PetscErrorCode DMShellSetDestroyContext(DM dm, PetscCtxDestroyFn *destroyctx)
250d71ae5a4SJacob Faibussowitsch {
25109904cd0SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
25209904cd0SBarry Smith   PetscBool isshell;
25309904cd0SBarry Smith 
25409904cd0SBarry Smith   PetscFunctionBegin;
25509904cd0SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
25609904cd0SBarry Smith   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
2573ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
25809904cd0SBarry Smith   shell->destroyctx = destroyctx;
2593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
26009904cd0SBarry Smith }
26109904cd0SBarry Smith 
26209904cd0SBarry Smith /*@
26320f4b53cSBarry Smith   DMShellSetContext - set some data to be usable by this `DMSHELL`
264fef3a512SBarry Smith 
265fef3a512SBarry Smith   Collective
266fef3a512SBarry Smith 
2674165533cSJose E. Roman   Input Parameters:
26820f4b53cSBarry Smith + dm  - `DMSHELL`
269fef3a512SBarry Smith - ctx - the context
270fef3a512SBarry Smith 
271fef3a512SBarry Smith   Level: advanced
272fef3a512SBarry Smith 
27320f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateMatrix()`, `DMShellGetContext()`
274fef3a512SBarry Smith @*/
DMShellSetContext(DM dm,PetscCtx ctx)275*2a8381b2SBarry Smith PetscErrorCode DMShellSetContext(DM dm, PetscCtx ctx)
276d71ae5a4SJacob Faibussowitsch {
277fef3a512SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
278fef3a512SBarry Smith   PetscBool isshell;
279fef3a512SBarry Smith 
280fef3a512SBarry Smith   PetscFunctionBegin;
281fef3a512SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2829566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
2833ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
284fef3a512SBarry Smith   shell->ctx = ctx;
2853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
286fef3a512SBarry Smith }
287fef3a512SBarry Smith 
288fef3a512SBarry Smith /*@
28920f4b53cSBarry Smith   DMShellGetContext - Returns the user-provided context associated to the `DMSHELL`
290fef3a512SBarry Smith 
291fef3a512SBarry Smith   Collective
292fef3a512SBarry Smith 
2934165533cSJose E. Roman   Input Parameter:
29420f4b53cSBarry Smith . dm - `DMSHELL`
295fef3a512SBarry Smith 
2964165533cSJose E. Roman   Output Parameter:
297fef3a512SBarry Smith . ctx - the context
298fef3a512SBarry Smith 
299fef3a512SBarry Smith   Level: advanced
300fef3a512SBarry Smith 
301*2a8381b2SBarry Smith   Fortran Notes:
302*2a8381b2SBarry Smith   This only works when the context is a Fortran derived type or a `PetscObject`. Declare `ctx` with
303*2a8381b2SBarry Smith .vb
304*2a8381b2SBarry Smith   type(tUsertype), pointer :: ctx
305*2a8381b2SBarry Smith .ve
306*2a8381b2SBarry Smith 
30720f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateMatrix()`, `DMShellSetContext()`
308fef3a512SBarry Smith @*/
DMShellGetContext(DM dm,PetscCtxRt ctx)309*2a8381b2SBarry Smith PetscErrorCode DMShellGetContext(DM dm, PetscCtxRt ctx)
310d71ae5a4SJacob Faibussowitsch {
311fef3a512SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
312fef3a512SBarry Smith   PetscBool isshell;
313fef3a512SBarry Smith 
314fef3a512SBarry Smith   PetscFunctionBegin;
315fef3a512SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3169566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
3177a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
3183ec1f749SStefano Zampini   *(void **)ctx = shell->ctx;
3193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
320fef3a512SBarry Smith }
321fef3a512SBarry Smith 
322fe1899a2SJed Brown /*@
32320f4b53cSBarry Smith   DMShellSetMatrix - sets a template matrix associated with the `DMSHELL`
324fe1899a2SJed Brown 
325fe1899a2SJed Brown   Collective
326fe1899a2SJed Brown 
3274165533cSJose E. Roman   Input Parameters:
32820f4b53cSBarry Smith + dm - `DMSHELL`
329fe1899a2SJed Brown - J  - template matrix
330fe1899a2SJed Brown 
331fe1899a2SJed Brown   Level: advanced
332fe1899a2SJed Brown 
33360225df5SJacob Faibussowitsch   Developer Notes:
33420f4b53cSBarry Smith   To avoid circular references, if `J` is already associated to the same `DM`, then `MatDuplicate`(`SHARE_NONZERO_PATTERN`) is called, followed by removing the `DM` reference from the private template.
33506f803f6SStefano Zampini 
33620f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateMatrix()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
337fe1899a2SJed Brown @*/
DMShellSetMatrix(DM dm,Mat J)338d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetMatrix(DM dm, Mat J)
339d71ae5a4SJacob Faibussowitsch {
340fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
3418c87107bSJed Brown   PetscBool isshell;
34206f803f6SStefano Zampini   DM        mdm;
343fe1899a2SJed Brown 
344fe1899a2SJed Brown   PetscFunctionBegin;
3458c87107bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3468c87107bSJed Brown   PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
3479566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
3483ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
3493ba16761SJacob Faibussowitsch   if (J == shell->A) PetscFunctionReturn(PETSC_SUCCESS);
3509566063dSJacob Faibussowitsch   PetscCall(MatGetDM(J, &mdm));
3519566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)J));
3529566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&shell->A));
35306f803f6SStefano Zampini   if (mdm == dm) {
3549566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(J, MAT_SHARE_NONZERO_PATTERN, &shell->A));
3559566063dSJacob Faibussowitsch     PetscCall(MatSetDM(shell->A, NULL));
35606f803f6SStefano Zampini   } else shell->A = J;
3573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
358fe1899a2SJed Brown }
359fe1899a2SJed Brown 
360fe1899a2SJed Brown /*@C
36120f4b53cSBarry Smith   DMShellSetCreateMatrix - sets the routine to create a matrix associated with the `DMSHELL`
362fe1899a2SJed Brown 
36320f4b53cSBarry Smith   Logically Collective
364fe1899a2SJed Brown 
3654165533cSJose E. Roman   Input Parameters:
36620f4b53cSBarry Smith + dm   - the `DMSHELL`
367fe1899a2SJed Brown - func - the function to create a matrix
368fe1899a2SJed Brown 
369fe1899a2SJed Brown   Level: advanced
370fe1899a2SJed Brown 
37120f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateMatrix()`, `DMShellSetMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
372fe1899a2SJed Brown @*/
DMShellSetCreateMatrix(DM dm,PetscErrorCode (* func)(DM,Mat *))373d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateMatrix(DM dm, PetscErrorCode (*func)(DM, Mat *))
374d71ae5a4SJacob Faibussowitsch {
375fe1899a2SJed Brown   PetscFunctionBegin;
376fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
377fe1899a2SJed Brown   dm->ops->creatematrix = func;
3783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
379fe1899a2SJed Brown }
380fe1899a2SJed Brown 
381fe1899a2SJed Brown /*@
38220f4b53cSBarry Smith   DMShellSetGlobalVector - sets a template global vector associated with the `DMSHELL`
383fe1899a2SJed Brown 
38420f4b53cSBarry Smith   Logically Collective
385fe1899a2SJed Brown 
3864165533cSJose E. Roman   Input Parameters:
38720f4b53cSBarry Smith + dm - `DMSHELL`
388fe1899a2SJed Brown - X  - template vector
389fe1899a2SJed Brown 
390fe1899a2SJed Brown   Level: advanced
391fe1899a2SJed Brown 
39220f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateGlobalVector()`, `DMShellSetMatrix()`, `DMShellSetCreateGlobalVector()`
393fe1899a2SJed Brown @*/
DMShellSetGlobalVector(DM dm,Vec X)394d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetGlobalVector(DM dm, Vec X)
395d71ae5a4SJacob Faibussowitsch {
396fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
3978c87107bSJed Brown   PetscBool isshell;
398cca7ec1eSBarry Smith   DM        vdm;
399fe1899a2SJed Brown 
400fe1899a2SJed Brown   PetscFunctionBegin;
4018c87107bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4028c87107bSJed Brown   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
4039566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
4043ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
4059566063dSJacob Faibussowitsch   PetscCall(VecGetDM(X, &vdm));
406cca7ec1eSBarry Smith   /*
407cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
408cca7ec1eSBarry 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
409cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
410cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
411cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
412cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
413cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
414cca7ec1eSBarry Smith       for pointing out the problem.
415cca7ec1eSBarry Smith    */
4163ba16761SJacob Faibussowitsch   if (vdm == dm) PetscFunctionReturn(PETSC_SUCCESS);
4179566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)X));
4189566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xglobal));
419fe1899a2SJed Brown   shell->Xglobal = X;
420245d7360SStefano Zampini   PetscCall(DMClearGlobalVectors(dm));
421245d7360SStefano Zampini   PetscCall(DMClearNamedGlobalVectors(dm));
4223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
423fe1899a2SJed Brown }
424fe1899a2SJed Brown 
42504d741b1SMatthew G. Knepley /*@
42620f4b53cSBarry Smith   DMShellGetGlobalVector - Returns the template global vector associated with the `DMSHELL`, or `NULL` if it was not set
42704d741b1SMatthew G. Knepley 
42820f4b53cSBarry Smith   Not Collective
42904d741b1SMatthew G. Knepley 
4304165533cSJose E. Roman   Input Parameters:
43120f4b53cSBarry Smith + dm - `DMSHELL`
43204d741b1SMatthew G. Knepley - X  - template vector
43304d741b1SMatthew G. Knepley 
43404d741b1SMatthew G. Knepley   Level: advanced
43504d741b1SMatthew G. Knepley 
43620f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetGlobalVector()`, `DMShellSetCreateGlobalVector()`, `DMCreateGlobalVector()`
43704d741b1SMatthew G. Knepley @*/
DMShellGetGlobalVector(DM dm,Vec * X)438d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetGlobalVector(DM dm, Vec *X)
439d71ae5a4SJacob Faibussowitsch {
44004d741b1SMatthew G. Knepley   DM_Shell *shell = (DM_Shell *)dm->data;
44104d741b1SMatthew G. Knepley   PetscBool isshell;
44204d741b1SMatthew G. Knepley 
44304d741b1SMatthew G. Knepley   PetscFunctionBegin;
44404d741b1SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4454f572ea9SToby Isaac   PetscAssertPointer(X, 2);
4469566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
4473ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
44804d741b1SMatthew G. Knepley   *X = shell->Xglobal;
4493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
45004d741b1SMatthew G. Knepley }
45104d741b1SMatthew G. Knepley 
452fe1899a2SJed Brown /*@C
45320f4b53cSBarry Smith   DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the `DMSHELL`
454fe1899a2SJed Brown 
455fe1899a2SJed Brown   Logically Collective
456fe1899a2SJed Brown 
4574165533cSJose E. Roman   Input Parameters:
45820f4b53cSBarry Smith + dm   - the `DMSHELL`
459fe1899a2SJed Brown - func - the creation routine
460fe1899a2SJed Brown 
461fe1899a2SJed Brown   Level: advanced
462fe1899a2SJed Brown 
46320f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetGlobalVector()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
464fe1899a2SJed Brown @*/
DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (* func)(DM,Vec *))465d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateGlobalVector(DM dm, PetscErrorCode (*func)(DM, Vec *))
466d71ae5a4SJacob Faibussowitsch {
467fe1899a2SJed Brown   PetscFunctionBegin;
468fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
469fe1899a2SJed Brown   dm->ops->createglobalvector = func;
4703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
471fe1899a2SJed Brown }
472fe1899a2SJed Brown 
473dc43b69eSJed Brown /*@
47420f4b53cSBarry Smith   DMShellSetLocalVector - sets a template local vector associated with the `DMSHELL`
475dc43b69eSJed Brown 
47620f4b53cSBarry Smith   Logically Collective
477dc43b69eSJed Brown 
4784165533cSJose E. Roman   Input Parameters:
47920f4b53cSBarry Smith + dm - `DMSHELL`
480dc43b69eSJed Brown - X  - template vector
481dc43b69eSJed Brown 
482dc43b69eSJed Brown   Level: advanced
483dc43b69eSJed Brown 
48420f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateLocalVector()`, `DMShellSetMatrix()`, `DMShellSetCreateLocalVector()`
485dc43b69eSJed Brown @*/
DMShellSetLocalVector(DM dm,Vec X)486d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalVector(DM dm, Vec X)
487d71ae5a4SJacob Faibussowitsch {
488dc43b69eSJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
489dc43b69eSJed Brown   PetscBool isshell;
490cca7ec1eSBarry Smith   DM        vdm;
491dc43b69eSJed Brown 
492dc43b69eSJed Brown   PetscFunctionBegin;
493dc43b69eSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
494dc43b69eSJed Brown   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
4959566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
4963ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
4979566063dSJacob Faibussowitsch   PetscCall(VecGetDM(X, &vdm));
498cca7ec1eSBarry Smith   /*
499cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
500cca7ec1eSBarry 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
501cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
502cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
503cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
504cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
505cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
506cca7ec1eSBarry Smith       for pointing out the problem.
507cca7ec1eSBarry Smith    */
5083ba16761SJacob Faibussowitsch   if (vdm == dm) PetscFunctionReturn(PETSC_SUCCESS);
5099566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)X));
5109566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xlocal));
511dc43b69eSJed Brown   shell->Xlocal = X;
512245d7360SStefano Zampini   PetscCall(DMClearLocalVectors(dm));
513245d7360SStefano Zampini   PetscCall(DMClearNamedLocalVectors(dm));
5143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
515dc43b69eSJed Brown }
516dc43b69eSJed Brown 
517dc43b69eSJed Brown /*@C
51820f4b53cSBarry Smith   DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the `DMSHELL`
519dc43b69eSJed Brown 
520dc43b69eSJed Brown   Logically Collective
521dc43b69eSJed Brown 
5224165533cSJose E. Roman   Input Parameters:
52320f4b53cSBarry Smith + dm   - the `DMSHELL`
524dc43b69eSJed Brown - func - the creation routine
525dc43b69eSJed Brown 
526dc43b69eSJed Brown   Level: advanced
527dc43b69eSJed Brown 
52820f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetLocalVector()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
529dc43b69eSJed Brown @*/
DMShellSetCreateLocalVector(DM dm,PetscErrorCode (* func)(DM,Vec *))530d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateLocalVector(DM dm, PetscErrorCode (*func)(DM, Vec *))
531d71ae5a4SJacob Faibussowitsch {
532dc43b69eSJed Brown   PetscFunctionBegin;
533dc43b69eSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
534dc43b69eSJed Brown   dm->ops->createlocalvector = func;
5353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
536dc43b69eSJed Brown }
537dc43b69eSJed Brown 
5388339e6d0SRichard Tran Mills /*@C
5398339e6d0SRichard Tran Mills   DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter
5408339e6d0SRichard Tran Mills 
5418f14a041SBarry Smith   Logically Collective
5428339e6d0SRichard Tran Mills 
543a4e35b19SJacob Faibussowitsch   Input Parameters:
54420f4b53cSBarry Smith + dm    - the `DMSHELL`
5458339e6d0SRichard Tran Mills . begin - the routine that begins the global to local scatter
5468339e6d0SRichard Tran Mills - end   - the routine that ends the global to local scatter
5478339e6d0SRichard Tran Mills 
5488339e6d0SRichard Tran Mills   Level: advanced
5498339e6d0SRichard Tran Mills 
55020f4b53cSBarry Smith   Note:
55120f4b53cSBarry Smith   If these functions are not provided but `DMShellSetGlobalToLocalVecScatter()` is called then
55215229ffcSPierre Jolivet   `DMGlobalToLocalBeginDefaultShell()`/`DMGlobalToLocalEndDefaultShell()` are used to perform the transfers
55320f4b53cSBarry Smith 
55420f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetLocalToGlobal()`, `DMGlobalToLocalBeginDefaultShell()`, `DMGlobalToLocalEndDefaultShell()`
5558339e6d0SRichard Tran Mills @*/
DMShellSetGlobalToLocal(DM dm,PetscErrorCode (* begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (* end)(DM,Vec,InsertMode,Vec))556d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetGlobalToLocal(DM dm, PetscErrorCode (*begin)(DM, Vec, InsertMode, Vec), PetscErrorCode (*end)(DM, Vec, InsertMode, Vec))
557d71ae5a4SJacob Faibussowitsch {
5588339e6d0SRichard Tran Mills   PetscFunctionBegin;
5592d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5608339e6d0SRichard Tran Mills   dm->ops->globaltolocalbegin = begin;
5618339e6d0SRichard Tran Mills   dm->ops->globaltolocalend   = end;
5623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5638339e6d0SRichard Tran Mills }
5648339e6d0SRichard Tran Mills 
5658339e6d0SRichard Tran Mills /*@C
5668339e6d0SRichard Tran Mills   DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter
5678339e6d0SRichard Tran Mills 
5688f14a041SBarry Smith   Logically Collective
5698339e6d0SRichard Tran Mills 
570a4e35b19SJacob Faibussowitsch   Input Parameters:
57120f4b53cSBarry Smith + dm    - the `DMSHELL`
5728339e6d0SRichard Tran Mills . begin - the routine that begins the local to global scatter
5738339e6d0SRichard Tran Mills - end   - the routine that ends the local to global scatter
5748339e6d0SRichard Tran Mills 
5758339e6d0SRichard Tran Mills   Level: advanced
5768339e6d0SRichard Tran Mills 
57720f4b53cSBarry Smith   Note:
57820f4b53cSBarry Smith   If these functions are not provided but `DMShellSetLocalToGlobalVecScatter()` is called then
57915229ffcSPierre Jolivet   `DMLocalToGlobalBeginDefaultShell()`/`DMLocalToGlobalEndDefaultShell()` are used to perform the transfers
58020f4b53cSBarry Smith 
58120f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetGlobalToLocal()`
5828339e6d0SRichard Tran Mills @*/
DMShellSetLocalToGlobal(DM dm,PetscErrorCode (* begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (* end)(DM,Vec,InsertMode,Vec))583d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalToGlobal(DM dm, PetscErrorCode (*begin)(DM, Vec, InsertMode, Vec), PetscErrorCode (*end)(DM, Vec, InsertMode, Vec))
584d71ae5a4SJacob Faibussowitsch {
5858339e6d0SRichard Tran Mills   PetscFunctionBegin;
5862d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5878339e6d0SRichard Tran Mills   dm->ops->localtoglobalbegin = begin;
5888339e6d0SRichard Tran Mills   dm->ops->localtoglobalend   = end;
5893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5908339e6d0SRichard Tran Mills }
5918339e6d0SRichard Tran Mills 
592f3db62a7SRichard Tran Mills /*@C
593f3db62a7SRichard Tran Mills   DMShellSetLocalToLocal - Sets the routines used to perform a local to local scatter
594f3db62a7SRichard Tran Mills 
5958f14a041SBarry Smith   Logically Collective
596f3db62a7SRichard Tran Mills 
597a4e35b19SJacob Faibussowitsch   Input Parameters:
59820f4b53cSBarry Smith + dm    - the `DMSHELL`
599f3db62a7SRichard Tran Mills . begin - the routine that begins the local to local scatter
600f3db62a7SRichard Tran Mills - end   - the routine that ends the local to local scatter
601f3db62a7SRichard Tran Mills 
602f3db62a7SRichard Tran Mills   Level: advanced
603f3db62a7SRichard Tran Mills 
60420f4b53cSBarry Smith   Note:
60520f4b53cSBarry Smith   If these functions are not provided but `DMShellSetLocalToLocalVecScatter()` is called then
60615229ffcSPierre Jolivet   `DMLocalToLocalBeginDefaultShell()`/`DMLocalToLocalEndDefaultShell()` are used to perform the transfers
60720f4b53cSBarry Smith 
60820f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetGlobalToLocal()`, `DMLocalToLocalBeginDefaultShell()`, `DMLocalToLocalEndDefaultShell()`
609f3db62a7SRichard Tran Mills @*/
DMShellSetLocalToLocal(DM dm,PetscErrorCode (* begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (* end)(DM,Vec,InsertMode,Vec))610d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalToLocal(DM dm, PetscErrorCode (*begin)(DM, Vec, InsertMode, Vec), PetscErrorCode (*end)(DM, Vec, InsertMode, Vec))
611d71ae5a4SJacob Faibussowitsch {
612f3db62a7SRichard Tran Mills   PetscFunctionBegin;
6132d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
614f3db62a7SRichard Tran Mills   dm->ops->localtolocalbegin = begin;
615f3db62a7SRichard Tran Mills   dm->ops->localtolocalend   = end;
6163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
617f3db62a7SRichard Tran Mills }
618f3db62a7SRichard Tran Mills 
61981634712SRichard Tran Mills /*@
62020f4b53cSBarry Smith   DMShellSetGlobalToLocalVecScatter - Sets a `VecScatter` context for global to local communication
62181634712SRichard Tran Mills 
6228f14a041SBarry Smith   Logically Collective
62381634712SRichard Tran Mills 
624a4e35b19SJacob Faibussowitsch   Input Parameters:
62520f4b53cSBarry Smith + dm   - the `DMSHELL`
62620f4b53cSBarry Smith - gtol - the global to local `VecScatter` context
62781634712SRichard Tran Mills 
62881634712SRichard Tran Mills   Level: advanced
62981634712SRichard Tran Mills 
63020f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetGlobalToLocal()`, `DMGlobalToLocalBeginDefaultShell()`, `DMGlobalToLocalEndDefaultShell()`
63181634712SRichard Tran Mills @*/
DMShellSetGlobalToLocalVecScatter(DM dm,VecScatter gtol)632d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter gtol)
633d71ae5a4SJacob Faibussowitsch {
63481634712SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
63581634712SRichard Tran Mills 
636b300e4a8SRichard Tran Mills   PetscFunctionBegin;
6372d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
63897929ea7SJunchao Zhang   PetscValidHeaderSpecific(gtol, PETSCSF_CLASSID, 2);
6399566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)gtol));
6409566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->gtol));
64181634712SRichard Tran Mills   shell->gtol = gtol;
6423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
64381634712SRichard Tran Mills }
64481634712SRichard Tran Mills 
645988ea7d6SRichard Tran Mills /*@
64620f4b53cSBarry Smith   DMShellSetLocalToGlobalVecScatter - Sets a` VecScatter` context for local to global communication
647988ea7d6SRichard Tran Mills 
6488f14a041SBarry Smith   Logically Collective
649988ea7d6SRichard Tran Mills 
650a4e35b19SJacob Faibussowitsch   Input Parameters:
65120f4b53cSBarry Smith + dm   - the `DMSHELL`
65220f4b53cSBarry Smith - ltog - the local to global `VecScatter` context
653988ea7d6SRichard Tran Mills 
654988ea7d6SRichard Tran Mills   Level: advanced
655988ea7d6SRichard Tran Mills 
65620f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetLocalToGlobal()`, `DMLocalToGlobalBeginDefaultShell()`, `DMLocalToGlobalEndDefaultShell()`
657988ea7d6SRichard Tran Mills @*/
DMShellSetLocalToGlobalVecScatter(DM dm,VecScatter ltog)658d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM dm, VecScatter ltog)
659d71ae5a4SJacob Faibussowitsch {
660988ea7d6SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
661988ea7d6SRichard Tran Mills 
662988ea7d6SRichard Tran Mills   PetscFunctionBegin;
6632d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
66497929ea7SJunchao Zhang   PetscValidHeaderSpecific(ltog, PETSCSF_CLASSID, 2);
6659566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)ltog));
6669566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltog));
667988ea7d6SRichard Tran Mills   shell->ltog = ltog;
6683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
669988ea7d6SRichard Tran Mills }
670988ea7d6SRichard Tran Mills 
671f3db62a7SRichard Tran Mills /*@
67220f4b53cSBarry Smith   DMShellSetLocalToLocalVecScatter - Sets a `VecScatter` context for local to local communication
673f3db62a7SRichard Tran Mills 
67420f4b53cSBarry Smith   Logically Collective
675f3db62a7SRichard Tran Mills 
676a4e35b19SJacob Faibussowitsch   Input Parameters:
67720f4b53cSBarry Smith + dm   - the `DMSHELL`
67820f4b53cSBarry Smith - ltol - the local to local `VecScatter` context
679f3db62a7SRichard Tran Mills 
680f3db62a7SRichard Tran Mills   Level: advanced
681f3db62a7SRichard Tran Mills 
68220f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetLocalToLocal()`, `DMLocalToLocalBeginDefaultShell()`, `DMLocalToLocalEndDefaultShell()`
683f3db62a7SRichard Tran Mills @*/
DMShellSetLocalToLocalVecScatter(DM dm,VecScatter ltol)684d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalToLocalVecScatter(DM dm, VecScatter ltol)
685d71ae5a4SJacob Faibussowitsch {
686f3db62a7SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
687f3db62a7SRichard Tran Mills 
688f3db62a7SRichard Tran Mills   PetscFunctionBegin;
6892d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
69097929ea7SJunchao Zhang   PetscValidHeaderSpecific(ltol, PETSCSF_CLASSID, 2);
6919566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)ltol));
6929566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltol));
693f3db62a7SRichard Tran Mills   shell->ltol = ltol;
6943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
695f3db62a7SRichard Tran Mills }
696f3db62a7SRichard Tran Mills 
6979bf9660cSLawrence Mitchell /*@C
69820f4b53cSBarry Smith   DMShellSetCoarsen - Set the routine used to coarsen the `DMSHELL`
6999bf9660cSLawrence Mitchell 
70020f4b53cSBarry Smith   Logically Collective
7019bf9660cSLawrence Mitchell 
702a4e35b19SJacob Faibussowitsch   Input Parameters:
70320f4b53cSBarry Smith + dm      - the `DMSHELL`
70420f4b53cSBarry Smith - coarsen - the routine that coarsens the `DM`
7059bf9660cSLawrence Mitchell 
7069bf9660cSLawrence Mitchell   Level: advanced
7079bf9660cSLawrence Mitchell 
70820f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetRefine()`, `DMCoarsen()`, `DMShellGetCoarsen()`, `DMShellSetContext()`, `DMShellGetContext()`
7099bf9660cSLawrence Mitchell @*/
DMShellSetCoarsen(DM dm,PetscErrorCode (* coarsen)(DM,MPI_Comm,DM *))710d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCoarsen(DM dm, PetscErrorCode (*coarsen)(DM, MPI_Comm, DM *))
711d71ae5a4SJacob Faibussowitsch {
712f572501eSLawrence Mitchell   PetscBool isshell;
713f572501eSLawrence Mitchell 
714f572501eSLawrence Mitchell   PetscFunctionBegin;
715f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7169566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
7173ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
718f572501eSLawrence Mitchell   dm->ops->coarsen = coarsen;
7193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
720f572501eSLawrence Mitchell }
721f572501eSLawrence Mitchell 
7229bf9660cSLawrence Mitchell /*@C
72320f4b53cSBarry Smith   DMShellGetCoarsen - Get the routine used to coarsen the `DMSHELL`
7244363ddcaSBoris Boutkov 
72520f4b53cSBarry Smith   Logically Collective
7264363ddcaSBoris Boutkov 
7274165533cSJose E. Roman   Input Parameter:
72820f4b53cSBarry Smith . dm - the `DMSHELL`
7294363ddcaSBoris Boutkov 
7304165533cSJose E. Roman   Output Parameter:
73120f4b53cSBarry Smith . coarsen - the routine that coarsens the `DM`
7324363ddcaSBoris Boutkov 
7334363ddcaSBoris Boutkov   Level: advanced
7344363ddcaSBoris Boutkov 
73520f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCoarsen()`, `DMCoarsen()`, `DMShellSetRefine()`, `DMRefine()`
7364363ddcaSBoris Boutkov @*/
DMShellGetCoarsen(DM dm,PetscErrorCode (** coarsen)(DM,MPI_Comm,DM *))737d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCoarsen(DM dm, PetscErrorCode (**coarsen)(DM, MPI_Comm, DM *))
738d71ae5a4SJacob Faibussowitsch {
7394363ddcaSBoris Boutkov   PetscBool isshell;
7404363ddcaSBoris Boutkov 
7414363ddcaSBoris Boutkov   PetscFunctionBegin;
7424363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7439566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
7447a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
7454363ddcaSBoris Boutkov   *coarsen = dm->ops->coarsen;
7463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7474363ddcaSBoris Boutkov }
7484363ddcaSBoris Boutkov 
7494363ddcaSBoris Boutkov /*@C
75020f4b53cSBarry Smith   DMShellSetRefine - Set the routine used to refine the `DMSHELL`
7519bf9660cSLawrence Mitchell 
75220f4b53cSBarry Smith   Logically Collective
7539bf9660cSLawrence Mitchell 
754a4e35b19SJacob Faibussowitsch   Input Parameters:
75520f4b53cSBarry Smith + dm     - the `DMSHELL`
75620f4b53cSBarry Smith - refine - the routine that refines the `DM`
7579bf9660cSLawrence Mitchell 
7589bf9660cSLawrence Mitchell   Level: advanced
7599bf9660cSLawrence Mitchell 
76020f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCoarsen()`, `DMRefine()`, `DMShellGetRefine()`, `DMShellSetContext()`, `DMShellGetContext()`
7619bf9660cSLawrence Mitchell @*/
DMShellSetRefine(DM dm,PetscErrorCode (* refine)(DM,MPI_Comm,DM *))762d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetRefine(DM dm, PetscErrorCode (*refine)(DM, MPI_Comm, DM *))
763d71ae5a4SJacob Faibussowitsch {
764f572501eSLawrence Mitchell   PetscBool isshell;
765f572501eSLawrence Mitchell 
766f572501eSLawrence Mitchell   PetscFunctionBegin;
767f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7689566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
7693ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
770f572501eSLawrence Mitchell   dm->ops->refine = refine;
7713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
772f572501eSLawrence Mitchell }
773f572501eSLawrence Mitchell 
7749bf9660cSLawrence Mitchell /*@C
77520f4b53cSBarry Smith   DMShellGetRefine - Get the routine used to refine the `DMSHELL`
7764363ddcaSBoris Boutkov 
77720f4b53cSBarry Smith   Logically Collective
7784363ddcaSBoris Boutkov 
7794165533cSJose E. Roman   Input Parameter:
78020f4b53cSBarry Smith . dm - the `DMSHELL`
7814363ddcaSBoris Boutkov 
7824165533cSJose E. Roman   Output Parameter:
78320f4b53cSBarry Smith . refine - the routine that refines the `DM`
7844363ddcaSBoris Boutkov 
7854363ddcaSBoris Boutkov   Level: advanced
7864363ddcaSBoris Boutkov 
78720f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCoarsen()`, `DMCoarsen()`, `DMShellSetRefine()`, `DMRefine()`
7884363ddcaSBoris Boutkov @*/
DMShellGetRefine(DM dm,PetscErrorCode (** refine)(DM,MPI_Comm,DM *))789d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetRefine(DM dm, PetscErrorCode (**refine)(DM, MPI_Comm, DM *))
790d71ae5a4SJacob Faibussowitsch {
7914363ddcaSBoris Boutkov   PetscBool isshell;
7924363ddcaSBoris Boutkov 
7934363ddcaSBoris Boutkov   PetscFunctionBegin;
7944363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7959566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
7967a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
7974363ddcaSBoris Boutkov   *refine = dm->ops->refine;
7983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7994363ddcaSBoris Boutkov }
8004363ddcaSBoris Boutkov 
8014363ddcaSBoris Boutkov /*@C
8029bf9660cSLawrence Mitchell   DMShellSetCreateInterpolation - Set the routine used to create the interpolation operator
8039bf9660cSLawrence Mitchell 
80420f4b53cSBarry Smith   Logically Collective
8059bf9660cSLawrence Mitchell 
806a4e35b19SJacob Faibussowitsch   Input Parameters:
80720f4b53cSBarry Smith + dm     - the `DMSHELL`
8089bf9660cSLawrence Mitchell - interp - the routine to create the interpolation
8099bf9660cSLawrence Mitchell 
8109bf9660cSLawrence Mitchell   Level: advanced
8119bf9660cSLawrence Mitchell 
81220f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateInterpolation()`, `DMShellSetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
8139bf9660cSLawrence Mitchell @*/
DMShellSetCreateInterpolation(DM dm,PetscErrorCode (* interp)(DM,DM,Mat *,Vec *))814d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateInterpolation(DM dm, PetscErrorCode (*interp)(DM, DM, Mat *, Vec *))
815d71ae5a4SJacob Faibussowitsch {
816f572501eSLawrence Mitchell   PetscBool isshell;
817f572501eSLawrence Mitchell 
818f572501eSLawrence Mitchell   PetscFunctionBegin;
819f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8209566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
8213ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
822f572501eSLawrence Mitchell   dm->ops->createinterpolation = interp;
8233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
824f572501eSLawrence Mitchell }
825f572501eSLawrence Mitchell 
8263ad4599aSBarry Smith /*@C
8274363ddcaSBoris Boutkov   DMShellGetCreateInterpolation - Get the routine used to create the interpolation operator
8284363ddcaSBoris Boutkov 
82920f4b53cSBarry Smith   Logically Collective
8304363ddcaSBoris Boutkov 
8314165533cSJose E. Roman   Input Parameter:
83220f4b53cSBarry Smith . dm - the `DMSHELL`
833a4a986ddSBoris Boutkov 
8344165533cSJose E. Roman   Output Parameter:
8354165533cSJose E. Roman . interp - the routine to create the interpolation
8364363ddcaSBoris Boutkov 
8374363ddcaSBoris Boutkov   Level: advanced
8384363ddcaSBoris Boutkov 
83920f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellGetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
8404363ddcaSBoris Boutkov @*/
DMShellGetCreateInterpolation(DM dm,PetscErrorCode (** interp)(DM,DM,Mat *,Vec *))841d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCreateInterpolation(DM dm, PetscErrorCode (**interp)(DM, DM, Mat *, Vec *))
842d71ae5a4SJacob Faibussowitsch {
8434363ddcaSBoris Boutkov   PetscBool isshell;
8444363ddcaSBoris Boutkov 
8454363ddcaSBoris Boutkov   PetscFunctionBegin;
8464363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8479566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
8487a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
8494363ddcaSBoris Boutkov   *interp = dm->ops->createinterpolation;
8503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8514363ddcaSBoris Boutkov }
8524363ddcaSBoris Boutkov 
8534363ddcaSBoris Boutkov /*@C
8543ad4599aSBarry Smith   DMShellSetCreateRestriction - Set the routine used to create the restriction operator
8553ad4599aSBarry Smith 
85620f4b53cSBarry Smith   Logically Collective
8573ad4599aSBarry Smith 
858a4e35b19SJacob Faibussowitsch   Input Parameters:
85920f4b53cSBarry Smith + dm          - the `DMSHELL`
86060225df5SJacob Faibussowitsch - restriction - the routine to create the restriction
8613ad4599aSBarry Smith 
8623ad4599aSBarry Smith   Level: advanced
8633ad4599aSBarry Smith 
86420f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
8653ad4599aSBarry Smith @*/
DMShellSetCreateRestriction(DM dm,PetscErrorCode (* restriction)(DM,DM,Mat *))866d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateRestriction(DM dm, PetscErrorCode (*restriction)(DM, DM, Mat *))
867d71ae5a4SJacob Faibussowitsch {
8683ad4599aSBarry Smith   PetscBool isshell;
8693ad4599aSBarry Smith 
8703ad4599aSBarry Smith   PetscFunctionBegin;
8713ad4599aSBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8729566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
8733ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
8743ad4599aSBarry Smith   dm->ops->createrestriction = restriction;
8753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8763ad4599aSBarry Smith }
8773ad4599aSBarry Smith 
8789bf9660cSLawrence Mitchell /*@C
8794363ddcaSBoris Boutkov   DMShellGetCreateRestriction - Get the routine used to create the restriction operator
8804363ddcaSBoris Boutkov 
88120f4b53cSBarry Smith   Logically Collective
8824363ddcaSBoris Boutkov 
8834165533cSJose E. Roman   Input Parameter:
88420f4b53cSBarry Smith . dm - the `DMSHELL`
885a4a986ddSBoris Boutkov 
8864165533cSJose E. Roman   Output Parameter:
8874165533cSJose E. Roman . restriction - the routine to create the restriction
8884363ddcaSBoris Boutkov 
8894363ddcaSBoris Boutkov   Level: advanced
8904363ddcaSBoris Boutkov 
89120f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellSetContext()`, `DMShellGetContext()`
8924363ddcaSBoris Boutkov @*/
DMShellGetCreateRestriction(DM dm,PetscErrorCode (** restriction)(DM,DM,Mat *))893d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCreateRestriction(DM dm, PetscErrorCode (**restriction)(DM, DM, Mat *))
894d71ae5a4SJacob Faibussowitsch {
8954363ddcaSBoris Boutkov   PetscBool isshell;
8964363ddcaSBoris Boutkov 
8974363ddcaSBoris Boutkov   PetscFunctionBegin;
8984363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8999566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
9007a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
9014363ddcaSBoris Boutkov   *restriction = dm->ops->createrestriction;
9023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9034363ddcaSBoris Boutkov }
9044363ddcaSBoris Boutkov 
9054363ddcaSBoris Boutkov /*@C
9069bf9660cSLawrence Mitchell   DMShellSetCreateInjection - Set the routine used to create the injection operator
9079bf9660cSLawrence Mitchell 
90820f4b53cSBarry Smith   Logically Collective
9099bf9660cSLawrence Mitchell 
9104165533cSJose E. Roman   Input Parameters:
91120f4b53cSBarry Smith + dm     - the `DMSHELL`
9129bf9660cSLawrence Mitchell - inject - the routine to create the injection
9139bf9660cSLawrence Mitchell 
9149bf9660cSLawrence Mitchell   Level: advanced
9159bf9660cSLawrence Mitchell 
91620f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCreateInterpolation()`, `DMCreateInjection()`, `DMShellGetCreateInjection()`, `DMShellSetContext()`, `DMShellGetContext()`
9179bf9660cSLawrence Mitchell @*/
DMShellSetCreateInjection(DM dm,PetscErrorCode (* inject)(DM,DM,Mat *))918d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateInjection(DM dm, PetscErrorCode (*inject)(DM, DM, Mat *))
919d71ae5a4SJacob Faibussowitsch {
920f572501eSLawrence Mitchell   PetscBool isshell;
921f572501eSLawrence Mitchell 
922f572501eSLawrence Mitchell   PetscFunctionBegin;
923f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9249566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
9253ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
9265a84ad33SLisandro Dalcin   dm->ops->createinjection = inject;
9273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
928f572501eSLawrence Mitchell }
929f572501eSLawrence Mitchell 
9304363ddcaSBoris Boutkov /*@C
9314363ddcaSBoris Boutkov   DMShellGetCreateInjection - Get the routine used to create the injection operator
9324363ddcaSBoris Boutkov 
93320f4b53cSBarry Smith   Logically Collective
9344363ddcaSBoris Boutkov 
9354165533cSJose E. Roman   Input Parameter:
93620f4b53cSBarry Smith . dm - the `DMSHELL`
937a4a986ddSBoris Boutkov 
9384165533cSJose E. Roman   Output Parameter:
9394165533cSJose E. Roman . inject - the routine to create the injection
9404363ddcaSBoris Boutkov 
9414363ddcaSBoris Boutkov   Level: advanced
9424363ddcaSBoris Boutkov 
94320f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellGetCreateInterpolation()`, `DMCreateInjection()`, `DMShellSetContext()`, `DMShellGetContext()`
9444363ddcaSBoris Boutkov @*/
DMShellGetCreateInjection(DM dm,PetscErrorCode (** inject)(DM,DM,Mat *))945d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCreateInjection(DM dm, PetscErrorCode (**inject)(DM, DM, Mat *))
946d71ae5a4SJacob Faibussowitsch {
9474363ddcaSBoris Boutkov   PetscBool isshell;
9484363ddcaSBoris Boutkov 
9494363ddcaSBoris Boutkov   PetscFunctionBegin;
9504363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9519566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
9527a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
9535a84ad33SLisandro Dalcin   *inject = dm->ops->createinjection;
9543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9554363ddcaSBoris Boutkov }
9564363ddcaSBoris Boutkov 
9579bf9660cSLawrence Mitchell /*@C
95820f4b53cSBarry Smith   DMShellSetCreateFieldDecomposition - Set the routine used to create a decomposition of fields for the `DMSHELL`
9599bf9660cSLawrence Mitchell 
96020f4b53cSBarry Smith   Logically Collective
9619bf9660cSLawrence Mitchell 
9624165533cSJose E. Roman   Input Parameters:
96320f4b53cSBarry Smith + dm     - the `DMSHELL`
9649bf9660cSLawrence Mitchell - decomp - the routine to create the decomposition
9659bf9660cSLawrence Mitchell 
9669bf9660cSLawrence Mitchell   Level: advanced
9679bf9660cSLawrence Mitchell 
96820f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateFieldDecomposition()`, `DMShellSetContext()`, `DMShellGetContext()`
9699bf9660cSLawrence Mitchell @*/
DMShellSetCreateFieldDecomposition(DM dm,PetscErrorCode (* decomp)(DM,PetscInt *,char ***,IS **,DM **))970d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateFieldDecomposition(DM dm, PetscErrorCode (*decomp)(DM, PetscInt *, char ***, IS **, DM **))
971d71ae5a4SJacob Faibussowitsch {
9725e2259d5SLawrence Mitchell   PetscBool isshell;
9735e2259d5SLawrence Mitchell 
9745e2259d5SLawrence Mitchell   PetscFunctionBegin;
9755e2259d5SLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9769566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
9773ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
9785e2259d5SLawrence Mitchell   dm->ops->createfielddecomposition = decomp;
9793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9805e2259d5SLawrence Mitchell }
9815e2259d5SLawrence Mitchell 
982c00061e5SLawrence Mitchell /*@C
98320f4b53cSBarry Smith   DMShellSetCreateDomainDecomposition - Set the routine used to create a domain decomposition for the `DMSHELL`
984e734121bSPatrick Farrell 
98520f4b53cSBarry Smith   Logically Collective
986e734121bSPatrick Farrell 
9874165533cSJose E. Roman   Input Parameters:
98820f4b53cSBarry Smith + dm     - the `DMSHELL`
989e734121bSPatrick Farrell - decomp - the routine to create the decomposition
990e734121bSPatrick Farrell 
991e734121bSPatrick Farrell   Level: advanced
992e734121bSPatrick Farrell 
99320f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateDomainDecomposition()`, `DMShellSetContext()`, `DMShellGetContext()`
994e734121bSPatrick Farrell @*/
DMShellSetCreateDomainDecomposition(DM dm,PetscErrorCode (* decomp)(DM,PetscInt *,char ***,IS **,IS **,DM **))995d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateDomainDecomposition(DM dm, PetscErrorCode (*decomp)(DM, PetscInt *, char ***, IS **, IS **, DM **))
996d71ae5a4SJacob Faibussowitsch {
997e734121bSPatrick Farrell   PetscBool isshell;
998e734121bSPatrick Farrell 
999e734121bSPatrick Farrell   PetscFunctionBegin;
1000e734121bSPatrick Farrell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10019566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
10023ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
1003e734121bSPatrick Farrell   dm->ops->createdomaindecomposition = decomp;
10043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1005e734121bSPatrick Farrell }
1006e734121bSPatrick Farrell 
1007e734121bSPatrick Farrell /*@C
100820f4b53cSBarry Smith   DMShellSetCreateDomainDecompositionScatters - Set the routine used to create the scatter contexts for domain decomposition with a `DMSHELL`
1009eef9d6cdSPatrick Farrell 
101020f4b53cSBarry Smith   Logically Collective
1011eef9d6cdSPatrick Farrell 
10124165533cSJose E. Roman   Input Parameters:
101320f4b53cSBarry Smith + dm      - the `DMSHELL`
1014eef9d6cdSPatrick Farrell - scatter - the routine to create the scatters
1015eef9d6cdSPatrick Farrell 
1016eef9d6cdSPatrick Farrell   Level: advanced
1017eef9d6cdSPatrick Farrell 
101820f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateDomainDecompositionScatters()`, `DMShellSetContext()`, `DMShellGetContext()`
1019eef9d6cdSPatrick Farrell @*/
DMShellSetCreateDomainDecompositionScatters(DM dm,PetscErrorCode (* scatter)(DM,PetscInt,DM *,VecScatter **,VecScatter **,VecScatter **))1020d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateDomainDecompositionScatters(DM dm, PetscErrorCode (*scatter)(DM, PetscInt, DM *, VecScatter **, VecScatter **, VecScatter **))
1021d71ae5a4SJacob Faibussowitsch {
1022eef9d6cdSPatrick Farrell   PetscBool isshell;
1023eef9d6cdSPatrick Farrell 
1024eef9d6cdSPatrick Farrell   PetscFunctionBegin;
1025eef9d6cdSPatrick Farrell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10269566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
10273ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
1028eef9d6cdSPatrick Farrell   dm->ops->createddscatters = scatter;
10293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1030eef9d6cdSPatrick Farrell }
1031eef9d6cdSPatrick Farrell 
1032eef9d6cdSPatrick Farrell /*@C
103320f4b53cSBarry Smith   DMShellSetCreateSubDM - Set the routine used to create a sub `DM` from the `DMSHELL`
1034c00061e5SLawrence Mitchell 
103520f4b53cSBarry Smith   Logically Collective
1036c00061e5SLawrence Mitchell 
10374165533cSJose E. Roman   Input Parameters:
103820f4b53cSBarry Smith + dm    - the `DMSHELL`
1039c00061e5SLawrence Mitchell - subdm - the routine to create the decomposition
1040c00061e5SLawrence Mitchell 
1041c00061e5SLawrence Mitchell   Level: advanced
1042c00061e5SLawrence Mitchell 
104320f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateSubDM()`, `DMShellGetCreateSubDM()`, `DMShellSetContext()`, `DMShellGetContext()`
1044c00061e5SLawrence Mitchell @*/
DMShellSetCreateSubDM(DM dm,PetscErrorCode (* subdm)(DM,PetscInt,const PetscInt[],IS *,DM *))1045d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateSubDM(DM dm, PetscErrorCode (*subdm)(DM, PetscInt, const PetscInt[], IS *, DM *))
1046d71ae5a4SJacob Faibussowitsch {
1047c00061e5SLawrence Mitchell   PetscBool isshell;
1048c00061e5SLawrence Mitchell 
1049c00061e5SLawrence Mitchell   PetscFunctionBegin;
1050c00061e5SLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10519566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
10523ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
1053c00061e5SLawrence Mitchell   dm->ops->createsubdm = subdm;
10543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1055c00061e5SLawrence Mitchell }
1056c00061e5SLawrence Mitchell 
10574363ddcaSBoris Boutkov /*@C
105820f4b53cSBarry Smith   DMShellGetCreateSubDM - Get the routine used to create a sub DM from the `DMSHELL`
10594363ddcaSBoris Boutkov 
106020f4b53cSBarry Smith   Logically Collective
10614363ddcaSBoris Boutkov 
10624165533cSJose E. Roman   Input Parameter:
106320f4b53cSBarry Smith . dm - the `DMSHELL`
1064a4a986ddSBoris Boutkov 
10654165533cSJose E. Roman   Output Parameter:
10664165533cSJose E. Roman . subdm - the routine to create the decomposition
10674363ddcaSBoris Boutkov 
10684363ddcaSBoris Boutkov   Level: advanced
10694363ddcaSBoris Boutkov 
107020f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateSubDM()`, `DMShellSetCreateSubDM()`, `DMShellSetContext()`, `DMShellGetContext()`
10714363ddcaSBoris Boutkov @*/
DMShellGetCreateSubDM(DM dm,PetscErrorCode (** subdm)(DM,PetscInt,const PetscInt[],IS *,DM *))1072d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCreateSubDM(DM dm, PetscErrorCode (**subdm)(DM, PetscInt, const PetscInt[], IS *, DM *))
1073d71ae5a4SJacob Faibussowitsch {
10744363ddcaSBoris Boutkov   PetscBool isshell;
10754363ddcaSBoris Boutkov 
10764363ddcaSBoris Boutkov   PetscFunctionBegin;
10774363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10789566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
10797a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
10804363ddcaSBoris Boutkov   *subdm = dm->ops->createsubdm;
10813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10824363ddcaSBoris Boutkov }
10834363ddcaSBoris Boutkov 
DMDestroy_Shell(DM dm)1084d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDestroy_Shell(DM dm)
1085d71ae5a4SJacob Faibussowitsch {
1086fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
1087fe1899a2SJed Brown 
1088fe1899a2SJed Brown   PetscFunctionBegin;
1089e6aa7a3bSBarry Smith   if (shell->destroyctx) PetscCallBack("Destroy Context", (*shell->destroyctx)(&shell->ctx));
10909566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&shell->A));
10919566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xglobal));
10929566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xlocal));
10939566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->gtol));
10949566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltog));
10959566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltol));
10967b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
10979566063dSJacob Faibussowitsch   PetscCall(PetscFree(shell));
10983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1099fe1899a2SJed Brown }
1100fe1899a2SJed Brown 
DMView_Shell(DM dm,PetscViewer v)1101d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMView_Shell(DM dm, PetscViewer v)
1102d71ae5a4SJacob Faibussowitsch {
11032d53ad75SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
11042d53ad75SBarry Smith 
11052d53ad75SBarry Smith   PetscFunctionBegin;
110601f8681bSStefano Zampini   if (shell->Xglobal) PetscCall(VecView(shell->Xglobal, v));
11073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11082d53ad75SBarry Smith }
11092d53ad75SBarry Smith 
DMLoad_Shell(DM dm,PetscViewer v)1110d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLoad_Shell(DM dm, PetscViewer v)
1111d71ae5a4SJacob Faibussowitsch {
11122d53ad75SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
11132d53ad75SBarry Smith 
11142d53ad75SBarry Smith   PetscFunctionBegin;
11159566063dSJacob Faibussowitsch   PetscCall(VecCreate(PetscObjectComm((PetscObject)dm), &shell->Xglobal));
11169566063dSJacob Faibussowitsch   PetscCall(VecLoad(shell->Xglobal, v));
11173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11182d53ad75SBarry Smith }
1119fe1899a2SJed Brown 
DMCreateSubDM_Shell(DM dm,PetscInt numFields,const PetscInt fields[],IS * is,DM * subdm)112066976f2fSJacob Faibussowitsch static PetscErrorCode DMCreateSubDM_Shell(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm)
1121d71ae5a4SJacob Faibussowitsch {
11226e44b4cfSMatthew G. Knepley   PetscFunctionBegin;
11239566063dSJacob Faibussowitsch   if (subdm) PetscCall(DMShellCreate(PetscObjectComm((PetscObject)dm), subdm));
1124dd072f5fSMatthew G. Knepley   PetscCall(DMCreateSectionSubDM(dm, numFields, fields, NULL, NULL, is, subdm));
11253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11266e44b4cfSMatthew G. Knepley }
11276e44b4cfSMatthew G. Knepley 
DMCreate_Shell(DM dm)1128d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm)
1129d71ae5a4SJacob Faibussowitsch {
1130fe1899a2SJed Brown   DM_Shell *shell;
1131fe1899a2SJed Brown 
1132fe1899a2SJed Brown   PetscFunctionBegin;
11334dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&shell));
11348c87107bSJed Brown   dm->data = shell;
1135fe1899a2SJed Brown 
11368c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
11378c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
1138dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
11398c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
11402d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
11412d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
11427a108d1dSBarry Smith   dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell;
11437a108d1dSBarry Smith   dm->ops->globaltolocalend   = DMGlobalToLocalEndDefaultShell;
114455daaa54SRichard Tran Mills   dm->ops->localtoglobalbegin = DMLocalToGlobalBeginDefaultShell;
114555daaa54SRichard Tran Mills   dm->ops->localtoglobalend   = DMLocalToGlobalEndDefaultShell;
114663731094SRichard Tran Mills   dm->ops->localtolocalbegin  = DMLocalToLocalBeginDefaultShell;
114763731094SRichard Tran Mills   dm->ops->localtolocalend    = DMLocalToLocalEndDefaultShell;
11486e44b4cfSMatthew G. Knepley   dm->ops->createsubdm        = DMCreateSubDM_Shell;
11499566063dSJacob Faibussowitsch   PetscCall(DMSetMatType(dm, MATDENSE));
11503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1151fe1899a2SJed Brown }
1152fe1899a2SJed Brown 
1153fe1899a2SJed Brown /*@
115420f4b53cSBarry Smith   DMShellCreate - Creates a `DMSHELL` object, used to manage user-defined problem data
1155fe1899a2SJed Brown 
1156d083f849SBarry Smith   Collective
1157fe1899a2SJed Brown 
1158fe1899a2SJed Brown   Input Parameter:
1159fe1899a2SJed Brown . comm - the processors that will share the global vector
1160fe1899a2SJed Brown 
11612fe279fdSBarry Smith   Output Parameter:
116260225df5SJacob Faibussowitsch . dm - the `DMSHELL`
1163fe1899a2SJed Brown 
1164fe1899a2SJed Brown   Level: advanced
1165fe1899a2SJed Brown 
1166a4e35b19SJacob Faibussowitsch .seealso: `DMDestroy()`, `DMCreateGlobalVector()`, `DMCreateLocalVector()`, `DMShellSetContext()`, `DMShellGetContext()`
1167fe1899a2SJed Brown @*/
DMShellCreate(MPI_Comm comm,DM * dm)1168d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellCreate(MPI_Comm comm, DM *dm)
1169d71ae5a4SJacob Faibussowitsch {
1170fe1899a2SJed Brown   PetscFunctionBegin;
11714f572ea9SToby Isaac   PetscAssertPointer(dm, 2);
11729566063dSJacob Faibussowitsch   PetscCall(DMCreate(comm, dm));
11739566063dSJacob Faibussowitsch   PetscCall(DMSetType(*dm, DMSHELL));
11749566063dSJacob Faibussowitsch   PetscCall(DMSetUp(*dm));
11753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1176fe1899a2SJed Brown }
1177