xref: /petsc/src/dm/impls/shell/dmshell.c (revision 01f8681b6f46fcda0abd7dd652a54c7dfe8b5224)
1fe1899a2SJed Brown #include <petscdmshell.h>       /*I    "petscdmshell.h"  I*/
207475bc1SBarry Smith #include <petscmat.h>
3af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
4fe1899a2SJed Brown 
5fe1899a2SJed Brown typedef struct  {
6fe1899a2SJed Brown   Vec        Xglobal;
7dc43b69eSJed Brown   Vec        Xlocal;
8fe1899a2SJed Brown   Mat        A;
9a94b16f6SRichard Tran Mills   VecScatter gtol;
10a94b16f6SRichard Tran Mills   VecScatter ltog;
11f089877aSRichard Tran Mills   VecScatter ltol;
12fef3a512SBarry Smith   void       *ctx;
13fe1899a2SJed Brown } DM_Shell;
14fe1899a2SJed Brown 
157a108d1dSBarry Smith /*@
167a108d1dSBarry Smith    DMGlobalToLocalBeginDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to begin a global to local scatter
178d359177SBarry Smith    Collective
188d359177SBarry Smith 
194165533cSJose E. Roman    Input Parameters:
208d359177SBarry Smith +  dm - shell DM
218d359177SBarry Smith .  g - global vector
228d359177SBarry Smith .  mode - InsertMode
238d359177SBarry Smith -  l - local vector
248d359177SBarry Smith 
257a108d1dSBarry Smith    Level: advanced
268d359177SBarry Smith 
277a108d1dSBarry Smith    Note:  This is not normally called directly by user code, generally user code calls DMGlobalToLocalBegin() and DMGlobalToLocalEnd(). If the user provides their own custom routines to DMShellSetLocalToGlobal() then those routines might have reason to call this function.
287a108d1dSBarry Smith 
29db781477SPatrick Sanan .seealso: `DMGlobalToLocalEndDefaultShell()`
308d359177SBarry Smith @*/
317a108d1dSBarry Smith PetscErrorCode DMGlobalToLocalBeginDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
328d359177SBarry Smith {
338d359177SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
348d359177SBarry Smith 
358d359177SBarry Smith   PetscFunctionBegin;
367a8be351SBarry Smith   PetscCheck(shell->gtol,((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
379566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->gtol,g,l,mode,SCATTER_FORWARD));
388d359177SBarry Smith   PetscFunctionReturn(0);
398d359177SBarry Smith }
408d359177SBarry Smith 
417a108d1dSBarry Smith /*@
427a108d1dSBarry Smith    DMGlobalToLocalEndDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to end a global to local scatter
438d359177SBarry Smith    Collective
448d359177SBarry Smith 
454165533cSJose E. Roman    Input Parameters:
468d359177SBarry Smith +  dm - shell DM
478d359177SBarry Smith .  g - global vector
488d359177SBarry Smith .  mode - InsertMode
498d359177SBarry Smith -  l - local vector
508d359177SBarry Smith 
517a108d1dSBarry Smith    Level: advanced
528d359177SBarry Smith 
53db781477SPatrick Sanan .seealso: `DMGlobalToLocalBeginDefaultShell()`
548d359177SBarry Smith @*/
557a108d1dSBarry Smith PetscErrorCode DMGlobalToLocalEndDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
568d359177SBarry Smith {
578d359177SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
588d359177SBarry Smith 
598d359177SBarry Smith   PetscFunctionBegin;
607a8be351SBarry Smith    PetscCheck(shell->gtol,((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
619566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->gtol,g,l,mode,SCATTER_FORWARD));
628d359177SBarry Smith   PetscFunctionReturn(0);
638d359177SBarry Smith }
648d359177SBarry Smith 
65c5076b69SRichard Tran Mills /*@
66c5076b69SRichard Tran Mills    DMLocalToGlobalBeginDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to begin a local to global scatter
67c5076b69SRichard Tran Mills    Collective
68c5076b69SRichard Tran Mills 
694165533cSJose E. Roman    Input Parameters:
70c5076b69SRichard Tran Mills +  dm - shell DM
71c5076b69SRichard Tran Mills .  l - local vector
72c5076b69SRichard Tran Mills .  mode - InsertMode
73c5076b69SRichard Tran Mills -  g - global vector
74c5076b69SRichard Tran Mills 
75c5076b69SRichard Tran Mills    Level: advanced
76c5076b69SRichard Tran Mills 
77c5076b69SRichard Tran Mills    Note:  This is not normally called directly by user code, generally user code calls DMLocalToGlobalBegin() and DMLocalToGlobalEnd(). If the user provides their own custom routines to DMShellSetLocalToGlobal() then those routines might have reason to call this function.
78c5076b69SRichard Tran Mills 
79db781477SPatrick Sanan .seealso: `DMLocalToGlobalEndDefaultShell()`
80c5076b69SRichard Tran Mills @*/
81c5076b69SRichard Tran Mills PetscErrorCode DMLocalToGlobalBeginDefaultShell(DM dm,Vec l,InsertMode mode,Vec g)
82c5076b69SRichard Tran Mills {
83c5076b69SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
84c5076b69SRichard Tran Mills 
85c5076b69SRichard Tran Mills   PetscFunctionBegin;
867a8be351SBarry Smith   PetscCheck(shell->ltog,((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
879566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->ltog,l,g,mode,SCATTER_FORWARD));
88c5076b69SRichard Tran Mills   PetscFunctionReturn(0);
89c5076b69SRichard Tran Mills }
90c5076b69SRichard Tran Mills 
91c5076b69SRichard Tran Mills /*@
92c5076b69SRichard Tran Mills    DMLocalToGlobalEndDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to end a local to global scatter
93c5076b69SRichard Tran Mills    Collective
94c5076b69SRichard Tran Mills 
954165533cSJose E. Roman    Input Parameters:
96c5076b69SRichard Tran Mills +  dm - shell DM
97c5076b69SRichard Tran Mills .  l - local vector
98c5076b69SRichard Tran Mills .  mode - InsertMode
99c5076b69SRichard Tran Mills -  g - global vector
100c5076b69SRichard Tran Mills 
101c5076b69SRichard Tran Mills    Level: advanced
102c5076b69SRichard Tran Mills 
103db781477SPatrick Sanan .seealso: `DMLocalToGlobalBeginDefaultShell()`
104c5076b69SRichard Tran Mills @*/
105c5076b69SRichard Tran Mills PetscErrorCode DMLocalToGlobalEndDefaultShell(DM dm,Vec l,InsertMode mode,Vec g)
106c5076b69SRichard Tran Mills {
107c5076b69SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
108c5076b69SRichard Tran Mills 
109c5076b69SRichard Tran Mills   PetscFunctionBegin;
1107a8be351SBarry Smith    PetscCheck(shell->ltog,((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
1119566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->ltog,l,g,mode,SCATTER_FORWARD));
112c5076b69SRichard Tran Mills   PetscFunctionReturn(0);
113c5076b69SRichard Tran Mills }
114c5076b69SRichard Tran Mills 
115f3db62a7SRichard Tran Mills /*@
116f3db62a7SRichard Tran Mills    DMLocalToLocalBeginDefaultShell - Uses the LocalToLocal VecScatter context set by the user to begin a local to local scatter
117f3db62a7SRichard Tran Mills    Collective
118f3db62a7SRichard Tran Mills 
1194165533cSJose E. Roman    Input Parameters:
120f3db62a7SRichard Tran Mills +  dm - shell DM
121f3db62a7SRichard Tran Mills .  g - the original local vector
122f3db62a7SRichard Tran Mills -  mode - InsertMode
123f3db62a7SRichard Tran Mills 
124f3db62a7SRichard Tran Mills    Output Parameter:
125f3db62a7SRichard Tran Mills .  l  - the local vector with correct ghost values
126f3db62a7SRichard Tran Mills 
127f3db62a7SRichard Tran Mills    Level: advanced
128f3db62a7SRichard Tran Mills 
129f3db62a7SRichard Tran Mills    Note:  This is not normally called directly by user code, generally user code calls DMLocalToLocalBegin() and DMLocalToLocalEnd(). If the user provides their own custom routines to DMShellSetLocalToLocal() then those routines might have reason to call this function.
130f3db62a7SRichard Tran Mills 
131db781477SPatrick Sanan .seealso: `DMLocalToLocalEndDefaultShell()`
132f3db62a7SRichard Tran Mills @*/
133f3db62a7SRichard Tran Mills PetscErrorCode DMLocalToLocalBeginDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
134f3db62a7SRichard Tran Mills {
135f3db62a7SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
136f3db62a7SRichard Tran Mills 
137f3db62a7SRichard Tran Mills   PetscFunctionBegin;
1387a8be351SBarry Smith   PetscCheck(shell->ltol,((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToLocalVecScatter()");
1399566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(shell->ltol,g,l,mode,SCATTER_FORWARD));
140f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
141f3db62a7SRichard Tran Mills }
142f3db62a7SRichard Tran Mills 
143f3db62a7SRichard Tran Mills /*@
144f3db62a7SRichard Tran Mills    DMLocalToLocalEndDefaultShell - Uses the LocalToLocal VecScatter context set by the user to end a local to local scatter
145f3db62a7SRichard Tran Mills    Collective
146f3db62a7SRichard Tran Mills 
1474165533cSJose E. Roman    Input Parameters:
148f3db62a7SRichard Tran Mills +  dm - shell DM
149f3db62a7SRichard Tran Mills .  g - the original local vector
150f3db62a7SRichard Tran Mills -  mode - InsertMode
151f3db62a7SRichard Tran Mills 
152f3db62a7SRichard Tran Mills    Output Parameter:
153f3db62a7SRichard Tran Mills .  l  - the local vector with correct ghost values
154f3db62a7SRichard Tran Mills 
155f3db62a7SRichard Tran Mills    Level: advanced
156f3db62a7SRichard Tran Mills 
157db781477SPatrick Sanan .seealso: `DMLocalToLocalBeginDefaultShell()`
158f3db62a7SRichard Tran Mills @*/
159f3db62a7SRichard Tran Mills PetscErrorCode DMLocalToLocalEndDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
160f3db62a7SRichard Tran Mills {
161f3db62a7SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
162f3db62a7SRichard Tran Mills 
163f3db62a7SRichard Tran Mills   PetscFunctionBegin;
1647a8be351SBarry Smith    PetscCheck(shell->ltol,((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
1659566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(shell->ltol,g,l,mode,SCATTER_FORWARD));
166f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
167f3db62a7SRichard Tran Mills }
168c5076b69SRichard Tran Mills 
169b412c318SBarry Smith static PetscErrorCode DMCreateMatrix_Shell(DM dm,Mat *J)
170fe1899a2SJed Brown {
171fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
172fe1899a2SJed Brown   Mat            A;
173fe1899a2SJed Brown 
174fe1899a2SJed Brown   PetscFunctionBegin;
175fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
176064a246eSJacob Faibussowitsch   PetscValidPointer(J,2);
1777bde9f88SJed Brown   if (!shell->A) {
1787bde9f88SJed Brown     if (shell->Xglobal) {
1797bde9f88SJed Brown       PetscInt m,M;
1809566063dSJacob Faibussowitsch       PetscCall(PetscInfo(dm,"Naively creating matrix using global vector distribution without preallocation\n"));
1819566063dSJacob Faibussowitsch       PetscCall(VecGetSize(shell->Xglobal,&M));
1829566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(shell->Xglobal,&m));
1839566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)dm),&shell->A));
1849566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(shell->A,m,m,M,M));
1859566063dSJacob Faibussowitsch       PetscCall(MatSetType(shell->A,dm->mattype));
1869566063dSJacob Faibussowitsch       PetscCall(MatSetUp(shell->A));
187ce94432eSBarry Smith     } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector");
1887bde9f88SJed Brown   }
189fe1899a2SJed Brown   A = shell->A;
1909566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(A,MAT_SHARE_NONZERO_PATTERN,J));
1919566063dSJacob Faibussowitsch   PetscCall(MatSetDM(*J,dm));
192fe1899a2SJed Brown   PetscFunctionReturn(0);
193fe1899a2SJed Brown }
194fe1899a2SJed Brown 
195fe1899a2SJed Brown PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec)
196fe1899a2SJed Brown {
197fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
198fe1899a2SJed Brown   Vec            X;
199fe1899a2SJed Brown 
200fe1899a2SJed Brown   PetscFunctionBegin;
201fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
202fe1899a2SJed Brown   PetscValidPointer(gvec,2);
203ea78f98cSLisandro Dalcin   *gvec = NULL;
204fe1899a2SJed Brown   X     = shell->Xglobal;
2057a8be351SBarry Smith   PetscCheck(X,PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
20606f803f6SStefano Zampini   /* Need to create a copy in order to attach the DM to the vector */
2079566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(X,gvec));
2089566063dSJacob Faibussowitsch   PetscCall(VecZeroEntries(*gvec));
2099566063dSJacob Faibussowitsch   PetscCall(VecSetDM(*gvec,dm));
210fe1899a2SJed Brown   PetscFunctionReturn(0);
211fe1899a2SJed Brown }
212fe1899a2SJed Brown 
213dc43b69eSJed Brown PetscErrorCode DMCreateLocalVector_Shell(DM dm,Vec *gvec)
214dc43b69eSJed Brown {
215dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
216dc43b69eSJed Brown   Vec            X;
217dc43b69eSJed Brown 
218dc43b69eSJed Brown   PetscFunctionBegin;
219dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
220dc43b69eSJed Brown   PetscValidPointer(gvec,2);
221ea78f98cSLisandro Dalcin   *gvec = NULL;
222dc43b69eSJed Brown   X     = shell->Xlocal;
2237a8be351SBarry Smith   PetscCheck(X,PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()");
22406f803f6SStefano Zampini   /* Need to create a copy in order to attach the DM to the vector */
2259566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(X,gvec));
2269566063dSJacob Faibussowitsch   PetscCall(VecZeroEntries(*gvec));
2279566063dSJacob Faibussowitsch   PetscCall(VecSetDM(*gvec,dm));
228dc43b69eSJed Brown   PetscFunctionReturn(0);
229dc43b69eSJed Brown }
230dc43b69eSJed Brown 
231fef3a512SBarry Smith /*@
232fef3a512SBarry Smith    DMShellSetContext - set some data to be usable by this DM
233fef3a512SBarry Smith 
234fef3a512SBarry Smith    Collective
235fef3a512SBarry Smith 
2364165533cSJose E. Roman    Input Parameters:
237fef3a512SBarry Smith +  dm - shell DM
238fef3a512SBarry Smith -  ctx - the context
239fef3a512SBarry Smith 
240fef3a512SBarry Smith    Level: advanced
241fef3a512SBarry Smith 
242db781477SPatrick Sanan .seealso: `DMCreateMatrix()`, `DMShellGetContext()`
243fef3a512SBarry Smith @*/
244fef3a512SBarry Smith PetscErrorCode DMShellSetContext(DM dm,void *ctx)
245fef3a512SBarry Smith {
246fef3a512SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
247fef3a512SBarry Smith   PetscBool      isshell;
248fef3a512SBarry Smith 
249fef3a512SBarry Smith   PetscFunctionBegin;
250fef3a512SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2519566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
252fef3a512SBarry Smith   if (!isshell) PetscFunctionReturn(0);
253fef3a512SBarry Smith   shell->ctx = ctx;
254fef3a512SBarry Smith   PetscFunctionReturn(0);
255fef3a512SBarry Smith }
256fef3a512SBarry Smith 
257fef3a512SBarry Smith /*@
258bf890c61SBoris Boutkov    DMShellGetContext - Returns the user-provided context associated to the DM
259fef3a512SBarry Smith 
260fef3a512SBarry Smith    Collective
261fef3a512SBarry Smith 
2624165533cSJose E. Roman    Input Parameter:
263fef3a512SBarry Smith .  dm - shell DM
264fef3a512SBarry Smith 
2654165533cSJose E. Roman    Output Parameter:
266fef3a512SBarry Smith .  ctx - the context
267fef3a512SBarry Smith 
268fef3a512SBarry Smith    Level: advanced
269fef3a512SBarry Smith 
270db781477SPatrick Sanan .seealso: `DMCreateMatrix()`, `DMShellSetContext()`
271fef3a512SBarry Smith @*/
2723ec1f749SStefano Zampini PetscErrorCode DMShellGetContext(DM dm,void *ctx)
273fef3a512SBarry Smith {
274fef3a512SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
275fef3a512SBarry Smith   PetscBool      isshell;
276fef3a512SBarry Smith 
277fef3a512SBarry Smith   PetscFunctionBegin;
278fef3a512SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2799566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
2807a8be351SBarry Smith   PetscCheck(isshell,PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
2813ec1f749SStefano Zampini   *(void**)ctx = shell->ctx;
282fef3a512SBarry Smith   PetscFunctionReturn(0);
283fef3a512SBarry Smith }
284fef3a512SBarry Smith 
285fe1899a2SJed Brown /*@
286fe1899a2SJed Brown    DMShellSetMatrix - sets a template matrix associated with the DMShell
287fe1899a2SJed Brown 
288fe1899a2SJed Brown    Collective
289fe1899a2SJed Brown 
2904165533cSJose E. Roman    Input Parameters:
291fe1899a2SJed Brown +  dm - shell DM
292fe1899a2SJed Brown -  J - template matrix
293fe1899a2SJed Brown 
294fe1899a2SJed Brown    Level: advanced
295fe1899a2SJed Brown 
29606f803f6SStefano Zampini    Developer Notes:
29706f803f6SStefano Zampini     To avoid circular references, if J is already associated to the same DM, then MatDuplicate(SHARE_NONZERO_PATTERN) is called, followed by removing the DM reference from the private template.
29806f803f6SStefano Zampini 
299db781477SPatrick Sanan .seealso: `DMCreateMatrix()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
300fe1899a2SJed Brown @*/
301fe1899a2SJed Brown PetscErrorCode DMShellSetMatrix(DM dm,Mat J)
302fe1899a2SJed Brown {
303fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
3048c87107bSJed Brown   PetscBool      isshell;
30506f803f6SStefano Zampini   DM             mdm;
306fe1899a2SJed Brown 
307fe1899a2SJed Brown   PetscFunctionBegin;
3088c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3098c87107bSJed Brown   PetscValidHeaderSpecific(J,MAT_CLASSID,2);
3109566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
3118c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
31206f803f6SStefano Zampini   if (J == shell->A) PetscFunctionReturn(0);
3139566063dSJacob Faibussowitsch   PetscCall(MatGetDM(J,&mdm));
3149566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)J));
3159566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&shell->A));
31606f803f6SStefano Zampini   if (mdm == dm) {
3179566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(J,MAT_SHARE_NONZERO_PATTERN,&shell->A));
3189566063dSJacob Faibussowitsch     PetscCall(MatSetDM(shell->A,NULL));
31906f803f6SStefano Zampini   } else shell->A = J;
320fe1899a2SJed Brown   PetscFunctionReturn(0);
321fe1899a2SJed Brown }
322fe1899a2SJed Brown 
323fe1899a2SJed Brown /*@C
324fe1899a2SJed Brown    DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM
325fe1899a2SJed Brown 
326d083f849SBarry Smith    Logically Collective on dm
327fe1899a2SJed Brown 
3284165533cSJose E. Roman    Input Parameters:
329fe1899a2SJed Brown +  dm - the shell DM
330fe1899a2SJed Brown -  func - the function to create a matrix
331fe1899a2SJed Brown 
332fe1899a2SJed Brown    Level: advanced
333fe1899a2SJed Brown 
334db781477SPatrick Sanan .seealso: `DMCreateMatrix()`, `DMShellSetMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
335fe1899a2SJed Brown @*/
336b412c318SBarry Smith PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,Mat*))
337fe1899a2SJed Brown {
338fe1899a2SJed Brown   PetscFunctionBegin;
339fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
340fe1899a2SJed Brown   dm->ops->creatematrix = func;
341fe1899a2SJed Brown   PetscFunctionReturn(0);
342fe1899a2SJed Brown }
343fe1899a2SJed Brown 
344fe1899a2SJed Brown /*@
345fe1899a2SJed Brown    DMShellSetGlobalVector - sets a template global vector associated with the DMShell
346fe1899a2SJed Brown 
347d083f849SBarry Smith    Logically Collective on dm
348fe1899a2SJed Brown 
3494165533cSJose E. Roman    Input Parameters:
350fe1899a2SJed Brown +  dm - shell DM
351fe1899a2SJed Brown -  X - template vector
352fe1899a2SJed Brown 
353fe1899a2SJed Brown    Level: advanced
354fe1899a2SJed Brown 
355db781477SPatrick Sanan .seealso: `DMCreateGlobalVector()`, `DMShellSetMatrix()`, `DMShellSetCreateGlobalVector()`
356fe1899a2SJed Brown @*/
357fe1899a2SJed Brown PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X)
358fe1899a2SJed Brown {
359fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
3608c87107bSJed Brown   PetscBool      isshell;
361cca7ec1eSBarry Smith   DM             vdm;
362fe1899a2SJed Brown 
363fe1899a2SJed Brown   PetscFunctionBegin;
3648c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3658c87107bSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
3669566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
3678c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
3689566063dSJacob Faibussowitsch   PetscCall(VecGetDM(X,&vdm));
369cca7ec1eSBarry Smith   /*
370cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
371cca7ec1eSBarry 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
372cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
373cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
374cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
375cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
376cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
377cca7ec1eSBarry Smith       for pointing out the problem.
378cca7ec1eSBarry Smith    */
379cca7ec1eSBarry Smith   if (vdm == dm) PetscFunctionReturn(0);
3809566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)X));
3819566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xglobal));
382fe1899a2SJed Brown   shell->Xglobal = X;
383fe1899a2SJed Brown   PetscFunctionReturn(0);
384fe1899a2SJed Brown }
385fe1899a2SJed Brown 
38604d741b1SMatthew G. Knepley /*@
38704d741b1SMatthew G. Knepley   DMShellGetGlobalVector - Returns the template global vector associated with the DMShell, or NULL if it was not set
38804d741b1SMatthew G. Knepley 
38904d741b1SMatthew G. Knepley    Not collective
39004d741b1SMatthew G. Knepley 
3914165533cSJose E. Roman    Input Parameters:
39204d741b1SMatthew G. Knepley +  dm - shell DM
39304d741b1SMatthew G. Knepley -  X - template vector
39404d741b1SMatthew G. Knepley 
39504d741b1SMatthew G. Knepley    Level: advanced
39604d741b1SMatthew G. Knepley 
397db781477SPatrick Sanan .seealso: `DMShellSetGlobalVector()`, `DMShellSetCreateGlobalVector()`, `DMCreateGlobalVector()`
39804d741b1SMatthew G. Knepley @*/
39904d741b1SMatthew G. Knepley PetscErrorCode DMShellGetGlobalVector(DM dm, Vec *X)
40004d741b1SMatthew G. Knepley {
40104d741b1SMatthew G. Knepley   DM_Shell      *shell = (DM_Shell *) dm->data;
40204d741b1SMatthew G. Knepley   PetscBool      isshell;
40304d741b1SMatthew G. Knepley 
40404d741b1SMatthew G. Knepley   PetscFunctionBegin;
40504d741b1SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
40604d741b1SMatthew G. Knepley   PetscValidPointer(X,2);
4079566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
40804d741b1SMatthew G. Knepley   if (!isshell) PetscFunctionReturn(0);
40904d741b1SMatthew G. Knepley   *X = shell->Xglobal;
41004d741b1SMatthew G. Knepley   PetscFunctionReturn(0);
41104d741b1SMatthew G. Knepley }
41204d741b1SMatthew G. Knepley 
413fe1899a2SJed Brown /*@C
414fe1899a2SJed Brown    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM
415fe1899a2SJed Brown 
416fe1899a2SJed Brown    Logically Collective
417fe1899a2SJed Brown 
4184165533cSJose E. Roman    Input Parameters:
419fe1899a2SJed Brown +  dm - the shell DM
420fe1899a2SJed Brown -  func - the creation routine
421fe1899a2SJed Brown 
422fe1899a2SJed Brown    Level: advanced
423fe1899a2SJed Brown 
424db781477SPatrick Sanan .seealso: `DMShellSetGlobalVector()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
425fe1899a2SJed Brown @*/
426fe1899a2SJed Brown PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
427fe1899a2SJed Brown {
428fe1899a2SJed Brown   PetscFunctionBegin;
429fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
430fe1899a2SJed Brown   dm->ops->createglobalvector = func;
431fe1899a2SJed Brown   PetscFunctionReturn(0);
432fe1899a2SJed Brown }
433fe1899a2SJed Brown 
434dc43b69eSJed Brown /*@
435dc43b69eSJed Brown    DMShellSetLocalVector - sets a template local vector associated with the DMShell
436dc43b69eSJed Brown 
437d083f849SBarry Smith    Logically Collective on dm
438dc43b69eSJed Brown 
4394165533cSJose E. Roman    Input Parameters:
440dc43b69eSJed Brown +  dm - shell DM
441dc43b69eSJed Brown -  X - template vector
442dc43b69eSJed Brown 
443dc43b69eSJed Brown    Level: advanced
444dc43b69eSJed Brown 
445db781477SPatrick Sanan .seealso: `DMCreateLocalVector()`, `DMShellSetMatrix()`, `DMShellSetCreateLocalVector()`
446dc43b69eSJed Brown @*/
447dc43b69eSJed Brown PetscErrorCode DMShellSetLocalVector(DM dm,Vec X)
448dc43b69eSJed Brown {
449dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
450dc43b69eSJed Brown   PetscBool      isshell;
451cca7ec1eSBarry Smith   DM             vdm;
452dc43b69eSJed Brown 
453dc43b69eSJed Brown   PetscFunctionBegin;
454dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
455dc43b69eSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
4569566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
457dc43b69eSJed Brown   if (!isshell) PetscFunctionReturn(0);
4589566063dSJacob Faibussowitsch   PetscCall(VecGetDM(X,&vdm));
459cca7ec1eSBarry Smith   /*
460cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
461cca7ec1eSBarry 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
462cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
463cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
464cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
465cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
466cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
467cca7ec1eSBarry Smith       for pointing out the problem.
468cca7ec1eSBarry Smith    */
469cca7ec1eSBarry Smith   if (vdm == dm) PetscFunctionReturn(0);
4709566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)X));
4719566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xlocal));
472dc43b69eSJed Brown   shell->Xlocal = X;
473dc43b69eSJed Brown   PetscFunctionReturn(0);
474dc43b69eSJed Brown }
475dc43b69eSJed Brown 
476dc43b69eSJed Brown /*@C
477dc43b69eSJed Brown    DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM
478dc43b69eSJed Brown 
479dc43b69eSJed Brown    Logically Collective
480dc43b69eSJed Brown 
4814165533cSJose E. Roman    Input Parameters:
482dc43b69eSJed Brown +  dm - the shell DM
483dc43b69eSJed Brown -  func - the creation routine
484dc43b69eSJed Brown 
485dc43b69eSJed Brown    Level: advanced
486dc43b69eSJed Brown 
487db781477SPatrick Sanan .seealso: `DMShellSetLocalVector()`, `DMShellSetCreateMatrix()`, `DMShellSetContext()`, `DMShellGetContext()`
488dc43b69eSJed Brown @*/
489dc43b69eSJed Brown PetscErrorCode DMShellSetCreateLocalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
490dc43b69eSJed Brown {
491dc43b69eSJed Brown   PetscFunctionBegin;
492dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
493dc43b69eSJed Brown   dm->ops->createlocalvector = func;
494dc43b69eSJed Brown   PetscFunctionReturn(0);
495dc43b69eSJed Brown }
496dc43b69eSJed Brown 
4978339e6d0SRichard Tran Mills /*@C
4988339e6d0SRichard Tran Mills    DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter
4998339e6d0SRichard Tran Mills 
500d083f849SBarry Smith    Logically Collective on dm
5018339e6d0SRichard Tran Mills 
5024165533cSJose E. Roman    Input Parameters
5038339e6d0SRichard Tran Mills +  dm - the shell DM
5048339e6d0SRichard Tran Mills .  begin - the routine that begins the global to local scatter
5058339e6d0SRichard Tran Mills -  end - the routine that ends the global to local scatter
5068339e6d0SRichard Tran Mills 
50795452b02SPatrick Sanan    Notes:
50895452b02SPatrick Sanan     If these functions are not provided but DMShellSetGlobalToLocalVecScatter() is called then
509f3db62a7SRichard Tran Mills    DMGlobalToLocalBeginDefaultShell()/DMGlobalToLocalEndDefaultShell() are used to to perform the transfers
5107a108d1dSBarry Smith 
5118339e6d0SRichard Tran Mills    Level: advanced
5128339e6d0SRichard Tran Mills 
513db781477SPatrick Sanan .seealso: `DMShellSetLocalToGlobal()`, `DMGlobalToLocalBeginDefaultShell()`, `DMGlobalToLocalEndDefaultShell()`
5148339e6d0SRichard Tran Mills @*/
515bdb10af2SPierre Jolivet PetscErrorCode DMShellSetGlobalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec))
516bdb10af2SPierre Jolivet {
5178339e6d0SRichard Tran Mills   PetscFunctionBegin;
5182d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5198339e6d0SRichard Tran Mills   dm->ops->globaltolocalbegin = begin;
5208339e6d0SRichard Tran Mills   dm->ops->globaltolocalend = end;
5218339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
5228339e6d0SRichard Tran Mills }
5238339e6d0SRichard Tran Mills 
5248339e6d0SRichard Tran Mills /*@C
5258339e6d0SRichard Tran Mills    DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter
5268339e6d0SRichard Tran Mills 
527d083f849SBarry Smith    Logically Collective on dm
5288339e6d0SRichard Tran Mills 
5294165533cSJose E. Roman    Input Parameters
5308339e6d0SRichard Tran Mills +  dm - the shell DM
5318339e6d0SRichard Tran Mills .  begin - the routine that begins the local to global scatter
5328339e6d0SRichard Tran Mills -  end - the routine that ends the local to global scatter
5338339e6d0SRichard Tran Mills 
53495452b02SPatrick Sanan    Notes:
53595452b02SPatrick Sanan     If these functions are not provided but DMShellSetLocalToGlobalVecScatter() is called then
536f3db62a7SRichard Tran Mills    DMLocalToGlobalBeginDefaultShell()/DMLocalToGlobalEndDefaultShell() are used to to perform the transfers
537f3db62a7SRichard Tran Mills 
5388339e6d0SRichard Tran Mills    Level: advanced
5398339e6d0SRichard Tran Mills 
540db781477SPatrick Sanan .seealso: `DMShellSetGlobalToLocal()`
5418339e6d0SRichard Tran Mills @*/
542bdb10af2SPierre Jolivet PetscErrorCode DMShellSetLocalToGlobal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec))
543bdb10af2SPierre Jolivet {
5448339e6d0SRichard Tran Mills   PetscFunctionBegin;
5452d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5468339e6d0SRichard Tran Mills   dm->ops->localtoglobalbegin = begin;
5478339e6d0SRichard Tran Mills   dm->ops->localtoglobalend = end;
5488339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
5498339e6d0SRichard Tran Mills }
5508339e6d0SRichard Tran Mills 
551f3db62a7SRichard Tran Mills /*@C
552f3db62a7SRichard Tran Mills    DMShellSetLocalToLocal - Sets the routines used to perform a local to local scatter
553f3db62a7SRichard Tran Mills 
554d083f849SBarry Smith    Logically Collective on dm
555f3db62a7SRichard Tran Mills 
5564165533cSJose E. Roman    Input Parameters
557f3db62a7SRichard Tran Mills +  dm - the shell DM
558f3db62a7SRichard Tran Mills .  begin - the routine that begins the local to local scatter
559f3db62a7SRichard Tran Mills -  end - the routine that ends the local to local scatter
560f3db62a7SRichard Tran Mills 
56195452b02SPatrick Sanan    Notes:
56295452b02SPatrick Sanan     If these functions are not provided but DMShellSetLocalToLocalVecScatter() is called then
563f3db62a7SRichard Tran Mills    DMLocalToLocalBeginDefaultShell()/DMLocalToLocalEndDefaultShell() are used to to perform the transfers
564f3db62a7SRichard Tran Mills 
565f3db62a7SRichard Tran Mills    Level: advanced
566f3db62a7SRichard Tran Mills 
567db781477SPatrick Sanan .seealso: `DMShellSetGlobalToLocal()`, `DMLocalToLocalBeginDefaultShell()`, `DMLocalToLocalEndDefaultShell()`
568f3db62a7SRichard Tran Mills @*/
569bdb10af2SPierre Jolivet PetscErrorCode DMShellSetLocalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec))
570bdb10af2SPierre Jolivet {
571f3db62a7SRichard Tran Mills   PetscFunctionBegin;
5722d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
573f3db62a7SRichard Tran Mills   dm->ops->localtolocalbegin = begin;
574f3db62a7SRichard Tran Mills   dm->ops->localtolocalend = end;
575f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
576f3db62a7SRichard Tran Mills }
577f3db62a7SRichard Tran Mills 
57881634712SRichard Tran Mills /*@
57981634712SRichard Tran Mills    DMShellSetGlobalToLocalVecScatter - Sets a VecScatter context for global to local communication
58081634712SRichard Tran Mills 
581d083f849SBarry Smith    Logically Collective on dm
58281634712SRichard Tran Mills 
5834165533cSJose E. Roman    Input Parameters
58481634712SRichard Tran Mills +  dm - the shell DM
58581634712SRichard Tran Mills -  gtol - the global to local VecScatter context
58681634712SRichard Tran Mills 
58781634712SRichard Tran Mills    Level: advanced
58881634712SRichard Tran Mills 
589db781477SPatrick Sanan .seealso: `DMShellSetGlobalToLocal()`, `DMGlobalToLocalBeginDefaultShell()`, `DMGlobalToLocalEndDefaultShell()`
59081634712SRichard Tran Mills @*/
591a94b16f6SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter gtol)
59281634712SRichard Tran Mills {
59381634712SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
59481634712SRichard Tran Mills 
595b300e4a8SRichard Tran Mills   PetscFunctionBegin;
5962d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
59797929ea7SJunchao Zhang   PetscValidHeaderSpecific(gtol,PETSCSF_CLASSID,2);
5989566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)gtol));
5999566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->gtol));
60081634712SRichard Tran Mills   shell->gtol = gtol;
60181634712SRichard Tran Mills   PetscFunctionReturn(0);
60281634712SRichard Tran Mills }
60381634712SRichard Tran Mills 
604988ea7d6SRichard Tran Mills /*@
605988ea7d6SRichard Tran Mills    DMShellSetLocalToGlobalVecScatter - Sets a VecScatter context for local to global communication
606988ea7d6SRichard Tran Mills 
607d083f849SBarry Smith    Logically Collective on dm
608988ea7d6SRichard Tran Mills 
6094165533cSJose E. Roman    Input Parameters
610988ea7d6SRichard Tran Mills +  dm - the shell DM
611988ea7d6SRichard Tran Mills -  ltog - the local to global VecScatter context
612988ea7d6SRichard Tran Mills 
613988ea7d6SRichard Tran Mills    Level: advanced
614988ea7d6SRichard Tran Mills 
615db781477SPatrick Sanan .seealso: `DMShellSetLocalToGlobal()`, `DMLocalToGlobalBeginDefaultShell()`, `DMLocalToGlobalEndDefaultShell()`
616988ea7d6SRichard Tran Mills @*/
617a94b16f6SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM dm, VecScatter ltog)
618988ea7d6SRichard Tran Mills {
619988ea7d6SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
620988ea7d6SRichard Tran Mills 
621988ea7d6SRichard Tran Mills   PetscFunctionBegin;
6222d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
62397929ea7SJunchao Zhang   PetscValidHeaderSpecific(ltog,PETSCSF_CLASSID,2);
6249566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)ltog));
6259566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltog));
626988ea7d6SRichard Tran Mills   shell->ltog = ltog;
627988ea7d6SRichard Tran Mills   PetscFunctionReturn(0);
628988ea7d6SRichard Tran Mills }
629988ea7d6SRichard Tran Mills 
630f3db62a7SRichard Tran Mills /*@
631f3db62a7SRichard Tran Mills    DMShellSetLocalToLocalVecScatter - Sets a VecScatter context for local to local communication
632f3db62a7SRichard Tran Mills 
633d083f849SBarry Smith    Logically Collective on dm
634f3db62a7SRichard Tran Mills 
6354165533cSJose E. Roman    Input Parameters
636f3db62a7SRichard Tran Mills +  dm - the shell DM
637f3db62a7SRichard Tran Mills -  ltol - the local to local VecScatter context
638f3db62a7SRichard Tran Mills 
639f3db62a7SRichard Tran Mills    Level: advanced
640f3db62a7SRichard Tran Mills 
641db781477SPatrick Sanan .seealso: `DMShellSetLocalToLocal()`, `DMLocalToLocalBeginDefaultShell()`, `DMLocalToLocalEndDefaultShell()`
642f3db62a7SRichard Tran Mills @*/
643f3db62a7SRichard Tran Mills PetscErrorCode DMShellSetLocalToLocalVecScatter(DM dm, VecScatter ltol)
644f3db62a7SRichard Tran Mills {
645f3db62a7SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
646f3db62a7SRichard Tran Mills 
647f3db62a7SRichard Tran Mills   PetscFunctionBegin;
6482d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
64997929ea7SJunchao Zhang   PetscValidHeaderSpecific(ltol,PETSCSF_CLASSID,2);
6509566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)ltol));
6519566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltol));
652f3db62a7SRichard Tran Mills   shell->ltol = ltol;
653f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
654f3db62a7SRichard Tran Mills }
655f3db62a7SRichard Tran Mills 
6569bf9660cSLawrence Mitchell /*@C
6579bf9660cSLawrence Mitchell    DMShellSetCoarsen - Set the routine used to coarsen the shell DM
6589bf9660cSLawrence Mitchell 
659d083f849SBarry Smith    Logically Collective on dm
6609bf9660cSLawrence Mitchell 
6614165533cSJose E. Roman    Input Parameters
6629bf9660cSLawrence Mitchell +  dm - the shell DM
6639bf9660cSLawrence Mitchell -  coarsen - the routine that coarsens the DM
6649bf9660cSLawrence Mitchell 
6659bf9660cSLawrence Mitchell    Level: advanced
6669bf9660cSLawrence Mitchell 
667db781477SPatrick Sanan .seealso: `DMShellSetRefine()`, `DMCoarsen()`, `DMShellGetCoarsen()`, `DMShellSetContext()`, `DMShellGetContext()`
6689bf9660cSLawrence Mitchell @*/
669f572501eSLawrence Mitchell PetscErrorCode DMShellSetCoarsen(DM dm, PetscErrorCode (*coarsen)(DM,MPI_Comm,DM*))
670f572501eSLawrence Mitchell {
671f572501eSLawrence Mitchell   PetscBool      isshell;
672f572501eSLawrence Mitchell 
673f572501eSLawrence Mitchell   PetscFunctionBegin;
674f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6759566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
676f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
677f572501eSLawrence Mitchell   dm->ops->coarsen = coarsen;
678f572501eSLawrence Mitchell   PetscFunctionReturn(0);
679f572501eSLawrence Mitchell }
680f572501eSLawrence Mitchell 
6819bf9660cSLawrence Mitchell /*@C
6824363ddcaSBoris Boutkov    DMShellGetCoarsen - Get the routine used to coarsen the shell DM
6834363ddcaSBoris Boutkov 
684d083f849SBarry Smith    Logically Collective on dm
6854363ddcaSBoris Boutkov 
6864165533cSJose E. Roman    Input Parameter:
6874363ddcaSBoris Boutkov .  dm - the shell DM
6884363ddcaSBoris Boutkov 
6894165533cSJose E. Roman    Output Parameter:
6904363ddcaSBoris Boutkov .  coarsen - the routine that coarsens the DM
6914363ddcaSBoris Boutkov 
6924363ddcaSBoris Boutkov    Level: advanced
6934363ddcaSBoris Boutkov 
694db781477SPatrick Sanan .seealso: `DMShellSetCoarsen()`, `DMCoarsen()`, `DMShellSetRefine()`, `DMRefine()`
6954363ddcaSBoris Boutkov @*/
6964363ddcaSBoris Boutkov PetscErrorCode DMShellGetCoarsen(DM dm, PetscErrorCode (**coarsen)(DM,MPI_Comm,DM*))
6974363ddcaSBoris Boutkov {
6984363ddcaSBoris Boutkov   PetscBool      isshell;
6994363ddcaSBoris Boutkov 
7004363ddcaSBoris Boutkov   PetscFunctionBegin;
7014363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7029566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
7037a8be351SBarry Smith   PetscCheck(isshell,PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
7044363ddcaSBoris Boutkov   *coarsen = dm->ops->coarsen;
7054363ddcaSBoris Boutkov   PetscFunctionReturn(0);
7064363ddcaSBoris Boutkov }
7074363ddcaSBoris Boutkov 
7084363ddcaSBoris Boutkov /*@C
7099bf9660cSLawrence Mitchell    DMShellSetRefine - Set the routine used to refine the shell DM
7109bf9660cSLawrence Mitchell 
711d083f849SBarry Smith    Logically Collective on dm
7129bf9660cSLawrence Mitchell 
7134165533cSJose E. Roman    Input Parameters
7149bf9660cSLawrence Mitchell +  dm - the shell DM
7159bf9660cSLawrence Mitchell -  refine - the routine that refines the DM
7169bf9660cSLawrence Mitchell 
7179bf9660cSLawrence Mitchell    Level: advanced
7189bf9660cSLawrence Mitchell 
719db781477SPatrick Sanan .seealso: `DMShellSetCoarsen()`, `DMRefine()`, `DMShellGetRefine()`, `DMShellSetContext()`, `DMShellGetContext()`
7209bf9660cSLawrence Mitchell @*/
721f572501eSLawrence Mitchell PetscErrorCode DMShellSetRefine(DM dm, PetscErrorCode (*refine)(DM,MPI_Comm,DM*))
722f572501eSLawrence Mitchell {
723f572501eSLawrence Mitchell   PetscBool      isshell;
724f572501eSLawrence Mitchell 
725f572501eSLawrence Mitchell   PetscFunctionBegin;
726f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7279566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
728f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
729f572501eSLawrence Mitchell   dm->ops->refine = refine;
730f572501eSLawrence Mitchell   PetscFunctionReturn(0);
731f572501eSLawrence Mitchell }
732f572501eSLawrence Mitchell 
7339bf9660cSLawrence Mitchell /*@C
7344363ddcaSBoris Boutkov    DMShellGetRefine - Get the routine used to refine the shell DM
7354363ddcaSBoris Boutkov 
736d083f849SBarry Smith    Logically Collective on dm
7374363ddcaSBoris Boutkov 
7384165533cSJose E. Roman    Input Parameter:
7394363ddcaSBoris Boutkov .  dm - the shell DM
7404363ddcaSBoris Boutkov 
7414165533cSJose E. Roman    Output Parameter:
7424363ddcaSBoris Boutkov .  refine - the routine that refines the DM
7434363ddcaSBoris Boutkov 
7444363ddcaSBoris Boutkov    Level: advanced
7454363ddcaSBoris Boutkov 
746db781477SPatrick Sanan .seealso: `DMShellSetCoarsen()`, `DMCoarsen()`, `DMShellSetRefine()`, `DMRefine()`
7474363ddcaSBoris Boutkov @*/
7484363ddcaSBoris Boutkov PetscErrorCode DMShellGetRefine(DM dm, PetscErrorCode (**refine)(DM,MPI_Comm,DM*))
7494363ddcaSBoris Boutkov {
7504363ddcaSBoris Boutkov   PetscBool      isshell;
7514363ddcaSBoris Boutkov 
7524363ddcaSBoris Boutkov   PetscFunctionBegin;
7534363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7549566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
7557a8be351SBarry Smith   PetscCheck(isshell,PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
7564363ddcaSBoris Boutkov   *refine = dm->ops->refine;
7574363ddcaSBoris Boutkov   PetscFunctionReturn(0);
7584363ddcaSBoris Boutkov }
7594363ddcaSBoris Boutkov 
7604363ddcaSBoris Boutkov /*@C
7619bf9660cSLawrence Mitchell    DMShellSetCreateInterpolation - Set the routine used to create the interpolation operator
7629bf9660cSLawrence Mitchell 
763d083f849SBarry Smith    Logically Collective on dm
7649bf9660cSLawrence Mitchell 
7654165533cSJose E. Roman    Input Parameters
7669bf9660cSLawrence Mitchell +  dm - the shell DM
7679bf9660cSLawrence Mitchell -  interp - the routine to create the interpolation
7689bf9660cSLawrence Mitchell 
7699bf9660cSLawrence Mitchell    Level: advanced
7709bf9660cSLawrence Mitchell 
771db781477SPatrick Sanan .seealso: `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateInterpolation()`, `DMShellSetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
7729bf9660cSLawrence Mitchell @*/
773f572501eSLawrence Mitchell PetscErrorCode DMShellSetCreateInterpolation(DM dm, PetscErrorCode (*interp)(DM,DM,Mat*,Vec*))
774f572501eSLawrence Mitchell {
775f572501eSLawrence Mitchell   PetscBool      isshell;
776f572501eSLawrence Mitchell 
777f572501eSLawrence Mitchell   PetscFunctionBegin;
778f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7799566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
780f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
781f572501eSLawrence Mitchell   dm->ops->createinterpolation = interp;
782f572501eSLawrence Mitchell   PetscFunctionReturn(0);
783f572501eSLawrence Mitchell }
784f572501eSLawrence Mitchell 
7853ad4599aSBarry Smith /*@C
7864363ddcaSBoris Boutkov    DMShellGetCreateInterpolation - Get the routine used to create the interpolation operator
7874363ddcaSBoris Boutkov 
788d083f849SBarry Smith    Logically Collective on dm
7894363ddcaSBoris Boutkov 
7904165533cSJose E. Roman    Input Parameter:
7914165533cSJose E. Roman .  dm - the shell DM
792a4a986ddSBoris Boutkov 
7934165533cSJose E. Roman    Output Parameter:
7944165533cSJose E. Roman .  interp - the routine to create the interpolation
7954363ddcaSBoris Boutkov 
7964363ddcaSBoris Boutkov    Level: advanced
7974363ddcaSBoris Boutkov 
798db781477SPatrick Sanan .seealso: `DMShellGetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
7994363ddcaSBoris Boutkov @*/
8004363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateInterpolation(DM dm, PetscErrorCode (**interp)(DM,DM,Mat*,Vec*))
8014363ddcaSBoris Boutkov {
8024363ddcaSBoris Boutkov   PetscBool      isshell;
8034363ddcaSBoris Boutkov 
8044363ddcaSBoris Boutkov   PetscFunctionBegin;
8054363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8069566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
8077a8be351SBarry Smith   PetscCheck(isshell,PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
8084363ddcaSBoris Boutkov   *interp = dm->ops->createinterpolation;
8094363ddcaSBoris Boutkov   PetscFunctionReturn(0);
8104363ddcaSBoris Boutkov }
8114363ddcaSBoris Boutkov 
8124363ddcaSBoris Boutkov /*@C
8133ad4599aSBarry Smith    DMShellSetCreateRestriction - Set the routine used to create the restriction operator
8143ad4599aSBarry Smith 
815d083f849SBarry Smith    Logically Collective on dm
8163ad4599aSBarry Smith 
8174165533cSJose E. Roman    Input Parameters
8183ad4599aSBarry Smith +  dm - the shell DM
8193ad4599aSBarry Smith -  striction- the routine to create the restriction
8203ad4599aSBarry Smith 
8213ad4599aSBarry Smith    Level: advanced
8223ad4599aSBarry Smith 
823db781477SPatrick Sanan .seealso: `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellGetCreateRestriction()`, `DMShellSetContext()`, `DMShellGetContext()`
8243ad4599aSBarry Smith @*/
8253ad4599aSBarry Smith PetscErrorCode DMShellSetCreateRestriction(DM dm, PetscErrorCode (*restriction)(DM,DM,Mat*))
8263ad4599aSBarry Smith {
8273ad4599aSBarry Smith   PetscBool      isshell;
8283ad4599aSBarry Smith 
8293ad4599aSBarry Smith   PetscFunctionBegin;
8303ad4599aSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8319566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
8323ad4599aSBarry Smith   if (!isshell) PetscFunctionReturn(0);
8333ad4599aSBarry Smith   dm->ops->createrestriction = restriction;
8343ad4599aSBarry Smith   PetscFunctionReturn(0);
8353ad4599aSBarry Smith }
8363ad4599aSBarry Smith 
8379bf9660cSLawrence Mitchell /*@C
8384363ddcaSBoris Boutkov    DMShellGetCreateRestriction - Get the routine used to create the restriction operator
8394363ddcaSBoris Boutkov 
840d083f849SBarry Smith    Logically Collective on dm
8414363ddcaSBoris Boutkov 
8424165533cSJose E. Roman    Input Parameter:
8434165533cSJose E. Roman .  dm - the shell DM
844a4a986ddSBoris Boutkov 
8454165533cSJose E. Roman    Output Parameter:
8464165533cSJose E. Roman .  restriction - the routine to create the restriction
8474363ddcaSBoris Boutkov 
8484363ddcaSBoris Boutkov    Level: advanced
8494363ddcaSBoris Boutkov 
850db781477SPatrick Sanan .seealso: `DMShellSetCreateInjection()`, `DMCreateInterpolation()`, `DMShellSetContext()`, `DMShellGetContext()`
8514363ddcaSBoris Boutkov @*/
8524363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateRestriction(DM dm, PetscErrorCode (**restriction)(DM,DM,Mat*))
8534363ddcaSBoris Boutkov {
8544363ddcaSBoris Boutkov   PetscBool      isshell;
8554363ddcaSBoris Boutkov 
8564363ddcaSBoris Boutkov   PetscFunctionBegin;
8574363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8589566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
8597a8be351SBarry Smith   PetscCheck(isshell,PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
8604363ddcaSBoris Boutkov   *restriction = dm->ops->createrestriction;
8614363ddcaSBoris Boutkov   PetscFunctionReturn(0);
8624363ddcaSBoris Boutkov }
8634363ddcaSBoris Boutkov 
8644363ddcaSBoris Boutkov /*@C
8659bf9660cSLawrence Mitchell    DMShellSetCreateInjection - Set the routine used to create the injection operator
8669bf9660cSLawrence Mitchell 
867d083f849SBarry Smith    Logically Collective on dm
8689bf9660cSLawrence Mitchell 
8694165533cSJose E. Roman    Input Parameters:
8709bf9660cSLawrence Mitchell +  dm - the shell DM
8719bf9660cSLawrence Mitchell -  inject - the routine to create the injection
8729bf9660cSLawrence Mitchell 
8739bf9660cSLawrence Mitchell    Level: advanced
8749bf9660cSLawrence Mitchell 
875db781477SPatrick Sanan .seealso: `DMShellSetCreateInterpolation()`, `DMCreateInjection()`, `DMShellGetCreateInjection()`, `DMShellSetContext()`, `DMShellGetContext()`
8769bf9660cSLawrence Mitchell @*/
877f572501eSLawrence Mitchell PetscErrorCode DMShellSetCreateInjection(DM dm, PetscErrorCode (*inject)(DM,DM,Mat*))
878f572501eSLawrence Mitchell {
879f572501eSLawrence Mitchell   PetscBool      isshell;
880f572501eSLawrence Mitchell 
881f572501eSLawrence Mitchell   PetscFunctionBegin;
882f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8839566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
884f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
8855a84ad33SLisandro Dalcin   dm->ops->createinjection = inject;
886f572501eSLawrence Mitchell   PetscFunctionReturn(0);
887f572501eSLawrence Mitchell }
888f572501eSLawrence Mitchell 
8894363ddcaSBoris Boutkov /*@C
8904363ddcaSBoris Boutkov    DMShellGetCreateInjection - Get the routine used to create the injection operator
8914363ddcaSBoris Boutkov 
892d083f849SBarry Smith    Logically Collective on dm
8934363ddcaSBoris Boutkov 
8944165533cSJose E. Roman    Input Parameter:
8954165533cSJose E. Roman .  dm - the shell DM
896a4a986ddSBoris Boutkov 
8974165533cSJose E. Roman    Output Parameter:
8984165533cSJose E. Roman .  inject - the routine to create the injection
8994363ddcaSBoris Boutkov 
9004363ddcaSBoris Boutkov    Level: advanced
9014363ddcaSBoris Boutkov 
902db781477SPatrick Sanan .seealso: `DMShellGetCreateInterpolation()`, `DMCreateInjection()`, `DMShellSetContext()`, `DMShellGetContext()`
9034363ddcaSBoris Boutkov @*/
9044363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateInjection(DM dm, PetscErrorCode (**inject)(DM,DM,Mat*))
9054363ddcaSBoris Boutkov {
9064363ddcaSBoris Boutkov   PetscBool      isshell;
9074363ddcaSBoris Boutkov 
9084363ddcaSBoris Boutkov   PetscFunctionBegin;
9094363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9109566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
9117a8be351SBarry Smith   PetscCheck(isshell,PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
9125a84ad33SLisandro Dalcin   *inject = dm->ops->createinjection;
9134363ddcaSBoris Boutkov   PetscFunctionReturn(0);
9144363ddcaSBoris Boutkov }
9154363ddcaSBoris Boutkov 
9169bf9660cSLawrence Mitchell /*@C
9179bf9660cSLawrence Mitchell    DMShellSetCreateFieldDecomposition - Set the routine used to create a decomposition of fields for the shell DM
9189bf9660cSLawrence Mitchell 
919d083f849SBarry Smith    Logically Collective on dm
9209bf9660cSLawrence Mitchell 
9214165533cSJose E. Roman    Input Parameters:
9229bf9660cSLawrence Mitchell +  dm - the shell DM
9239bf9660cSLawrence Mitchell -  decomp - the routine to create the decomposition
9249bf9660cSLawrence Mitchell 
9259bf9660cSLawrence Mitchell    Level: advanced
9269bf9660cSLawrence Mitchell 
927db781477SPatrick Sanan .seealso: `DMCreateFieldDecomposition()`, `DMShellSetContext()`, `DMShellGetContext()`
9289bf9660cSLawrence Mitchell @*/
9295e2259d5SLawrence Mitchell PetscErrorCode DMShellSetCreateFieldDecomposition(DM dm, PetscErrorCode (*decomp)(DM,PetscInt*,char***, IS**,DM**))
9305e2259d5SLawrence Mitchell {
9315e2259d5SLawrence Mitchell   PetscBool      isshell;
9325e2259d5SLawrence Mitchell 
9335e2259d5SLawrence Mitchell   PetscFunctionBegin;
9345e2259d5SLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9359566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
9365e2259d5SLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
9375e2259d5SLawrence Mitchell   dm->ops->createfielddecomposition = decomp;
9385e2259d5SLawrence Mitchell   PetscFunctionReturn(0);
9395e2259d5SLawrence Mitchell }
9405e2259d5SLawrence Mitchell 
941c00061e5SLawrence Mitchell /*@C
942e734121bSPatrick Farrell    DMShellSetCreateDomainDecomposition - Set the routine used to create a domain decomposition for the shell DM
943e734121bSPatrick Farrell 
944d083f849SBarry Smith    Logically Collective on dm
945e734121bSPatrick Farrell 
9464165533cSJose E. Roman    Input Parameters:
947e734121bSPatrick Farrell +  dm - the shell DM
948e734121bSPatrick Farrell -  decomp - the routine to create the decomposition
949e734121bSPatrick Farrell 
950e734121bSPatrick Farrell    Level: advanced
951e734121bSPatrick Farrell 
952db781477SPatrick Sanan .seealso: `DMCreateDomainDecomposition()`, `DMShellSetContext()`, `DMShellGetContext()`
953e734121bSPatrick Farrell @*/
954e734121bSPatrick Farrell PetscErrorCode DMShellSetCreateDomainDecomposition(DM dm, PetscErrorCode (*decomp)(DM,PetscInt*,char***, IS**,IS**,DM**))
955e734121bSPatrick Farrell {
956e734121bSPatrick Farrell   PetscBool      isshell;
957e734121bSPatrick Farrell 
958e734121bSPatrick Farrell   PetscFunctionBegin;
959e734121bSPatrick Farrell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9609566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
961e734121bSPatrick Farrell   if (!isshell) PetscFunctionReturn(0);
962e734121bSPatrick Farrell   dm->ops->createdomaindecomposition = decomp;
963e734121bSPatrick Farrell   PetscFunctionReturn(0);
964e734121bSPatrick Farrell }
965e734121bSPatrick Farrell 
966e734121bSPatrick Farrell /*@C
967eef9d6cdSPatrick Farrell    DMShellSetCreateDomainDecompositionScatters - Set the routine used to create the scatter contexts for domain decomposition with a shell DM
968eef9d6cdSPatrick Farrell 
969d083f849SBarry Smith    Logically Collective on dm
970eef9d6cdSPatrick Farrell 
9714165533cSJose E. Roman    Input Parameters:
972eef9d6cdSPatrick Farrell +  dm - the shell DM
973eef9d6cdSPatrick Farrell -  scatter - the routine to create the scatters
974eef9d6cdSPatrick Farrell 
975eef9d6cdSPatrick Farrell    Level: advanced
976eef9d6cdSPatrick Farrell 
977db781477SPatrick Sanan .seealso: `DMCreateDomainDecompositionScatters()`, `DMShellSetContext()`, `DMShellGetContext()`
978eef9d6cdSPatrick Farrell @*/
979eef9d6cdSPatrick Farrell PetscErrorCode DMShellSetCreateDomainDecompositionScatters(DM dm, PetscErrorCode (*scatter)(DM,PetscInt,DM*,VecScatter**,VecScatter**,VecScatter**))
980eef9d6cdSPatrick Farrell {
981eef9d6cdSPatrick Farrell   PetscBool      isshell;
982eef9d6cdSPatrick Farrell 
983eef9d6cdSPatrick Farrell   PetscFunctionBegin;
984eef9d6cdSPatrick Farrell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9859566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
986eef9d6cdSPatrick Farrell   if (!isshell) PetscFunctionReturn(0);
987eef9d6cdSPatrick Farrell   dm->ops->createddscatters = scatter;
988eef9d6cdSPatrick Farrell   PetscFunctionReturn(0);
989eef9d6cdSPatrick Farrell }
990eef9d6cdSPatrick Farrell 
991eef9d6cdSPatrick Farrell /*@C
992c00061e5SLawrence Mitchell    DMShellSetCreateSubDM - Set the routine used to create a sub DM from the shell DM
993c00061e5SLawrence Mitchell 
994d083f849SBarry Smith    Logically Collective on dm
995c00061e5SLawrence Mitchell 
9964165533cSJose E. Roman    Input Parameters:
997c00061e5SLawrence Mitchell +  dm - the shell DM
998c00061e5SLawrence Mitchell -  subdm - the routine to create the decomposition
999c00061e5SLawrence Mitchell 
1000c00061e5SLawrence Mitchell    Level: advanced
1001c00061e5SLawrence Mitchell 
1002db781477SPatrick Sanan .seealso: `DMCreateSubDM()`, `DMShellGetCreateSubDM()`, `DMShellSetContext()`, `DMShellGetContext()`
1003c00061e5SLawrence Mitchell @*/
1004276c5506SMatthew G. Knepley PetscErrorCode DMShellSetCreateSubDM(DM dm, PetscErrorCode (*subdm)(DM,PetscInt,const PetscInt[],IS*,DM*))
1005c00061e5SLawrence Mitchell {
1006c00061e5SLawrence Mitchell   PetscBool      isshell;
1007c00061e5SLawrence Mitchell 
1008c00061e5SLawrence Mitchell   PetscFunctionBegin;
1009c00061e5SLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10109566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
1011c00061e5SLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
1012c00061e5SLawrence Mitchell   dm->ops->createsubdm = subdm;
1013c00061e5SLawrence Mitchell   PetscFunctionReturn(0);
1014c00061e5SLawrence Mitchell }
1015c00061e5SLawrence Mitchell 
10164363ddcaSBoris Boutkov /*@C
10174363ddcaSBoris Boutkov    DMShellGetCreateSubDM - Get the routine used to create a sub DM from the shell DM
10184363ddcaSBoris Boutkov 
1019d083f849SBarry Smith    Logically Collective on dm
10204363ddcaSBoris Boutkov 
10214165533cSJose E. Roman    Input Parameter:
10224165533cSJose E. Roman .  dm - the shell DM
1023a4a986ddSBoris Boutkov 
10244165533cSJose E. Roman    Output Parameter:
10254165533cSJose E. Roman .  subdm - the routine to create the decomposition
10264363ddcaSBoris Boutkov 
10274363ddcaSBoris Boutkov    Level: advanced
10284363ddcaSBoris Boutkov 
1029db781477SPatrick Sanan .seealso: `DMCreateSubDM()`, `DMShellSetCreateSubDM()`, `DMShellSetContext()`, `DMShellGetContext()`
10304363ddcaSBoris Boutkov @*/
10314363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateSubDM(DM dm, PetscErrorCode (**subdm)(DM,PetscInt,const PetscInt[],IS*,DM*))
10324363ddcaSBoris Boutkov {
10334363ddcaSBoris Boutkov   PetscBool      isshell;
10344363ddcaSBoris Boutkov 
10354363ddcaSBoris Boutkov   PetscFunctionBegin;
10364363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10379566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell));
10387a8be351SBarry Smith   PetscCheck(isshell,PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
10394363ddcaSBoris Boutkov   *subdm = dm->ops->createsubdm;
10404363ddcaSBoris Boutkov   PetscFunctionReturn(0);
10414363ddcaSBoris Boutkov }
10424363ddcaSBoris Boutkov 
1043fe1899a2SJed Brown static PetscErrorCode DMDestroy_Shell(DM dm)
1044fe1899a2SJed Brown {
1045fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
1046fe1899a2SJed Brown 
1047fe1899a2SJed Brown   PetscFunctionBegin;
10489566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&shell->A));
10499566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xglobal));
10509566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&shell->Xlocal));
10519566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->gtol));
10529566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltog));
10539566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&shell->ltol));
10547b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
10559566063dSJacob Faibussowitsch   PetscCall(PetscFree(shell));
1056fe1899a2SJed Brown   PetscFunctionReturn(0);
1057fe1899a2SJed Brown }
1058fe1899a2SJed Brown 
10592d53ad75SBarry Smith static PetscErrorCode DMView_Shell(DM dm,PetscViewer v)
10602d53ad75SBarry Smith {
10612d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
10622d53ad75SBarry Smith 
10632d53ad75SBarry Smith   PetscFunctionBegin;
1064*01f8681bSStefano Zampini   if (shell->Xglobal) PetscCall(VecView(shell->Xglobal,v));
10652d53ad75SBarry Smith   PetscFunctionReturn(0);
10662d53ad75SBarry Smith }
10672d53ad75SBarry Smith 
10682d53ad75SBarry Smith static PetscErrorCode DMLoad_Shell(DM dm,PetscViewer v)
10692d53ad75SBarry Smith {
10702d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
10712d53ad75SBarry Smith 
10722d53ad75SBarry Smith   PetscFunctionBegin;
10739566063dSJacob Faibussowitsch   PetscCall(VecCreate(PetscObjectComm((PetscObject)dm),&shell->Xglobal));
10749566063dSJacob Faibussowitsch   PetscCall(VecLoad(shell->Xglobal,v));
10752d53ad75SBarry Smith   PetscFunctionReturn(0);
10762d53ad75SBarry Smith }
1077fe1899a2SJed Brown 
1078276c5506SMatthew G. Knepley PetscErrorCode DMCreateSubDM_Shell(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm)
10796e44b4cfSMatthew G. Knepley {
10806e44b4cfSMatthew G. Knepley   PetscFunctionBegin;
10819566063dSJacob Faibussowitsch   if (subdm) PetscCall(DMShellCreate(PetscObjectComm((PetscObject) dm), subdm));
10829566063dSJacob Faibussowitsch   PetscCall(DMCreateSectionSubDM(dm, numFields, fields, is, subdm));
10836e44b4cfSMatthew G. Knepley   PetscFunctionReturn(0);
10846e44b4cfSMatthew G. Knepley }
10856e44b4cfSMatthew G. Knepley 
10868cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm)
1087fe1899a2SJed Brown {
1088fe1899a2SJed Brown   DM_Shell       *shell;
1089fe1899a2SJed Brown 
1090fe1899a2SJed Brown   PetscFunctionBegin;
10919566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(dm,&shell));
10928c87107bSJed Brown   dm->data = shell;
1093fe1899a2SJed Brown 
10948c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
10958c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
1096dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
10978c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
10982d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
10992d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
11007a108d1dSBarry Smith   dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell;
11017a108d1dSBarry Smith   dm->ops->globaltolocalend   = DMGlobalToLocalEndDefaultShell;
110255daaa54SRichard Tran Mills   dm->ops->localtoglobalbegin = DMLocalToGlobalBeginDefaultShell;
110355daaa54SRichard Tran Mills   dm->ops->localtoglobalend   = DMLocalToGlobalEndDefaultShell;
110463731094SRichard Tran Mills   dm->ops->localtolocalbegin  = DMLocalToLocalBeginDefaultShell;
110563731094SRichard Tran Mills   dm->ops->localtolocalend    = DMLocalToLocalEndDefaultShell;
11066e44b4cfSMatthew G. Knepley   dm->ops->createsubdm        = DMCreateSubDM_Shell;
11079566063dSJacob Faibussowitsch   PetscCall(DMSetMatType(dm,MATDENSE));
1108fe1899a2SJed Brown   PetscFunctionReturn(0);
1109fe1899a2SJed Brown }
1110fe1899a2SJed Brown 
1111fe1899a2SJed Brown /*@
1112fe1899a2SJed Brown     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
1113fe1899a2SJed Brown 
1114d083f849SBarry Smith     Collective
1115fe1899a2SJed Brown 
1116fe1899a2SJed Brown     Input Parameter:
1117fe1899a2SJed Brown .   comm - the processors that will share the global vector
1118fe1899a2SJed Brown 
1119fe1899a2SJed Brown     Output Parameters:
1120fe1899a2SJed Brown .   shell - the shell DM
1121fe1899a2SJed Brown 
1122fe1899a2SJed Brown     Level: advanced
1123fe1899a2SJed Brown 
1124db781477SPatrick Sanan .seealso `DMDestroy()`, `DMCreateGlobalVector()`, `DMCreateLocalVector()`, `DMShellSetContext()`, `DMShellGetContext()`
1125fe1899a2SJed Brown @*/
1126fe1899a2SJed Brown PetscErrorCode  DMShellCreate(MPI_Comm comm,DM *dm)
1127fe1899a2SJed Brown {
1128fe1899a2SJed Brown   PetscFunctionBegin;
1129fe1899a2SJed Brown   PetscValidPointer(dm,2);
11309566063dSJacob Faibussowitsch   PetscCall(DMCreate(comm,dm));
11319566063dSJacob Faibussowitsch   PetscCall(DMSetType(*dm,DMSHELL));
11329566063dSJacob Faibussowitsch   PetscCall(DMSetUp(*dm));
1133fe1899a2SJed Brown   PetscFunctionReturn(0);
1134fe1899a2SJed Brown }
1135