xref: /petsc/src/dm/impls/shell/dmshell.c (revision a4e35b1925eceef64945ea472b84f2bf06a67b5e)
1fe1899a2SJed Brown #include <petscdmshell.h> /*I    "petscdmshell.h"  I*/
207475bc1SBarry Smith #include <petscmat.h>
3af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
4fe1899a2SJed Brown 
5fe1899a2SJed Brown typedef struct {
6fe1899a2SJed Brown   Vec        Xglobal;
7dc43b69eSJed Brown   Vec        Xlocal;
8fe1899a2SJed Brown   Mat        A;
9a94b16f6SRichard Tran Mills   VecScatter gtol;
10a94b16f6SRichard Tran Mills   VecScatter ltog;
11f089877aSRichard Tran Mills   VecScatter ltol;
12fef3a512SBarry Smith   void      *ctx;
1309904cd0SBarry Smith   PetscErrorCode (*destroyctx)(void *);
14fe1899a2SJed Brown } DM_Shell;
15fe1899a2SJed Brown 
167a108d1dSBarry Smith /*@
1720f4b53cSBarry Smith   DMGlobalToLocalBeginDefaultShell - Uses the GlobalToLocal `VecScatter` context set by the user to begin a global to local scatter
1820f4b53cSBarry Smith 
198d359177SBarry Smith   Collective
208d359177SBarry Smith 
214165533cSJose E. Roman   Input Parameters:
2220f4b53cSBarry Smith + dm   - `DMSHELL`
238d359177SBarry Smith . g    - global vector
2420f4b53cSBarry Smith . mode - `InsertMode`
258d359177SBarry Smith - l    - local vector
268d359177SBarry Smith 
277a108d1dSBarry Smith   Level: advanced
288d359177SBarry Smith 
2920f4b53cSBarry Smith   Note:
3020f4b53cSBarry Smith   This is not normally called directly by user code, generally user code calls `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()`. If the user provides their own custom routines to `DMShellSetLocalToGlobal()` then those routines might have reason to call this function.
317a108d1dSBarry Smith 
3220f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMGlobalToLocalEndDefaultShell()`
338d359177SBarry Smith @*/
34d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalBeginDefaultShell(DM dm, Vec g, InsertMode mode, Vec l)
35d71ae5a4SJacob Faibussowitsch {
368d359177SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
378d359177SBarry Smith 
388d359177SBarry Smith   PetscFunctionBegin;
397a8be351SBarry Smith   PetscCheck(shell->gtol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
409566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->gtol, g, l, mode, SCATTER_FORWARD));
413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
428d359177SBarry Smith }
438d359177SBarry Smith 
447a108d1dSBarry Smith /*@
4520f4b53cSBarry Smith   DMGlobalToLocalEndDefaultShell - Uses the GlobalToLocal `VecScatter` context set by the user to end a global to local scatter
468d359177SBarry Smith   Collective
478d359177SBarry Smith 
484165533cSJose E. Roman   Input Parameters:
4920f4b53cSBarry Smith + dm   - `DMSHELL`
508d359177SBarry Smith . g    - global vector
5120f4b53cSBarry Smith . mode - `InsertMode`
528d359177SBarry Smith - l    - local vector
538d359177SBarry Smith 
547a108d1dSBarry Smith   Level: advanced
558d359177SBarry Smith 
5620f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMGlobalToLocalBeginDefaultShell()`
578d359177SBarry Smith @*/
58d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalEndDefaultShell(DM dm, Vec g, InsertMode mode, Vec l)
59d71ae5a4SJacob Faibussowitsch {
608d359177SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
618d359177SBarry Smith 
628d359177SBarry Smith   PetscFunctionBegin;
637a8be351SBarry Smith   PetscCheck(shell->gtol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
649566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->gtol, g, l, mode, SCATTER_FORWARD));
653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
668d359177SBarry Smith }
678d359177SBarry Smith 
68c5076b69SRichard Tran Mills /*@
6920f4b53cSBarry Smith   DMLocalToGlobalBeginDefaultShell - Uses the LocalToGlobal `VecScatter` context set by the user to begin a local to global scatter
70c5076b69SRichard Tran Mills   Collective
71c5076b69SRichard Tran Mills 
724165533cSJose E. Roman   Input Parameters:
7320f4b53cSBarry Smith + dm   - `DMSHELL`
74c5076b69SRichard Tran Mills . l    - local vector
7520f4b53cSBarry Smith . mode - `InsertMode`
76c5076b69SRichard Tran Mills - g    - global vector
77c5076b69SRichard Tran Mills 
78c5076b69SRichard Tran Mills   Level: advanced
79c5076b69SRichard Tran Mills 
8020f4b53cSBarry Smith   Note:
8120f4b53cSBarry Smith   This is not normally called directly by user code, generally user code calls `DMLocalToGlobalBegin()` and `DMLocalToGlobalEnd()`. If the user provides their own custom routines to `DMShellSetLocalToGlobal()` then those routines might have reason to call this function.
82c5076b69SRichard Tran Mills 
8320f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMLocalToGlobalEndDefaultShell()`
84c5076b69SRichard Tran Mills @*/
85d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalBeginDefaultShell(DM dm, Vec l, InsertMode mode, Vec g)
86d71ae5a4SJacob Faibussowitsch {
87c5076b69SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
88c5076b69SRichard Tran Mills 
89c5076b69SRichard Tran Mills   PetscFunctionBegin;
907a8be351SBarry Smith   PetscCheck(shell->ltog, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
919566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->ltog, l, g, mode, SCATTER_FORWARD));
923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
93c5076b69SRichard Tran Mills }
94c5076b69SRichard Tran Mills 
95c5076b69SRichard Tran Mills /*@
9620f4b53cSBarry Smith   DMLocalToGlobalEndDefaultShell - Uses the LocalToGlobal `VecScatter` context set by the user to end a local to global scatter
97c5076b69SRichard Tran Mills   Collective
98c5076b69SRichard Tran Mills 
994165533cSJose E. Roman   Input Parameters:
10020f4b53cSBarry Smith + dm   - `DMSHELL`
101c5076b69SRichard Tran Mills . l    - local vector
10220f4b53cSBarry Smith . mode - `InsertMode`
103c5076b69SRichard Tran Mills - g    - global vector
104c5076b69SRichard Tran Mills 
105c5076b69SRichard Tran Mills   Level: advanced
106c5076b69SRichard Tran Mills 
10720f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMLocalToGlobalBeginDefaultShell()`
108c5076b69SRichard Tran Mills @*/
109d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalEndDefaultShell(DM dm, Vec l, InsertMode mode, Vec g)
110d71ae5a4SJacob Faibussowitsch {
111c5076b69SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
112c5076b69SRichard Tran Mills 
113c5076b69SRichard Tran Mills   PetscFunctionBegin;
1147a8be351SBarry Smith   PetscCheck(shell->ltog, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
1159566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->ltog, l, g, mode, SCATTER_FORWARD));
1163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
117c5076b69SRichard Tran Mills }
118c5076b69SRichard Tran Mills 
119f3db62a7SRichard Tran Mills /*@
12020f4b53cSBarry Smith   DMLocalToLocalBeginDefaultShell - Uses the LocalToLocal `VecScatter` context set by the user to begin a local to local scatter
121f3db62a7SRichard Tran Mills   Collective
122f3db62a7SRichard Tran Mills 
1234165533cSJose E. Roman   Input Parameters:
12420f4b53cSBarry Smith + dm   - `DMSHELL`
125f3db62a7SRichard Tran Mills . g    - the original local vector
12620f4b53cSBarry Smith - mode - `InsertMode`
127f3db62a7SRichard Tran Mills 
128f3db62a7SRichard Tran Mills   Output Parameter:
129f3db62a7SRichard Tran Mills . l - the local vector with correct ghost values
130f3db62a7SRichard Tran Mills 
131f3db62a7SRichard Tran Mills   Level: advanced
132f3db62a7SRichard Tran Mills 
13320f4b53cSBarry Smith   Note:
13420f4b53cSBarry Smith   This is not normally called directly by user code, generally user code calls `DMLocalToLocalBegin()` and `DMLocalToLocalEnd()`. If the user provides their own custom routines to `DMShellSetLocalToLocal()` then those routines might have reason to call this function.
135f3db62a7SRichard Tran Mills 
13620f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMLocalToLocalEndDefaultShell()`
137f3db62a7SRichard Tran Mills @*/
138d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalBeginDefaultShell(DM dm, Vec g, InsertMode mode, Vec l)
139d71ae5a4SJacob Faibussowitsch {
140f3db62a7SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
141f3db62a7SRichard Tran Mills 
142f3db62a7SRichard Tran Mills   PetscFunctionBegin;
1437a8be351SBarry Smith   PetscCheck(shell->ltol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToLocalVecScatter()");
1449566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->ltol, g, l, mode, SCATTER_FORWARD));
1453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
146f3db62a7SRichard Tran Mills }
147f3db62a7SRichard Tran Mills 
148f3db62a7SRichard Tran Mills /*@
14920f4b53cSBarry Smith   DMLocalToLocalEndDefaultShell - Uses the LocalToLocal `VecScatter` context set by the user to end a local to local scatter
150f3db62a7SRichard Tran Mills   Collective
151f3db62a7SRichard Tran Mills 
1524165533cSJose E. Roman   Input Parameters:
15320f4b53cSBarry Smith + dm   - `DMSHELL`
154f3db62a7SRichard Tran Mills . g    - the original local vector
15520f4b53cSBarry Smith - mode - `InsertMode`
156f3db62a7SRichard Tran Mills 
157f3db62a7SRichard Tran Mills   Output Parameter:
158f3db62a7SRichard Tran Mills . l - the local vector with correct ghost values
159f3db62a7SRichard Tran Mills 
160f3db62a7SRichard Tran Mills   Level: advanced
161f3db62a7SRichard Tran Mills 
16220f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMLocalToLocalBeginDefaultShell()`
163f3db62a7SRichard Tran Mills @*/
164d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalEndDefaultShell(DM dm, Vec g, InsertMode mode, Vec l)
165d71ae5a4SJacob Faibussowitsch {
166f3db62a7SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
167f3db62a7SRichard Tran Mills 
168f3db62a7SRichard Tran Mills   PetscFunctionBegin;
1697a8be351SBarry Smith   PetscCheck(shell->ltol, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
1709566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->ltol, g, l, mode, SCATTER_FORWARD));
1713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
172f3db62a7SRichard Tran Mills }
173c5076b69SRichard Tran Mills 
174d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCreateMatrix_Shell(DM dm, Mat *J)
175d71ae5a4SJacob Faibussowitsch {
176fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
177fe1899a2SJed Brown   Mat       A;
178fe1899a2SJed Brown 
179fe1899a2SJed Brown   PetscFunctionBegin;
180fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1814f572ea9SToby Isaac   PetscAssertPointer(J, 2);
1827bde9f88SJed Brown   if (!shell->A) {
1837bde9f88SJed Brown     if (shell->Xglobal) {
1847bde9f88SJed Brown       PetscInt m, M;
1859566063dSJacob Faibussowitsch       PetscCall(PetscInfo(dm, "Naively creating matrix using global vector distribution without preallocation\n"));
1869566063dSJacob Faibussowitsch       PetscCall(VecGetSize(shell->Xglobal, &M));
1879566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(shell->Xglobal, &m));
1889566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)dm), &shell->A));
1899566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(shell->A, m, m, M, M));
1909566063dSJacob Faibussowitsch       PetscCall(MatSetType(shell->A, dm->mattype));
1919566063dSJacob Faibussowitsch       PetscCall(MatSetUp(shell->A));
192ce94432eSBarry Smith     } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector");
1937bde9f88SJed Brown   }
194fe1899a2SJed Brown   A = shell->A;
1959566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(A, MAT_SHARE_NONZERO_PATTERN, J));
1969566063dSJacob Faibussowitsch   PetscCall(MatSetDM(*J, dm));
1973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
198fe1899a2SJed Brown }
199fe1899a2SJed Brown 
200d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateGlobalVector_Shell(DM dm, Vec *gvec)
201d71ae5a4SJacob Faibussowitsch {
202fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
203fe1899a2SJed Brown   Vec       X;
204fe1899a2SJed Brown 
205fe1899a2SJed Brown   PetscFunctionBegin;
206fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
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 
218d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLocalVector_Shell(DM dm, Vec *gvec)
219d71ae5a4SJacob Faibussowitsch {
220dc43b69eSJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
221dc43b69eSJed Brown   Vec       X;
222dc43b69eSJed Brown 
223dc43b69eSJed Brown   PetscFunctionBegin;
224dc43b69eSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
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 @*/
249d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetDestroyContext(DM dm, PetscErrorCode (*destroyctx)(void *))
250d71ae5a4SJacob Faibussowitsch {
25109904cd0SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
25209904cd0SBarry Smith   PetscBool isshell;
25309904cd0SBarry Smith 
25409904cd0SBarry Smith   PetscFunctionBegin;
25509904cd0SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
25609904cd0SBarry Smith   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
2573ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
25809904cd0SBarry Smith   shell->destroyctx = destroyctx;
2593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
26009904cd0SBarry Smith }
26109904cd0SBarry Smith 
26209904cd0SBarry Smith /*@
26320f4b53cSBarry Smith   DMShellSetContext - set some data to be usable by this `DMSHELL`
264fef3a512SBarry Smith 
265fef3a512SBarry Smith   Collective
266fef3a512SBarry Smith 
2674165533cSJose E. Roman   Input Parameters:
26820f4b53cSBarry Smith + dm  - `DMSHELL`
269fef3a512SBarry Smith - ctx - the context
270fef3a512SBarry Smith 
271fef3a512SBarry Smith   Level: advanced
272fef3a512SBarry Smith 
27320f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateMatrix()`, `DMShellGetContext()`
274fef3a512SBarry Smith @*/
275d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetContext(DM dm, void *ctx)
276d71ae5a4SJacob Faibussowitsch {
277fef3a512SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
278fef3a512SBarry Smith   PetscBool isshell;
279fef3a512SBarry Smith 
280fef3a512SBarry Smith   PetscFunctionBegin;
281fef3a512SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2829566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
2833ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
284fef3a512SBarry Smith   shell->ctx = ctx;
2853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
286fef3a512SBarry Smith }
287fef3a512SBarry Smith 
288fef3a512SBarry Smith /*@
28920f4b53cSBarry Smith   DMShellGetContext - Returns the user-provided context associated to the `DMSHELL`
290fef3a512SBarry Smith 
291fef3a512SBarry Smith   Collective
292fef3a512SBarry Smith 
2934165533cSJose E. Roman   Input Parameter:
29420f4b53cSBarry Smith . dm - `DMSHELL`
295fef3a512SBarry Smith 
2964165533cSJose E. Roman   Output Parameter:
297fef3a512SBarry Smith . ctx - the context
298fef3a512SBarry Smith 
299fef3a512SBarry Smith   Level: advanced
300fef3a512SBarry Smith 
30120f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateMatrix()`, `DMShellSetContext()`
302fef3a512SBarry Smith @*/
303d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetContext(DM dm, void *ctx)
304d71ae5a4SJacob Faibussowitsch {
305fef3a512SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
306fef3a512SBarry Smith   PetscBool isshell;
307fef3a512SBarry Smith 
308fef3a512SBarry Smith   PetscFunctionBegin;
309fef3a512SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3109566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
3117a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
3123ec1f749SStefano Zampini   *(void **)ctx = shell->ctx;
3133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
314fef3a512SBarry Smith }
315fef3a512SBarry Smith 
316fe1899a2SJed Brown /*@
31720f4b53cSBarry Smith   DMShellSetMatrix - sets a template matrix associated with the `DMSHELL`
318fe1899a2SJed Brown 
319fe1899a2SJed Brown   Collective
320fe1899a2SJed Brown 
3214165533cSJose E. Roman   Input Parameters:
32220f4b53cSBarry Smith + dm - `DMSHELL`
323fe1899a2SJed Brown - J  - template matrix
324fe1899a2SJed Brown 
325fe1899a2SJed Brown   Level: advanced
326fe1899a2SJed Brown 
32760225df5SJacob Faibussowitsch   Developer Notes:
32820f4b53cSBarry Smith   To avoid circular references, if `J` is already associated to the same `DM`, then `MatDuplicate`(`SHARE_NONZERO_PATTERN`) is called, followed by removing the `DM` reference from the private template.
32906f803f6SStefano Zampini 
33020f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateMatrix()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
331fe1899a2SJed Brown @*/
332d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetMatrix(DM dm, Mat J)
333d71ae5a4SJacob Faibussowitsch {
334fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
3358c87107bSJed Brown   PetscBool isshell;
33606f803f6SStefano Zampini   DM        mdm;
337fe1899a2SJed Brown 
338fe1899a2SJed Brown   PetscFunctionBegin;
3398c87107bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3408c87107bSJed Brown   PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
3419566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
3423ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
3433ba16761SJacob Faibussowitsch   if (J == shell->A) PetscFunctionReturn(PETSC_SUCCESS);
3449566063dSJacob Faibussowitsch   PetscCall(MatGetDM(J, &mdm));
3459566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)J));
3469566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&shell->A));
34706f803f6SStefano Zampini   if (mdm == dm) {
3489566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(J, MAT_SHARE_NONZERO_PATTERN, &shell->A));
3499566063dSJacob Faibussowitsch     PetscCall(MatSetDM(shell->A, NULL));
35006f803f6SStefano Zampini   } else shell->A = J;
3513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
352fe1899a2SJed Brown }
353fe1899a2SJed Brown 
354fe1899a2SJed Brown /*@C
35520f4b53cSBarry Smith   DMShellSetCreateMatrix - sets the routine to create a matrix associated with the `DMSHELL`
356fe1899a2SJed Brown 
35720f4b53cSBarry Smith   Logically Collective
358fe1899a2SJed Brown 
3594165533cSJose E. Roman   Input Parameters:
36020f4b53cSBarry Smith + dm   - the `DMSHELL`
361fe1899a2SJed Brown - func - the function to create a matrix
362fe1899a2SJed Brown 
363fe1899a2SJed Brown   Level: advanced
364fe1899a2SJed Brown 
36520f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateMatrix()`, `DMShellSetMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
366fe1899a2SJed Brown @*/
367d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateMatrix(DM dm, PetscErrorCode (*func)(DM, Mat *))
368d71ae5a4SJacob Faibussowitsch {
369fe1899a2SJed Brown   PetscFunctionBegin;
370fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
371fe1899a2SJed Brown   dm->ops->creatematrix = func;
3723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
373fe1899a2SJed Brown }
374fe1899a2SJed Brown 
375fe1899a2SJed Brown /*@
37620f4b53cSBarry Smith   DMShellSetGlobalVector - sets a template global vector associated with the `DMSHELL`
377fe1899a2SJed Brown 
37820f4b53cSBarry Smith   Logically Collective
379fe1899a2SJed Brown 
3804165533cSJose E. Roman   Input Parameters:
38120f4b53cSBarry Smith + dm - `DMSHELL`
382fe1899a2SJed Brown - X  - template vector
383fe1899a2SJed Brown 
384fe1899a2SJed Brown   Level: advanced
385fe1899a2SJed Brown 
38620f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateGlobalVector()`, `DMShellSetMatrix()`, `DMShellSetCreateGlobalVector()`
387fe1899a2SJed Brown @*/
388d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetGlobalVector(DM dm, Vec X)
389d71ae5a4SJacob Faibussowitsch {
390fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
3918c87107bSJed Brown   PetscBool isshell;
392cca7ec1eSBarry Smith   DM        vdm;
393fe1899a2SJed Brown 
394fe1899a2SJed Brown   PetscFunctionBegin;
3958c87107bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3968c87107bSJed Brown   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
3979566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
3983ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
3999566063dSJacob Faibussowitsch   PetscCall(VecGetDM(X, &vdm));
400cca7ec1eSBarry Smith   /*
401cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
402cca7ec1eSBarry Smith       with the same DM then the current base global vector for the DM is ok and if we replace it with the new one
403cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
404cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
405cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
406cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
407cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
408cca7ec1eSBarry Smith       for pointing out the problem.
409cca7ec1eSBarry Smith    */
4103ba16761SJacob Faibussowitsch   if (vdm == dm) PetscFunctionReturn(PETSC_SUCCESS);
4119566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)X));
4129566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xglobal));
413fe1899a2SJed Brown   shell->Xglobal = X;
414245d7360SStefano Zampini   PetscCall(DMClearGlobalVectors(dm));
415245d7360SStefano Zampini   PetscCall(DMClearNamedGlobalVectors(dm));
4163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
417fe1899a2SJed Brown }
418fe1899a2SJed Brown 
41904d741b1SMatthew G. Knepley /*@
42020f4b53cSBarry Smith   DMShellGetGlobalVector - Returns the template global vector associated with the `DMSHELL`, or `NULL` if it was not set
42104d741b1SMatthew G. Knepley 
42220f4b53cSBarry Smith   Not Collective
42304d741b1SMatthew G. Knepley 
4244165533cSJose E. Roman   Input Parameters:
42520f4b53cSBarry Smith + dm - `DMSHELL`
42604d741b1SMatthew G. Knepley - X  - template vector
42704d741b1SMatthew G. Knepley 
42804d741b1SMatthew G. Knepley   Level: advanced
42904d741b1SMatthew G. Knepley 
43020f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetGlobalVector()`, `DMShellSetCreateGlobalVector()`, `DMCreateGlobalVector()`
43104d741b1SMatthew G. Knepley @*/
432d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetGlobalVector(DM dm, Vec *X)
433d71ae5a4SJacob Faibussowitsch {
43404d741b1SMatthew G. Knepley   DM_Shell *shell = (DM_Shell *)dm->data;
43504d741b1SMatthew G. Knepley   PetscBool isshell;
43604d741b1SMatthew G. Knepley 
43704d741b1SMatthew G. Knepley   PetscFunctionBegin;
43804d741b1SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4394f572ea9SToby Isaac   PetscAssertPointer(X, 2);
4409566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
4413ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
44204d741b1SMatthew G. Knepley   *X = shell->Xglobal;
4433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
44404d741b1SMatthew G. Knepley }
44504d741b1SMatthew G. Knepley 
446fe1899a2SJed Brown /*@C
44720f4b53cSBarry Smith   DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the `DMSHELL`
448fe1899a2SJed Brown 
449fe1899a2SJed Brown   Logically Collective
450fe1899a2SJed Brown 
4514165533cSJose E. Roman   Input Parameters:
45220f4b53cSBarry Smith + dm   - the `DMSHELL`
453fe1899a2SJed Brown - func - the creation routine
454fe1899a2SJed Brown 
455fe1899a2SJed Brown   Level: advanced
456fe1899a2SJed Brown 
45720f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetGlobalVector()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
458fe1899a2SJed Brown @*/
459d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateGlobalVector(DM dm, PetscErrorCode (*func)(DM, Vec *))
460d71ae5a4SJacob Faibussowitsch {
461fe1899a2SJed Brown   PetscFunctionBegin;
462fe1899a2SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
463fe1899a2SJed Brown   dm->ops->createglobalvector = func;
4643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
465fe1899a2SJed Brown }
466fe1899a2SJed Brown 
467dc43b69eSJed Brown /*@
46820f4b53cSBarry Smith   DMShellSetLocalVector - sets a template local vector associated with the `DMSHELL`
469dc43b69eSJed Brown 
47020f4b53cSBarry Smith   Logically Collective
471dc43b69eSJed Brown 
4724165533cSJose E. Roman   Input Parameters:
47320f4b53cSBarry Smith + dm - `DMSHELL`
474dc43b69eSJed Brown - X  - template vector
475dc43b69eSJed Brown 
476dc43b69eSJed Brown   Level: advanced
477dc43b69eSJed Brown 
47820f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateLocalVector()`, `DMShellSetMatrix()`, `DMShellSetCreateLocalVector()`
479dc43b69eSJed Brown @*/
480d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalVector(DM dm, Vec X)
481d71ae5a4SJacob Faibussowitsch {
482dc43b69eSJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
483dc43b69eSJed Brown   PetscBool isshell;
484cca7ec1eSBarry Smith   DM        vdm;
485dc43b69eSJed Brown 
486dc43b69eSJed Brown   PetscFunctionBegin;
487dc43b69eSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
488dc43b69eSJed Brown   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
4899566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
4903ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
4919566063dSJacob Faibussowitsch   PetscCall(VecGetDM(X, &vdm));
492cca7ec1eSBarry Smith   /*
493cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
494cca7ec1eSBarry 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
495cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
496cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
497cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
498cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
499cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
500cca7ec1eSBarry Smith       for pointing out the problem.
501cca7ec1eSBarry Smith    */
5023ba16761SJacob Faibussowitsch   if (vdm == dm) PetscFunctionReturn(PETSC_SUCCESS);
5039566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)X));
5049566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xlocal));
505dc43b69eSJed Brown   shell->Xlocal = X;
506245d7360SStefano Zampini   PetscCall(DMClearLocalVectors(dm));
507245d7360SStefano Zampini   PetscCall(DMClearNamedLocalVectors(dm));
5083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
509dc43b69eSJed Brown }
510dc43b69eSJed Brown 
511dc43b69eSJed Brown /*@C
51220f4b53cSBarry Smith   DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the `DMSHELL`
513dc43b69eSJed Brown 
514dc43b69eSJed Brown   Logically Collective
515dc43b69eSJed Brown 
5164165533cSJose E. Roman   Input Parameters:
51720f4b53cSBarry Smith + dm   - the `DMSHELL`
518dc43b69eSJed Brown - func - the creation routine
519dc43b69eSJed Brown 
520dc43b69eSJed Brown   Level: advanced
521dc43b69eSJed Brown 
52220f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetLocalVector()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
523dc43b69eSJed Brown @*/
524d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateLocalVector(DM dm, PetscErrorCode (*func)(DM, Vec *))
525d71ae5a4SJacob Faibussowitsch {
526dc43b69eSJed Brown   PetscFunctionBegin;
527dc43b69eSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
528dc43b69eSJed Brown   dm->ops->createlocalvector = func;
5293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
530dc43b69eSJed Brown }
531dc43b69eSJed Brown 
5328339e6d0SRichard Tran Mills /*@C
5338339e6d0SRichard Tran Mills   DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter
5348339e6d0SRichard Tran Mills 
535d083f849SBarry Smith   Logically Collective on dm
5368339e6d0SRichard Tran Mills 
537*a4e35b19SJacob Faibussowitsch   Input Parameters:
53820f4b53cSBarry Smith + dm    - the `DMSHELL`
5398339e6d0SRichard Tran Mills . begin - the routine that begins the global to local scatter
5408339e6d0SRichard Tran Mills - end   - the routine that ends the global to local scatter
5418339e6d0SRichard Tran Mills 
5428339e6d0SRichard Tran Mills   Level: advanced
5438339e6d0SRichard Tran Mills 
54420f4b53cSBarry Smith   Note:
54520f4b53cSBarry Smith   If these functions are not provided but `DMShellSetGlobalToLocalVecScatter()` is called then
54620f4b53cSBarry Smith   `DMGlobalToLocalBeginDefaultShell()`/`DMGlobalToLocalEndDefaultShell()` are used to to perform the transfers
54720f4b53cSBarry Smith 
54820f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetLocalToGlobal()`, `DMGlobalToLocalBeginDefaultShell()`, `DMGlobalToLocalEndDefaultShell()`
5498339e6d0SRichard Tran Mills @*/
550d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetGlobalToLocal(DM dm, PetscErrorCode (*begin)(DM, Vec, InsertMode, Vec), PetscErrorCode (*end)(DM, Vec, InsertMode, Vec))
551d71ae5a4SJacob Faibussowitsch {
5528339e6d0SRichard Tran Mills   PetscFunctionBegin;
5532d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5548339e6d0SRichard Tran Mills   dm->ops->globaltolocalbegin = begin;
5558339e6d0SRichard Tran Mills   dm->ops->globaltolocalend   = end;
5563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5578339e6d0SRichard Tran Mills }
5588339e6d0SRichard Tran Mills 
5598339e6d0SRichard Tran Mills /*@C
5608339e6d0SRichard Tran Mills   DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter
5618339e6d0SRichard Tran Mills 
562d083f849SBarry Smith   Logically Collective on dm
5638339e6d0SRichard Tran Mills 
564*a4e35b19SJacob Faibussowitsch   Input Parameters:
56520f4b53cSBarry Smith + dm    - the `DMSHELL`
5668339e6d0SRichard Tran Mills . begin - the routine that begins the local to global scatter
5678339e6d0SRichard Tran Mills - end   - the routine that ends the local to global scatter
5688339e6d0SRichard Tran Mills 
5698339e6d0SRichard Tran Mills   Level: advanced
5708339e6d0SRichard Tran Mills 
57120f4b53cSBarry Smith   Note:
57220f4b53cSBarry Smith   If these functions are not provided but `DMShellSetLocalToGlobalVecScatter()` is called then
57320f4b53cSBarry Smith   `DMLocalToGlobalBeginDefaultShell()`/`DMLocalToGlobalEndDefaultShell()` are used to to perform the transfers
57420f4b53cSBarry Smith 
57520f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetGlobalToLocal()`
5768339e6d0SRichard Tran Mills @*/
577d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalToGlobal(DM dm, PetscErrorCode (*begin)(DM, Vec, InsertMode, Vec), PetscErrorCode (*end)(DM, Vec, InsertMode, Vec))
578d71ae5a4SJacob Faibussowitsch {
5798339e6d0SRichard Tran Mills   PetscFunctionBegin;
5802d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5818339e6d0SRichard Tran Mills   dm->ops->localtoglobalbegin = begin;
5828339e6d0SRichard Tran Mills   dm->ops->localtoglobalend   = end;
5833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5848339e6d0SRichard Tran Mills }
5858339e6d0SRichard Tran Mills 
586f3db62a7SRichard Tran Mills /*@C
587f3db62a7SRichard Tran Mills   DMShellSetLocalToLocal - Sets the routines used to perform a local to local scatter
588f3db62a7SRichard Tran Mills 
589d083f849SBarry Smith   Logically Collective on dm
590f3db62a7SRichard Tran Mills 
591*a4e35b19SJacob Faibussowitsch   Input Parameters:
59220f4b53cSBarry Smith + dm    - the `DMSHELL`
593f3db62a7SRichard Tran Mills . begin - the routine that begins the local to local scatter
594f3db62a7SRichard Tran Mills - end   - the routine that ends the local to local scatter
595f3db62a7SRichard Tran Mills 
596f3db62a7SRichard Tran Mills   Level: advanced
597f3db62a7SRichard Tran Mills 
59820f4b53cSBarry Smith   Note:
59920f4b53cSBarry Smith   If these functions are not provided but `DMShellSetLocalToLocalVecScatter()` is called then
60020f4b53cSBarry Smith   `DMLocalToLocalBeginDefaultShell()`/`DMLocalToLocalEndDefaultShell()` are used to to perform the transfers
60120f4b53cSBarry Smith 
60220f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetGlobalToLocal()`, `DMLocalToLocalBeginDefaultShell()`, `DMLocalToLocalEndDefaultShell()`
603f3db62a7SRichard Tran Mills @*/
604d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalToLocal(DM dm, PetscErrorCode (*begin)(DM, Vec, InsertMode, Vec), PetscErrorCode (*end)(DM, Vec, InsertMode, Vec))
605d71ae5a4SJacob Faibussowitsch {
606f3db62a7SRichard Tran Mills   PetscFunctionBegin;
6072d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
608f3db62a7SRichard Tran Mills   dm->ops->localtolocalbegin = begin;
609f3db62a7SRichard Tran Mills   dm->ops->localtolocalend   = end;
6103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
611f3db62a7SRichard Tran Mills }
612f3db62a7SRichard Tran Mills 
61381634712SRichard Tran Mills /*@
61420f4b53cSBarry Smith   DMShellSetGlobalToLocalVecScatter - Sets a `VecScatter` context for global to local communication
61581634712SRichard Tran Mills 
616d083f849SBarry Smith   Logically Collective on dm
61781634712SRichard Tran Mills 
618*a4e35b19SJacob Faibussowitsch   Input Parameters:
61920f4b53cSBarry Smith + dm   - the `DMSHELL`
62020f4b53cSBarry Smith - gtol - the global to local `VecScatter` context
62181634712SRichard Tran Mills 
62281634712SRichard Tran Mills   Level: advanced
62381634712SRichard Tran Mills 
62420f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetGlobalToLocal()`, `DMGlobalToLocalBeginDefaultShell()`, `DMGlobalToLocalEndDefaultShell()`
62581634712SRichard Tran Mills @*/
626d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter gtol)
627d71ae5a4SJacob Faibussowitsch {
62881634712SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
62981634712SRichard Tran Mills 
630b300e4a8SRichard Tran Mills   PetscFunctionBegin;
6312d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
63297929ea7SJunchao Zhang   PetscValidHeaderSpecific(gtol, PETSCSF_CLASSID, 2);
6339566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)gtol));
6349566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->gtol));
63581634712SRichard Tran Mills   shell->gtol = gtol;
6363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
63781634712SRichard Tran Mills }
63881634712SRichard Tran Mills 
639988ea7d6SRichard Tran Mills /*@
64020f4b53cSBarry Smith   DMShellSetLocalToGlobalVecScatter - Sets a` VecScatter` context for local to global communication
641988ea7d6SRichard Tran Mills 
642d083f849SBarry Smith   Logically Collective on dm
643988ea7d6SRichard Tran Mills 
644*a4e35b19SJacob Faibussowitsch   Input Parameters:
64520f4b53cSBarry Smith + dm   - the `DMSHELL`
64620f4b53cSBarry Smith - ltog - the local to global `VecScatter` context
647988ea7d6SRichard Tran Mills 
648988ea7d6SRichard Tran Mills   Level: advanced
649988ea7d6SRichard Tran Mills 
65020f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetLocalToGlobal()`, `DMLocalToGlobalBeginDefaultShell()`, `DMLocalToGlobalEndDefaultShell()`
651988ea7d6SRichard Tran Mills @*/
652d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM dm, VecScatter ltog)
653d71ae5a4SJacob Faibussowitsch {
654988ea7d6SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
655988ea7d6SRichard Tran Mills 
656988ea7d6SRichard Tran Mills   PetscFunctionBegin;
6572d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
65897929ea7SJunchao Zhang   PetscValidHeaderSpecific(ltog, PETSCSF_CLASSID, 2);
6599566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)ltog));
6609566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltog));
661988ea7d6SRichard Tran Mills   shell->ltog = ltog;
6623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
663988ea7d6SRichard Tran Mills }
664988ea7d6SRichard Tran Mills 
665f3db62a7SRichard Tran Mills /*@
66620f4b53cSBarry Smith   DMShellSetLocalToLocalVecScatter - Sets a `VecScatter` context for local to local communication
667f3db62a7SRichard Tran Mills 
66820f4b53cSBarry Smith   Logically Collective
669f3db62a7SRichard Tran Mills 
670*a4e35b19SJacob Faibussowitsch   Input Parameters:
67120f4b53cSBarry Smith + dm   - the `DMSHELL`
67220f4b53cSBarry Smith - ltol - the local to local `VecScatter` context
673f3db62a7SRichard Tran Mills 
674f3db62a7SRichard Tran Mills   Level: advanced
675f3db62a7SRichard Tran Mills 
67620f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetLocalToLocal()`, `DMLocalToLocalBeginDefaultShell()`, `DMLocalToLocalEndDefaultShell()`
677f3db62a7SRichard Tran Mills @*/
678d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetLocalToLocalVecScatter(DM dm, VecScatter ltol)
679d71ae5a4SJacob Faibussowitsch {
680f3db62a7SRichard Tran Mills   DM_Shell *shell = (DM_Shell *)dm->data;
681f3db62a7SRichard Tran Mills 
682f3db62a7SRichard Tran Mills   PetscFunctionBegin;
6832d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
68497929ea7SJunchao Zhang   PetscValidHeaderSpecific(ltol, PETSCSF_CLASSID, 2);
6859566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)ltol));
6869566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltol));
687f3db62a7SRichard Tran Mills   shell->ltol = ltol;
6883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
689f3db62a7SRichard Tran Mills }
690f3db62a7SRichard Tran Mills 
6919bf9660cSLawrence Mitchell /*@C
69220f4b53cSBarry Smith   DMShellSetCoarsen - Set the routine used to coarsen the `DMSHELL`
6939bf9660cSLawrence Mitchell 
69420f4b53cSBarry Smith   Logically Collective
6959bf9660cSLawrence Mitchell 
696*a4e35b19SJacob Faibussowitsch   Input Parameters:
69720f4b53cSBarry Smith + dm      - the `DMSHELL`
69820f4b53cSBarry Smith - coarsen - the routine that coarsens the `DM`
6999bf9660cSLawrence Mitchell 
7009bf9660cSLawrence Mitchell   Level: advanced
7019bf9660cSLawrence Mitchell 
70220f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetRefine()`, `DMCoarsen()`, `DMShellGetCoarsen()`, `DMShellSetContext()`, `DMShellGetContext()`
7039bf9660cSLawrence Mitchell @*/
704d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCoarsen(DM dm, PetscErrorCode (*coarsen)(DM, MPI_Comm, DM *))
705d71ae5a4SJacob Faibussowitsch {
706f572501eSLawrence Mitchell   PetscBool isshell;
707f572501eSLawrence Mitchell 
708f572501eSLawrence Mitchell   PetscFunctionBegin;
709f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7109566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
7113ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
712f572501eSLawrence Mitchell   dm->ops->coarsen = coarsen;
7133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
714f572501eSLawrence Mitchell }
715f572501eSLawrence Mitchell 
7169bf9660cSLawrence Mitchell /*@C
71720f4b53cSBarry Smith   DMShellGetCoarsen - Get the routine used to coarsen the `DMSHELL`
7184363ddcaSBoris Boutkov 
71920f4b53cSBarry Smith   Logically Collective
7204363ddcaSBoris Boutkov 
7214165533cSJose E. Roman   Input Parameter:
72220f4b53cSBarry Smith . dm - the `DMSHELL`
7234363ddcaSBoris Boutkov 
7244165533cSJose E. Roman   Output Parameter:
72520f4b53cSBarry Smith . coarsen - the routine that coarsens the `DM`
7264363ddcaSBoris Boutkov 
7274363ddcaSBoris Boutkov   Level: advanced
7284363ddcaSBoris Boutkov 
72920f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCoarsen()`, `DMCoarsen()`, `DMShellSetRefine()`, `DMRefine()`
7304363ddcaSBoris Boutkov @*/
731d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCoarsen(DM dm, PetscErrorCode (**coarsen)(DM, MPI_Comm, DM *))
732d71ae5a4SJacob Faibussowitsch {
7334363ddcaSBoris Boutkov   PetscBool isshell;
7344363ddcaSBoris Boutkov 
7354363ddcaSBoris Boutkov   PetscFunctionBegin;
7364363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7379566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
7387a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
7394363ddcaSBoris Boutkov   *coarsen = dm->ops->coarsen;
7403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7414363ddcaSBoris Boutkov }
7424363ddcaSBoris Boutkov 
7434363ddcaSBoris Boutkov /*@C
74420f4b53cSBarry Smith   DMShellSetRefine - Set the routine used to refine the `DMSHELL`
7459bf9660cSLawrence Mitchell 
74620f4b53cSBarry Smith   Logically Collective
7479bf9660cSLawrence Mitchell 
748*a4e35b19SJacob Faibussowitsch   Input Parameters:
74920f4b53cSBarry Smith + dm     - the `DMSHELL`
75020f4b53cSBarry Smith - refine - the routine that refines the `DM`
7519bf9660cSLawrence Mitchell 
7529bf9660cSLawrence Mitchell   Level: advanced
7539bf9660cSLawrence Mitchell 
75420f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCoarsen()`, `DMRefine()`, `DMShellGetRefine()`, `DMShellSetContext()`, `DMShellGetContext()`
7559bf9660cSLawrence Mitchell @*/
756d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetRefine(DM dm, PetscErrorCode (*refine)(DM, MPI_Comm, DM *))
757d71ae5a4SJacob Faibussowitsch {
758f572501eSLawrence Mitchell   PetscBool isshell;
759f572501eSLawrence Mitchell 
760f572501eSLawrence Mitchell   PetscFunctionBegin;
761f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7629566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
7633ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
764f572501eSLawrence Mitchell   dm->ops->refine = refine;
7653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
766f572501eSLawrence Mitchell }
767f572501eSLawrence Mitchell 
7689bf9660cSLawrence Mitchell /*@C
76920f4b53cSBarry Smith   DMShellGetRefine - Get the routine used to refine the `DMSHELL`
7704363ddcaSBoris Boutkov 
77120f4b53cSBarry Smith   Logically Collective
7724363ddcaSBoris Boutkov 
7734165533cSJose E. Roman   Input Parameter:
77420f4b53cSBarry Smith . dm - the `DMSHELL`
7754363ddcaSBoris Boutkov 
7764165533cSJose E. Roman   Output Parameter:
77720f4b53cSBarry Smith . refine - the routine that refines the `DM`
7784363ddcaSBoris Boutkov 
7794363ddcaSBoris Boutkov   Level: advanced
7804363ddcaSBoris Boutkov 
78120f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCoarsen()`, `DMCoarsen()`, `DMShellSetRefine()`, `DMRefine()`
7824363ddcaSBoris Boutkov @*/
783d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetRefine(DM dm, PetscErrorCode (**refine)(DM, MPI_Comm, DM *))
784d71ae5a4SJacob Faibussowitsch {
7854363ddcaSBoris Boutkov   PetscBool isshell;
7864363ddcaSBoris Boutkov 
7874363ddcaSBoris Boutkov   PetscFunctionBegin;
7884363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7899566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
7907a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
7914363ddcaSBoris Boutkov   *refine = dm->ops->refine;
7923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7934363ddcaSBoris Boutkov }
7944363ddcaSBoris Boutkov 
7954363ddcaSBoris Boutkov /*@C
7969bf9660cSLawrence Mitchell   DMShellSetCreateInterpolation - Set the routine used to create the interpolation operator
7979bf9660cSLawrence Mitchell 
79820f4b53cSBarry Smith   Logically Collective
7999bf9660cSLawrence Mitchell 
800*a4e35b19SJacob Faibussowitsch   Input Parameters:
80120f4b53cSBarry Smith + dm     - the `DMSHELL`
8029bf9660cSLawrence Mitchell - interp - the routine to create the interpolation
8039bf9660cSLawrence Mitchell 
8049bf9660cSLawrence Mitchell   Level: advanced
8059bf9660cSLawrence Mitchell 
80620f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateInterpolation()`, `DMShellSetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
8079bf9660cSLawrence Mitchell @*/
808d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateInterpolation(DM dm, PetscErrorCode (*interp)(DM, DM, Mat *, Vec *))
809d71ae5a4SJacob Faibussowitsch {
810f572501eSLawrence Mitchell   PetscBool isshell;
811f572501eSLawrence Mitchell 
812f572501eSLawrence Mitchell   PetscFunctionBegin;
813f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8149566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
8153ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
816f572501eSLawrence Mitchell   dm->ops->createinterpolation = interp;
8173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
818f572501eSLawrence Mitchell }
819f572501eSLawrence Mitchell 
8203ad4599aSBarry Smith /*@C
8214363ddcaSBoris Boutkov   DMShellGetCreateInterpolation - Get the routine used to create the interpolation operator
8224363ddcaSBoris Boutkov 
82320f4b53cSBarry Smith   Logically Collective
8244363ddcaSBoris Boutkov 
8254165533cSJose E. Roman   Input Parameter:
82620f4b53cSBarry Smith . dm - the `DMSHELL`
827a4a986ddSBoris Boutkov 
8284165533cSJose E. Roman   Output Parameter:
8294165533cSJose E. Roman . interp - the routine to create the interpolation
8304363ddcaSBoris Boutkov 
8314363ddcaSBoris Boutkov   Level: advanced
8324363ddcaSBoris Boutkov 
83320f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellGetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
8344363ddcaSBoris Boutkov @*/
835d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCreateInterpolation(DM dm, PetscErrorCode (**interp)(DM, DM, Mat *, Vec *))
836d71ae5a4SJacob Faibussowitsch {
8374363ddcaSBoris Boutkov   PetscBool isshell;
8384363ddcaSBoris Boutkov 
8394363ddcaSBoris Boutkov   PetscFunctionBegin;
8404363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8419566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
8427a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
8434363ddcaSBoris Boutkov   *interp = dm->ops->createinterpolation;
8443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8454363ddcaSBoris Boutkov }
8464363ddcaSBoris Boutkov 
8474363ddcaSBoris Boutkov /*@C
8483ad4599aSBarry Smith   DMShellSetCreateRestriction - Set the routine used to create the restriction operator
8493ad4599aSBarry Smith 
85020f4b53cSBarry Smith   Logically Collective
8513ad4599aSBarry Smith 
852*a4e35b19SJacob Faibussowitsch   Input Parameters:
85320f4b53cSBarry Smith + dm          - the `DMSHELL`
85460225df5SJacob Faibussowitsch - restriction - the routine to create the restriction
8553ad4599aSBarry Smith 
8563ad4599aSBarry Smith   Level: advanced
8573ad4599aSBarry Smith 
85820f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
8593ad4599aSBarry Smith @*/
860d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateRestriction(DM dm, PetscErrorCode (*restriction)(DM, DM, Mat *))
861d71ae5a4SJacob Faibussowitsch {
8623ad4599aSBarry Smith   PetscBool isshell;
8633ad4599aSBarry Smith 
8643ad4599aSBarry Smith   PetscFunctionBegin;
8653ad4599aSBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8669566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
8673ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
8683ad4599aSBarry Smith   dm->ops->createrestriction = restriction;
8693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8703ad4599aSBarry Smith }
8713ad4599aSBarry Smith 
8729bf9660cSLawrence Mitchell /*@C
8734363ddcaSBoris Boutkov   DMShellGetCreateRestriction - Get the routine used to create the restriction operator
8744363ddcaSBoris Boutkov 
87520f4b53cSBarry Smith   Logically Collective
8764363ddcaSBoris Boutkov 
8774165533cSJose E. Roman   Input Parameter:
87820f4b53cSBarry Smith . dm - the `DMSHELL`
879a4a986ddSBoris Boutkov 
8804165533cSJose E. Roman   Output Parameter:
8814165533cSJose E. Roman . restriction - the routine to create the restriction
8824363ddcaSBoris Boutkov 
8834363ddcaSBoris Boutkov   Level: advanced
8844363ddcaSBoris Boutkov 
88520f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellSetContext()`, `DMShellGetContext()`
8864363ddcaSBoris Boutkov @*/
887d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCreateRestriction(DM dm, PetscErrorCode (**restriction)(DM, DM, Mat *))
888d71ae5a4SJacob Faibussowitsch {
8894363ddcaSBoris Boutkov   PetscBool isshell;
8904363ddcaSBoris Boutkov 
8914363ddcaSBoris Boutkov   PetscFunctionBegin;
8924363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8939566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
8947a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
8954363ddcaSBoris Boutkov   *restriction = dm->ops->createrestriction;
8963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8974363ddcaSBoris Boutkov }
8984363ddcaSBoris Boutkov 
8994363ddcaSBoris Boutkov /*@C
9009bf9660cSLawrence Mitchell   DMShellSetCreateInjection - Set the routine used to create the injection operator
9019bf9660cSLawrence Mitchell 
90220f4b53cSBarry Smith   Logically Collective
9039bf9660cSLawrence Mitchell 
9044165533cSJose E. Roman   Input Parameters:
90520f4b53cSBarry Smith + dm     - the `DMSHELL`
9069bf9660cSLawrence Mitchell - inject - the routine to create the injection
9079bf9660cSLawrence Mitchell 
9089bf9660cSLawrence Mitchell   Level: advanced
9099bf9660cSLawrence Mitchell 
91020f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellSetCreateInterpolation()`, `DMCreateInjection()`, `DMShellGetCreateInjection()`, `DMShellSetContext()`, `DMShellGetContext()`
9119bf9660cSLawrence Mitchell @*/
912d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateInjection(DM dm, PetscErrorCode (*inject)(DM, DM, Mat *))
913d71ae5a4SJacob Faibussowitsch {
914f572501eSLawrence Mitchell   PetscBool isshell;
915f572501eSLawrence Mitchell 
916f572501eSLawrence Mitchell   PetscFunctionBegin;
917f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9189566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
9193ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
9205a84ad33SLisandro Dalcin   dm->ops->createinjection = inject;
9213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
922f572501eSLawrence Mitchell }
923f572501eSLawrence Mitchell 
9244363ddcaSBoris Boutkov /*@C
9254363ddcaSBoris Boutkov   DMShellGetCreateInjection - Get the routine used to create the injection operator
9264363ddcaSBoris Boutkov 
92720f4b53cSBarry Smith   Logically Collective
9284363ddcaSBoris Boutkov 
9294165533cSJose E. Roman   Input Parameter:
93020f4b53cSBarry Smith . dm - the `DMSHELL`
931a4a986ddSBoris Boutkov 
9324165533cSJose E. Roman   Output Parameter:
9334165533cSJose E. Roman . inject - the routine to create the injection
9344363ddcaSBoris Boutkov 
9354363ddcaSBoris Boutkov   Level: advanced
9364363ddcaSBoris Boutkov 
93720f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMShellGetCreateInterpolation()`, `DMCreateInjection()`, `DMShellSetContext()`, `DMShellGetContext()`
9384363ddcaSBoris Boutkov @*/
939d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCreateInjection(DM dm, PetscErrorCode (**inject)(DM, DM, Mat *))
940d71ae5a4SJacob Faibussowitsch {
9414363ddcaSBoris Boutkov   PetscBool isshell;
9424363ddcaSBoris Boutkov 
9434363ddcaSBoris Boutkov   PetscFunctionBegin;
9444363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9459566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
9467a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
9475a84ad33SLisandro Dalcin   *inject = dm->ops->createinjection;
9483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9494363ddcaSBoris Boutkov }
9504363ddcaSBoris Boutkov 
9519bf9660cSLawrence Mitchell /*@C
95220f4b53cSBarry Smith   DMShellSetCreateFieldDecomposition - Set the routine used to create a decomposition of fields for the `DMSHELL`
9539bf9660cSLawrence Mitchell 
95420f4b53cSBarry Smith   Logically Collective
9559bf9660cSLawrence Mitchell 
9564165533cSJose E. Roman   Input Parameters:
95720f4b53cSBarry Smith + dm     - the `DMSHELL`
9589bf9660cSLawrence Mitchell - decomp - the routine to create the decomposition
9599bf9660cSLawrence Mitchell 
9609bf9660cSLawrence Mitchell   Level: advanced
9619bf9660cSLawrence Mitchell 
96220f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateFieldDecomposition()`, `DMShellSetContext()`, `DMShellGetContext()`
9639bf9660cSLawrence Mitchell @*/
964d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateFieldDecomposition(DM dm, PetscErrorCode (*decomp)(DM, PetscInt *, char ***, IS **, DM **))
965d71ae5a4SJacob Faibussowitsch {
9665e2259d5SLawrence Mitchell   PetscBool isshell;
9675e2259d5SLawrence Mitchell 
9685e2259d5SLawrence Mitchell   PetscFunctionBegin;
9695e2259d5SLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9709566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
9713ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
9725e2259d5SLawrence Mitchell   dm->ops->createfielddecomposition = decomp;
9733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9745e2259d5SLawrence Mitchell }
9755e2259d5SLawrence Mitchell 
976c00061e5SLawrence Mitchell /*@C
97720f4b53cSBarry Smith   DMShellSetCreateDomainDecomposition - Set the routine used to create a domain decomposition for the `DMSHELL`
978e734121bSPatrick Farrell 
97920f4b53cSBarry Smith   Logically Collective
980e734121bSPatrick Farrell 
9814165533cSJose E. Roman   Input Parameters:
98220f4b53cSBarry Smith + dm     - the `DMSHELL`
983e734121bSPatrick Farrell - decomp - the routine to create the decomposition
984e734121bSPatrick Farrell 
985e734121bSPatrick Farrell   Level: advanced
986e734121bSPatrick Farrell 
98720f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateDomainDecomposition()`, `DMShellSetContext()`, `DMShellGetContext()`
988e734121bSPatrick Farrell @*/
989d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateDomainDecomposition(DM dm, PetscErrorCode (*decomp)(DM, PetscInt *, char ***, IS **, IS **, DM **))
990d71ae5a4SJacob Faibussowitsch {
991e734121bSPatrick Farrell   PetscBool isshell;
992e734121bSPatrick Farrell 
993e734121bSPatrick Farrell   PetscFunctionBegin;
994e734121bSPatrick Farrell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9959566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
9963ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
997e734121bSPatrick Farrell   dm->ops->createdomaindecomposition = decomp;
9983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
999e734121bSPatrick Farrell }
1000e734121bSPatrick Farrell 
1001e734121bSPatrick Farrell /*@C
100220f4b53cSBarry Smith   DMShellSetCreateDomainDecompositionScatters - Set the routine used to create the scatter contexts for domain decomposition with a `DMSHELL`
1003eef9d6cdSPatrick Farrell 
100420f4b53cSBarry Smith   Logically Collective
1005eef9d6cdSPatrick Farrell 
10064165533cSJose E. Roman   Input Parameters:
100720f4b53cSBarry Smith + dm      - the `DMSHELL`
1008eef9d6cdSPatrick Farrell - scatter - the routine to create the scatters
1009eef9d6cdSPatrick Farrell 
1010eef9d6cdSPatrick Farrell   Level: advanced
1011eef9d6cdSPatrick Farrell 
101220f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateDomainDecompositionScatters()`, `DMShellSetContext()`, `DMShellGetContext()`
1013eef9d6cdSPatrick Farrell @*/
1014d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateDomainDecompositionScatters(DM dm, PetscErrorCode (*scatter)(DM, PetscInt, DM *, VecScatter **, VecScatter **, VecScatter **))
1015d71ae5a4SJacob Faibussowitsch {
1016eef9d6cdSPatrick Farrell   PetscBool isshell;
1017eef9d6cdSPatrick Farrell 
1018eef9d6cdSPatrick Farrell   PetscFunctionBegin;
1019eef9d6cdSPatrick Farrell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10209566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
10213ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
1022eef9d6cdSPatrick Farrell   dm->ops->createddscatters = scatter;
10233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1024eef9d6cdSPatrick Farrell }
1025eef9d6cdSPatrick Farrell 
1026eef9d6cdSPatrick Farrell /*@C
102720f4b53cSBarry Smith   DMShellSetCreateSubDM - Set the routine used to create a sub `DM` from the `DMSHELL`
1028c00061e5SLawrence Mitchell 
102920f4b53cSBarry Smith   Logically Collective
1030c00061e5SLawrence Mitchell 
10314165533cSJose E. Roman   Input Parameters:
103220f4b53cSBarry Smith + dm    - the `DMSHELL`
1033c00061e5SLawrence Mitchell - subdm - the routine to create the decomposition
1034c00061e5SLawrence Mitchell 
1035c00061e5SLawrence Mitchell   Level: advanced
1036c00061e5SLawrence Mitchell 
103720f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateSubDM()`, `DMShellGetCreateSubDM()`, `DMShellSetContext()`, `DMShellGetContext()`
1038c00061e5SLawrence Mitchell @*/
1039d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellSetCreateSubDM(DM dm, PetscErrorCode (*subdm)(DM, PetscInt, const PetscInt[], IS *, DM *))
1040d71ae5a4SJacob Faibussowitsch {
1041c00061e5SLawrence Mitchell   PetscBool isshell;
1042c00061e5SLawrence Mitchell 
1043c00061e5SLawrence Mitchell   PetscFunctionBegin;
1044c00061e5SLawrence Mitchell   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10459566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
10463ba16761SJacob Faibussowitsch   if (!isshell) PetscFunctionReturn(PETSC_SUCCESS);
1047c00061e5SLawrence Mitchell   dm->ops->createsubdm = subdm;
10483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1049c00061e5SLawrence Mitchell }
1050c00061e5SLawrence Mitchell 
10514363ddcaSBoris Boutkov /*@C
105220f4b53cSBarry Smith   DMShellGetCreateSubDM - Get the routine used to create a sub DM from the `DMSHELL`
10534363ddcaSBoris Boutkov 
105420f4b53cSBarry Smith   Logically Collective
10554363ddcaSBoris Boutkov 
10564165533cSJose E. Roman   Input Parameter:
105720f4b53cSBarry Smith . dm - the `DMSHELL`
1058a4a986ddSBoris Boutkov 
10594165533cSJose E. Roman   Output Parameter:
10604165533cSJose E. Roman . subdm - the routine to create the decomposition
10614363ddcaSBoris Boutkov 
10624363ddcaSBoris Boutkov   Level: advanced
10634363ddcaSBoris Boutkov 
106420f4b53cSBarry Smith .seealso: `DM`, `DMSHELL`, `DMCreateSubDM()`, `DMShellSetCreateSubDM()`, `DMShellSetContext()`, `DMShellGetContext()`
10654363ddcaSBoris Boutkov @*/
1066d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellGetCreateSubDM(DM dm, PetscErrorCode (**subdm)(DM, PetscInt, const PetscInt[], IS *, DM *))
1067d71ae5a4SJacob Faibussowitsch {
10684363ddcaSBoris Boutkov   PetscBool isshell;
10694363ddcaSBoris Boutkov 
10704363ddcaSBoris Boutkov   PetscFunctionBegin;
10714363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10729566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
10737a8be351SBarry Smith   PetscCheck(isshell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only use with DMSHELL type DMs");
10744363ddcaSBoris Boutkov   *subdm = dm->ops->createsubdm;
10753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10764363ddcaSBoris Boutkov }
10774363ddcaSBoris Boutkov 
1078d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDestroy_Shell(DM dm)
1079d71ae5a4SJacob Faibussowitsch {
1080fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell *)dm->data;
1081fe1899a2SJed Brown 
1082fe1899a2SJed Brown   PetscFunctionBegin;
108309904cd0SBarry Smith   if (shell->destroyctx) PetscCallBack("Destroy Context", (*shell->destroyctx)(shell->ctx));
10849566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&shell->A));
10859566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xglobal));
10869566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xlocal));
10879566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->gtol));
10889566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltog));
10899566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltol));
10907b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
10919566063dSJacob Faibussowitsch   PetscCall(PetscFree(shell));
10923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1093fe1899a2SJed Brown }
1094fe1899a2SJed Brown 
1095d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMView_Shell(DM dm, PetscViewer v)
1096d71ae5a4SJacob Faibussowitsch {
10972d53ad75SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
10982d53ad75SBarry Smith 
10992d53ad75SBarry Smith   PetscFunctionBegin;
110001f8681bSStefano Zampini   if (shell->Xglobal) PetscCall(VecView(shell->Xglobal, v));
11013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11022d53ad75SBarry Smith }
11032d53ad75SBarry Smith 
1104d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLoad_Shell(DM dm, PetscViewer v)
1105d71ae5a4SJacob Faibussowitsch {
11062d53ad75SBarry Smith   DM_Shell *shell = (DM_Shell *)dm->data;
11072d53ad75SBarry Smith 
11082d53ad75SBarry Smith   PetscFunctionBegin;
11099566063dSJacob Faibussowitsch   PetscCall(VecCreate(PetscObjectComm((PetscObject)dm), &shell->Xglobal));
11109566063dSJacob Faibussowitsch   PetscCall(VecLoad(shell->Xglobal, v));
11113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11122d53ad75SBarry Smith }
1113fe1899a2SJed Brown 
1114d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSubDM_Shell(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm)
1115d71ae5a4SJacob Faibussowitsch {
11166e44b4cfSMatthew G. Knepley   PetscFunctionBegin;
11179566063dSJacob Faibussowitsch   if (subdm) PetscCall(DMShellCreate(PetscObjectComm((PetscObject)dm), subdm));
11189566063dSJacob Faibussowitsch   PetscCall(DMCreateSectionSubDM(dm, numFields, fields, is, subdm));
11193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11206e44b4cfSMatthew G. Knepley }
11216e44b4cfSMatthew G. Knepley 
1122d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm)
1123d71ae5a4SJacob Faibussowitsch {
1124fe1899a2SJed Brown   DM_Shell *shell;
1125fe1899a2SJed Brown 
1126fe1899a2SJed Brown   PetscFunctionBegin;
11274dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&shell));
11288c87107bSJed Brown   dm->data = shell;
1129fe1899a2SJed Brown 
11308c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
11318c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
1132dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
11338c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
11342d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
11352d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
11367a108d1dSBarry Smith   dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell;
11377a108d1dSBarry Smith   dm->ops->globaltolocalend   = DMGlobalToLocalEndDefaultShell;
113855daaa54SRichard Tran Mills   dm->ops->localtoglobalbegin = DMLocalToGlobalBeginDefaultShell;
113955daaa54SRichard Tran Mills   dm->ops->localtoglobalend   = DMLocalToGlobalEndDefaultShell;
114063731094SRichard Tran Mills   dm->ops->localtolocalbegin  = DMLocalToLocalBeginDefaultShell;
114163731094SRichard Tran Mills   dm->ops->localtolocalend    = DMLocalToLocalEndDefaultShell;
11426e44b4cfSMatthew G. Knepley   dm->ops->createsubdm        = DMCreateSubDM_Shell;
11439566063dSJacob Faibussowitsch   PetscCall(DMSetMatType(dm, MATDENSE));
11443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1145fe1899a2SJed Brown }
1146fe1899a2SJed Brown 
1147fe1899a2SJed Brown /*@
114820f4b53cSBarry Smith   DMShellCreate - Creates a `DMSHELL` object, used to manage user-defined problem data
1149fe1899a2SJed Brown 
1150d083f849SBarry Smith   Collective
1151fe1899a2SJed Brown 
1152fe1899a2SJed Brown   Input Parameter:
1153fe1899a2SJed Brown . comm - the processors that will share the global vector
1154fe1899a2SJed Brown 
11552fe279fdSBarry Smith   Output Parameter:
115660225df5SJacob Faibussowitsch . dm - the `DMSHELL`
1157fe1899a2SJed Brown 
1158fe1899a2SJed Brown   Level: advanced
1159fe1899a2SJed Brown 
1160*a4e35b19SJacob Faibussowitsch .seealso: `DMDestroy()`, `DMCreateGlobalVector()`, `DMCreateLocalVector()`, `DMShellSetContext()`, `DMShellGetContext()`
1161fe1899a2SJed Brown @*/
1162d71ae5a4SJacob Faibussowitsch PetscErrorCode DMShellCreate(MPI_Comm comm, DM *dm)
1163d71ae5a4SJacob Faibussowitsch {
1164fe1899a2SJed Brown   PetscFunctionBegin;
11654f572ea9SToby Isaac   PetscAssertPointer(dm, 2);
11669566063dSJacob Faibussowitsch   PetscCall(DMCreate(comm, dm));
11679566063dSJacob Faibussowitsch   PetscCall(DMSetType(*dm, DMSHELL));
11689566063dSJacob Faibussowitsch   PetscCall(DMSetUp(*dm));
11693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1170fe1899a2SJed Brown }
1171