xref: /petsc/src/dm/impls/shell/dmshell.c (revision 04d741b103f946af7eda6f0c9812d859beb8fccc)
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 
198d359177SBarry Smith    Input Arguments:
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 
297a108d1dSBarry Smith .seealso: DMGlobalToLocalEndDefaultShell()
308d359177SBarry Smith @*/
317a108d1dSBarry Smith PetscErrorCode DMGlobalToLocalBeginDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
328d359177SBarry Smith {
338d359177SBarry Smith   PetscErrorCode ierr;
348d359177SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
358d359177SBarry Smith 
368d359177SBarry Smith   PetscFunctionBegin;
377a108d1dSBarry Smith   if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
38a94b16f6SRichard Tran Mills   ierr = VecScatterBegin(shell->gtol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
398d359177SBarry Smith   PetscFunctionReturn(0);
408d359177SBarry Smith }
418d359177SBarry Smith 
427a108d1dSBarry Smith /*@
437a108d1dSBarry Smith    DMGlobalToLocalEndDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to end a global to local scatter
448d359177SBarry Smith    Collective
458d359177SBarry Smith 
468d359177SBarry Smith    Input Arguments:
478d359177SBarry Smith +  dm - shell DM
488d359177SBarry Smith .  g - global vector
498d359177SBarry Smith .  mode - InsertMode
508d359177SBarry Smith -  l - local vector
518d359177SBarry Smith 
527a108d1dSBarry Smith    Level: advanced
538d359177SBarry Smith 
547a108d1dSBarry Smith .seealso: DMGlobalToLocalBeginDefaultShell()
558d359177SBarry Smith @*/
567a108d1dSBarry Smith PetscErrorCode DMGlobalToLocalEndDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
578d359177SBarry Smith {
588d359177SBarry Smith   PetscErrorCode ierr;
598d359177SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
608d359177SBarry Smith 
618d359177SBarry Smith   PetscFunctionBegin;
627a108d1dSBarry Smith    if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
63a94b16f6SRichard Tran Mills   ierr = VecScatterEnd(shell->gtol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
648d359177SBarry Smith   PetscFunctionReturn(0);
658d359177SBarry Smith }
668d359177SBarry Smith 
67c5076b69SRichard Tran Mills /*@
68c5076b69SRichard Tran Mills    DMLocalToGlobalBeginDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to begin a local to global scatter
69c5076b69SRichard Tran Mills    Collective
70c5076b69SRichard Tran Mills 
71c5076b69SRichard Tran Mills    Input Arguments:
72c5076b69SRichard Tran Mills +  dm - shell DM
73c5076b69SRichard Tran Mills .  l - local vector
74c5076b69SRichard Tran Mills .  mode - InsertMode
75c5076b69SRichard Tran Mills -  g - global vector
76c5076b69SRichard Tran Mills 
77c5076b69SRichard Tran Mills    Level: advanced
78c5076b69SRichard Tran Mills 
79c5076b69SRichard 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.
80c5076b69SRichard Tran Mills 
81c5076b69SRichard Tran Mills .seealso: DMLocalToGlobalEndDefaultShell()
82c5076b69SRichard Tran Mills @*/
83c5076b69SRichard Tran Mills PetscErrorCode DMLocalToGlobalBeginDefaultShell(DM dm,Vec l,InsertMode mode,Vec g)
84c5076b69SRichard Tran Mills {
85c5076b69SRichard Tran Mills   PetscErrorCode ierr;
86c5076b69SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
87c5076b69SRichard Tran Mills 
88c5076b69SRichard Tran Mills   PetscFunctionBegin;
89c5076b69SRichard Tran Mills   if (!shell->ltog) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
90a94b16f6SRichard Tran Mills   ierr = VecScatterBegin(shell->ltog,l,g,mode,SCATTER_FORWARD);CHKERRQ(ierr);
91c5076b69SRichard Tran Mills   PetscFunctionReturn(0);
92c5076b69SRichard Tran Mills }
93c5076b69SRichard Tran Mills 
94c5076b69SRichard Tran Mills /*@
95c5076b69SRichard Tran Mills    DMLocalToGlobalEndDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to end a local to global scatter
96c5076b69SRichard Tran Mills    Collective
97c5076b69SRichard Tran Mills 
98c5076b69SRichard Tran Mills    Input Arguments:
99c5076b69SRichard Tran Mills +  dm - shell DM
100c5076b69SRichard Tran Mills .  l - local vector
101c5076b69SRichard Tran Mills .  mode - InsertMode
102c5076b69SRichard Tran Mills -  g - global vector
103c5076b69SRichard Tran Mills 
104c5076b69SRichard Tran Mills    Level: advanced
105c5076b69SRichard Tran Mills 
106c5076b69SRichard Tran Mills .seealso: DMLocalToGlobalBeginDefaultShell()
107c5076b69SRichard Tran Mills @*/
108c5076b69SRichard Tran Mills PetscErrorCode DMLocalToGlobalEndDefaultShell(DM dm,Vec l,InsertMode mode,Vec g)
109c5076b69SRichard Tran Mills {
110c5076b69SRichard Tran Mills   PetscErrorCode ierr;
111c5076b69SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
112c5076b69SRichard Tran Mills 
113c5076b69SRichard Tran Mills   PetscFunctionBegin;
114c5076b69SRichard Tran Mills    if (!shell->ltog) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
115a94b16f6SRichard Tran Mills   ierr = VecScatterEnd(shell->ltog,l,g,mode,SCATTER_FORWARD);CHKERRQ(ierr);
116c5076b69SRichard Tran Mills   PetscFunctionReturn(0);
117c5076b69SRichard Tran Mills }
118c5076b69SRichard Tran Mills 
119f3db62a7SRichard Tran Mills /*@
120f3db62a7SRichard Tran Mills    DMLocalToLocalBeginDefaultShell - Uses the LocalToLocal VecScatter context set by the user to begin a local to local scatter
121f3db62a7SRichard Tran Mills    Collective
122f3db62a7SRichard Tran Mills 
123f3db62a7SRichard Tran Mills    Input Arguments:
124f3db62a7SRichard Tran Mills +  dm - shell DM
125f3db62a7SRichard Tran Mills .  g - the original local vector
126f3db62a7SRichard Tran Mills -  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 
133f3db62a7SRichard 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.
134f3db62a7SRichard Tran Mills 
135f3db62a7SRichard Tran Mills .seealso: DMLocalToLocalEndDefaultShell()
136f3db62a7SRichard Tran Mills @*/
137f3db62a7SRichard Tran Mills PetscErrorCode DMLocalToLocalBeginDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
138f3db62a7SRichard Tran Mills {
139f3db62a7SRichard Tran Mills   PetscErrorCode ierr;
140f3db62a7SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
141f3db62a7SRichard Tran Mills 
142f3db62a7SRichard Tran Mills   PetscFunctionBegin;
143f3db62a7SRichard Tran Mills   if (!shell->ltol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToLocalVecScatter()");
144f3db62a7SRichard Tran Mills   ierr = VecScatterBegin(shell->ltol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
145f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
146f3db62a7SRichard Tran Mills }
147f3db62a7SRichard Tran Mills 
148f3db62a7SRichard Tran Mills /*@
149f3db62a7SRichard Tran Mills    DMLocalToLocalEndDefaultShell - Uses the LocalToLocal VecScatter context set by the user to end a local to local scatter
150f3db62a7SRichard Tran Mills    Collective
151f3db62a7SRichard Tran Mills 
152f3db62a7SRichard Tran Mills    Input Arguments:
153f3db62a7SRichard Tran Mills +  dm - shell DM
154f3db62a7SRichard Tran Mills .  g - the original local vector
155f3db62a7SRichard Tran Mills -  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 
162f3db62a7SRichard Tran Mills .seealso: DMLocalToLocalBeginDefaultShell()
163f3db62a7SRichard Tran Mills @*/
164f3db62a7SRichard Tran Mills PetscErrorCode DMLocalToLocalEndDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
165f3db62a7SRichard Tran Mills {
166f3db62a7SRichard Tran Mills   PetscErrorCode ierr;
167f3db62a7SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
168f3db62a7SRichard Tran Mills 
169f3db62a7SRichard Tran Mills   PetscFunctionBegin;
170f3db62a7SRichard Tran Mills    if (!shell->ltol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
171f3db62a7SRichard Tran Mills   ierr = VecScatterEnd(shell->ltol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
172f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
173f3db62a7SRichard Tran Mills }
174c5076b69SRichard Tran Mills 
175b412c318SBarry Smith static PetscErrorCode DMCreateMatrix_Shell(DM dm,Mat *J)
176fe1899a2SJed Brown {
177fe1899a2SJed Brown   PetscErrorCode ierr;
178fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
179fe1899a2SJed Brown   Mat            A;
180fe1899a2SJed Brown 
181fe1899a2SJed Brown   PetscFunctionBegin;
182fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
183fe1899a2SJed Brown   PetscValidPointer(J,3);
1847bde9f88SJed Brown   if (!shell->A) {
1857bde9f88SJed Brown     if (shell->Xglobal) {
1867bde9f88SJed Brown       PetscInt m,M;
187955c1f14SBarry Smith       ierr = PetscInfo(dm,"Naively creating matrix using global vector distribution without preallocation\n");CHKERRQ(ierr);
1887bde9f88SJed Brown       ierr = VecGetSize(shell->Xglobal,&M);CHKERRQ(ierr);
1897bde9f88SJed Brown       ierr = VecGetLocalSize(shell->Xglobal,&m);CHKERRQ(ierr);
190ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)dm),&shell->A);CHKERRQ(ierr);
1917bde9f88SJed Brown       ierr = MatSetSizes(shell->A,m,m,M,M);CHKERRQ(ierr);
192b412c318SBarry Smith       ierr = MatSetType(shell->A,dm->mattype);CHKERRQ(ierr);
1937bde9f88SJed Brown       ierr = MatSetUp(shell->A);CHKERRQ(ierr);
194ce94432eSBarry Smith     } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector");
1957bde9f88SJed Brown   }
196fe1899a2SJed Brown   A = shell->A;
19706f803f6SStefano Zampini   ierr = MatDuplicate(A,MAT_SHARE_NONZERO_PATTERN,J);CHKERRQ(ierr);
19806f803f6SStefano Zampini   ierr = MatSetDM(*J,dm);CHKERRQ(ierr);
199fe1899a2SJed Brown   PetscFunctionReturn(0);
200fe1899a2SJed Brown }
201fe1899a2SJed Brown 
202fe1899a2SJed Brown PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec)
203fe1899a2SJed Brown {
204fe1899a2SJed Brown   PetscErrorCode ierr;
205fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
206fe1899a2SJed Brown   Vec            X;
207fe1899a2SJed Brown 
208fe1899a2SJed Brown   PetscFunctionBegin;
209fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
210fe1899a2SJed Brown   PetscValidPointer(gvec,2);
211ea78f98cSLisandro Dalcin   *gvec = NULL;
212fe1899a2SJed Brown   X     = shell->Xglobal;
213ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
21406f803f6SStefano Zampini   /* Need to create a copy in order to attach the DM to the vector */
215fe1899a2SJed Brown   ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
216fe1899a2SJed Brown   ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
217c688c046SMatthew G Knepley   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
218fe1899a2SJed Brown   PetscFunctionReturn(0);
219fe1899a2SJed Brown }
220fe1899a2SJed Brown 
221dc43b69eSJed Brown PetscErrorCode DMCreateLocalVector_Shell(DM dm,Vec *gvec)
222dc43b69eSJed Brown {
223dc43b69eSJed Brown   PetscErrorCode ierr;
224dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
225dc43b69eSJed Brown   Vec            X;
226dc43b69eSJed Brown 
227dc43b69eSJed Brown   PetscFunctionBegin;
228dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
229dc43b69eSJed Brown   PetscValidPointer(gvec,2);
230ea78f98cSLisandro Dalcin   *gvec = NULL;
231dc43b69eSJed Brown   X     = shell->Xlocal;
232ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()");
23306f803f6SStefano Zampini   /* Need to create a copy in order to attach the DM to the vector */
234dc43b69eSJed Brown   ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
235dc43b69eSJed Brown   ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
2366e4cbd8bSMark F. Adams   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
237dc43b69eSJed Brown   PetscFunctionReturn(0);
238dc43b69eSJed Brown }
239dc43b69eSJed Brown 
240fef3a512SBarry Smith /*@
241fef3a512SBarry Smith    DMShellSetContext - set some data to be usable by this DM
242fef3a512SBarry Smith 
243fef3a512SBarry Smith    Collective
244fef3a512SBarry Smith 
245fef3a512SBarry Smith    Input Arguments:
246fef3a512SBarry Smith +  dm - shell DM
247fef3a512SBarry Smith -  ctx - the context
248fef3a512SBarry Smith 
249fef3a512SBarry Smith    Level: advanced
250fef3a512SBarry Smith 
251fef3a512SBarry Smith .seealso: DMCreateMatrix(), DMShellGetContext()
252fef3a512SBarry Smith @*/
253fef3a512SBarry Smith PetscErrorCode DMShellSetContext(DM dm,void *ctx)
254fef3a512SBarry Smith {
255fef3a512SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
256fef3a512SBarry Smith   PetscErrorCode ierr;
257fef3a512SBarry Smith   PetscBool      isshell;
258fef3a512SBarry Smith 
259fef3a512SBarry Smith   PetscFunctionBegin;
260fef3a512SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
261fef3a512SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
262fef3a512SBarry Smith   if (!isshell) PetscFunctionReturn(0);
263fef3a512SBarry Smith   shell->ctx = ctx;
264fef3a512SBarry Smith   PetscFunctionReturn(0);
265fef3a512SBarry Smith }
266fef3a512SBarry Smith 
267fef3a512SBarry Smith /*@
268bf890c61SBoris Boutkov    DMShellGetContext - Returns the user-provided context associated to the DM
269fef3a512SBarry Smith 
270fef3a512SBarry Smith    Collective
271fef3a512SBarry Smith 
272fef3a512SBarry Smith    Input Argument:
273fef3a512SBarry Smith .  dm - shell DM
274fef3a512SBarry Smith 
275fef3a512SBarry Smith    Output Argument:
276fef3a512SBarry Smith .  ctx - the context
277fef3a512SBarry Smith 
278fef3a512SBarry Smith    Level: advanced
279fef3a512SBarry Smith 
280fef3a512SBarry Smith .seealso: DMCreateMatrix(), DMShellSetContext()
281fef3a512SBarry Smith @*/
282fef3a512SBarry Smith PetscErrorCode DMShellGetContext(DM dm,void **ctx)
283fef3a512SBarry Smith {
284fef3a512SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
285fef3a512SBarry Smith   PetscErrorCode ierr;
286fef3a512SBarry Smith   PetscBool      isshell;
287fef3a512SBarry Smith 
288fef3a512SBarry Smith   PetscFunctionBegin;
289fef3a512SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
290fef3a512SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
2918dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
292fef3a512SBarry Smith   *ctx = shell->ctx;
293fef3a512SBarry Smith   PetscFunctionReturn(0);
294fef3a512SBarry Smith }
295fef3a512SBarry Smith 
296fe1899a2SJed Brown /*@
297fe1899a2SJed Brown    DMShellSetMatrix - sets a template matrix associated with the DMShell
298fe1899a2SJed Brown 
299fe1899a2SJed Brown    Collective
300fe1899a2SJed Brown 
301fe1899a2SJed Brown    Input Arguments:
302fe1899a2SJed Brown +  dm - shell DM
303fe1899a2SJed Brown -  J - template matrix
304fe1899a2SJed Brown 
305fe1899a2SJed Brown    Level: advanced
306fe1899a2SJed Brown 
30706f803f6SStefano Zampini    Developer Notes:
30806f803f6SStefano 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.
30906f803f6SStefano Zampini 
310fef3a512SBarry Smith .seealso: DMCreateMatrix(), DMShellSetCreateMatrix(), DMShellSetContext(), DMShellGetContext()
311fe1899a2SJed Brown @*/
312fe1899a2SJed Brown PetscErrorCode DMShellSetMatrix(DM dm,Mat J)
313fe1899a2SJed Brown {
314fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
315fe1899a2SJed Brown   PetscErrorCode ierr;
3168c87107bSJed Brown   PetscBool      isshell;
31706f803f6SStefano Zampini   DM             mdm;
318fe1899a2SJed Brown 
319fe1899a2SJed Brown   PetscFunctionBegin;
3208c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3218c87107bSJed Brown   PetscValidHeaderSpecific(J,MAT_CLASSID,2);
322251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
3238c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
32406f803f6SStefano Zampini   if (J == shell->A) PetscFunctionReturn(0);
32506f803f6SStefano Zampini   ierr = MatGetDM(J,&mdm);CHKERRQ(ierr);
326fe1899a2SJed Brown   ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
327fe1899a2SJed Brown   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
32806f803f6SStefano Zampini   if (mdm == dm) {
32906f803f6SStefano Zampini     ierr = MatDuplicate(J,MAT_SHARE_NONZERO_PATTERN,&shell->A);CHKERRQ(ierr);
33006f803f6SStefano Zampini     ierr = MatSetDM(shell->A,NULL);CHKERRQ(ierr);
33106f803f6SStefano Zampini   } else shell->A = J;
332fe1899a2SJed Brown   PetscFunctionReturn(0);
333fe1899a2SJed Brown }
334fe1899a2SJed Brown 
335fe1899a2SJed Brown /*@C
336fe1899a2SJed Brown    DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM
337fe1899a2SJed Brown 
338d083f849SBarry Smith    Logically Collective on dm
339fe1899a2SJed Brown 
340fe1899a2SJed Brown    Input Arguments:
341fe1899a2SJed Brown +  dm - the shell DM
342fe1899a2SJed Brown -  func - the function to create a matrix
343fe1899a2SJed Brown 
344fe1899a2SJed Brown    Level: advanced
345fe1899a2SJed Brown 
346fef3a512SBarry Smith .seealso: DMCreateMatrix(), DMShellSetMatrix(), DMShellSetContext(), DMShellGetContext()
347fe1899a2SJed Brown @*/
348b412c318SBarry Smith PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,Mat*))
349fe1899a2SJed Brown {
350fe1899a2SJed Brown   PetscFunctionBegin;
351fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
352fe1899a2SJed Brown   dm->ops->creatematrix = func;
353fe1899a2SJed Brown   PetscFunctionReturn(0);
354fe1899a2SJed Brown }
355fe1899a2SJed Brown 
356fe1899a2SJed Brown /*@
357fe1899a2SJed Brown    DMShellSetGlobalVector - sets a template global vector associated with the DMShell
358fe1899a2SJed Brown 
359d083f849SBarry Smith    Logically Collective on dm
360fe1899a2SJed Brown 
361fe1899a2SJed Brown    Input Arguments:
362fe1899a2SJed Brown +  dm - shell DM
363fe1899a2SJed Brown -  X - template vector
364fe1899a2SJed Brown 
365fe1899a2SJed Brown    Level: advanced
366fe1899a2SJed Brown 
367fe1899a2SJed Brown .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector()
368fe1899a2SJed Brown @*/
369fe1899a2SJed Brown PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X)
370fe1899a2SJed Brown {
371fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
372fe1899a2SJed Brown   PetscErrorCode ierr;
3738c87107bSJed Brown   PetscBool      isshell;
374cca7ec1eSBarry Smith   DM             vdm;
375fe1899a2SJed Brown 
376fe1899a2SJed Brown   PetscFunctionBegin;
3778c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3788c87107bSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
379251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
3808c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
381cca7ec1eSBarry Smith   ierr = VecGetDM(X,&vdm);CHKERRQ(ierr);
382cca7ec1eSBarry Smith   /*
383cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
384cca7ec1eSBarry 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
385cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
386cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
387cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
388cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
389cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
390cca7ec1eSBarry Smith       for pointing out the problem.
391cca7ec1eSBarry Smith    */
392cca7ec1eSBarry Smith   if (vdm == dm) PetscFunctionReturn(0);
393fe1899a2SJed Brown   ierr           = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
394fe1899a2SJed Brown   ierr           = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
395fe1899a2SJed Brown   shell->Xglobal = X;
396fe1899a2SJed Brown   PetscFunctionReturn(0);
397fe1899a2SJed Brown }
398fe1899a2SJed Brown 
399*04d741b1SMatthew G. Knepley /*@
400*04d741b1SMatthew G. Knepley   DMShellGetGlobalVector - Returns the template global vector associated with the DMShell, or NULL if it was not set
401*04d741b1SMatthew G. Knepley 
402*04d741b1SMatthew G. Knepley    Not collective
403*04d741b1SMatthew G. Knepley 
404*04d741b1SMatthew G. Knepley    Input Arguments:
405*04d741b1SMatthew G. Knepley +  dm - shell DM
406*04d741b1SMatthew G. Knepley -  X - template vector
407*04d741b1SMatthew G. Knepley 
408*04d741b1SMatthew G. Knepley    Level: advanced
409*04d741b1SMatthew G. Knepley 
410*04d741b1SMatthew G. Knepley .seealso: DMShellSetGlobalVector(), DMShellSetCreateGlobalVector(), DMCreateGlobalVector()
411*04d741b1SMatthew G. Knepley @*/
412*04d741b1SMatthew G. Knepley PetscErrorCode DMShellGetGlobalVector(DM dm, Vec *X)
413*04d741b1SMatthew G. Knepley {
414*04d741b1SMatthew G. Knepley   DM_Shell      *shell = (DM_Shell *) dm->data;
415*04d741b1SMatthew G. Knepley   PetscBool      isshell;
416*04d741b1SMatthew G. Knepley   PetscErrorCode ierr;
417*04d741b1SMatthew G. Knepley 
418*04d741b1SMatthew G. Knepley   PetscFunctionBegin;
419*04d741b1SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
420*04d741b1SMatthew G. Knepley   PetscValidPointer(X,2);
421*04d741b1SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
422*04d741b1SMatthew G. Knepley   if (!isshell) PetscFunctionReturn(0);
423*04d741b1SMatthew G. Knepley   *X = shell->Xglobal;
424*04d741b1SMatthew G. Knepley   PetscFunctionReturn(0);
425*04d741b1SMatthew G. Knepley }
426*04d741b1SMatthew G. Knepley 
427fe1899a2SJed Brown /*@C
428fe1899a2SJed Brown    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM
429fe1899a2SJed Brown 
430fe1899a2SJed Brown    Logically Collective
431fe1899a2SJed Brown 
432fe1899a2SJed Brown    Input Arguments:
433fe1899a2SJed Brown +  dm - the shell DM
434fe1899a2SJed Brown -  func - the creation routine
435fe1899a2SJed Brown 
436fe1899a2SJed Brown    Level: advanced
437fe1899a2SJed Brown 
438fef3a512SBarry Smith .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix(), DMShellSetContext(), DMShellGetContext()
439fe1899a2SJed Brown @*/
440fe1899a2SJed Brown PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
441fe1899a2SJed Brown {
442fe1899a2SJed Brown   PetscFunctionBegin;
443fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
444fe1899a2SJed Brown   dm->ops->createglobalvector = func;
445fe1899a2SJed Brown   PetscFunctionReturn(0);
446fe1899a2SJed Brown }
447fe1899a2SJed Brown 
448dc43b69eSJed Brown /*@
449dc43b69eSJed Brown    DMShellSetLocalVector - sets a template local vector associated with the DMShell
450dc43b69eSJed Brown 
451d083f849SBarry Smith    Logically Collective on dm
452dc43b69eSJed Brown 
453dc43b69eSJed Brown    Input Arguments:
454dc43b69eSJed Brown +  dm - shell DM
455dc43b69eSJed Brown -  X - template vector
456dc43b69eSJed Brown 
457dc43b69eSJed Brown    Level: advanced
458dc43b69eSJed Brown 
459dc43b69eSJed Brown .seealso: DMCreateLocalVector(), DMShellSetMatrix(), DMShellSetCreateLocalVector()
460dc43b69eSJed Brown @*/
461dc43b69eSJed Brown PetscErrorCode DMShellSetLocalVector(DM dm,Vec X)
462dc43b69eSJed Brown {
463dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
464dc43b69eSJed Brown   PetscErrorCode ierr;
465dc43b69eSJed Brown   PetscBool      isshell;
466cca7ec1eSBarry Smith   DM             vdm;
467dc43b69eSJed Brown 
468dc43b69eSJed Brown   PetscFunctionBegin;
469dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
470dc43b69eSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
471dc43b69eSJed Brown   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
472dc43b69eSJed Brown   if (!isshell) PetscFunctionReturn(0);
473cca7ec1eSBarry Smith   ierr = VecGetDM(X,&vdm);CHKERRQ(ierr);
474cca7ec1eSBarry Smith   /*
475cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
476cca7ec1eSBarry 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
477cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
478cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
479cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
480cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
481cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
482cca7ec1eSBarry Smith       for pointing out the problem.
483cca7ec1eSBarry Smith    */
484cca7ec1eSBarry Smith   if (vdm == dm) PetscFunctionReturn(0);
485dc43b69eSJed Brown   ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
486dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
487dc43b69eSJed Brown   shell->Xlocal = X;
488dc43b69eSJed Brown   PetscFunctionReturn(0);
489dc43b69eSJed Brown }
490dc43b69eSJed Brown 
491dc43b69eSJed Brown /*@C
492dc43b69eSJed Brown    DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM
493dc43b69eSJed Brown 
494dc43b69eSJed Brown    Logically Collective
495dc43b69eSJed Brown 
496dc43b69eSJed Brown    Input Arguments:
497dc43b69eSJed Brown +  dm - the shell DM
498dc43b69eSJed Brown -  func - the creation routine
499dc43b69eSJed Brown 
500dc43b69eSJed Brown    Level: advanced
501dc43b69eSJed Brown 
502fef3a512SBarry Smith .seealso: DMShellSetLocalVector(), DMShellSetCreateMatrix(), DMShellSetContext(), DMShellGetContext()
503dc43b69eSJed Brown @*/
504dc43b69eSJed Brown PetscErrorCode DMShellSetCreateLocalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
505dc43b69eSJed Brown {
506dc43b69eSJed Brown   PetscFunctionBegin;
507dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
508dc43b69eSJed Brown   dm->ops->createlocalvector = func;
509dc43b69eSJed Brown   PetscFunctionReturn(0);
510dc43b69eSJed Brown }
511dc43b69eSJed Brown 
5128339e6d0SRichard Tran Mills /*@C
5138339e6d0SRichard Tran Mills    DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter
5148339e6d0SRichard Tran Mills 
515d083f849SBarry Smith    Logically Collective on dm
5168339e6d0SRichard Tran Mills 
5178339e6d0SRichard Tran Mills    Input Arguments
5188339e6d0SRichard Tran Mills +  dm - the shell DM
5198339e6d0SRichard Tran Mills .  begin - the routine that begins the global to local scatter
5208339e6d0SRichard Tran Mills -  end - the routine that ends the global to local scatter
5218339e6d0SRichard Tran Mills 
52295452b02SPatrick Sanan    Notes:
52395452b02SPatrick Sanan     If these functions are not provided but DMShellSetGlobalToLocalVecScatter() is called then
524f3db62a7SRichard Tran Mills    DMGlobalToLocalBeginDefaultShell()/DMGlobalToLocalEndDefaultShell() are used to to perform the transfers
5257a108d1dSBarry Smith 
5268339e6d0SRichard Tran Mills    Level: advanced
5278339e6d0SRichard Tran Mills 
5287a108d1dSBarry Smith .seealso: DMShellSetLocalToGlobal(), DMGlobalToLocalBeginDefaultShell(), DMGlobalToLocalEndDefaultShell()
5298339e6d0SRichard Tran Mills @*/
530bdb10af2SPierre Jolivet PetscErrorCode DMShellSetGlobalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec))
531bdb10af2SPierre Jolivet {
5328339e6d0SRichard Tran Mills   PetscFunctionBegin;
5332d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5348339e6d0SRichard Tran Mills   dm->ops->globaltolocalbegin = begin;
5358339e6d0SRichard Tran Mills   dm->ops->globaltolocalend = end;
5368339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
5378339e6d0SRichard Tran Mills }
5388339e6d0SRichard Tran Mills 
5398339e6d0SRichard Tran Mills /*@C
5408339e6d0SRichard Tran Mills    DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter
5418339e6d0SRichard Tran Mills 
542d083f849SBarry Smith    Logically Collective on dm
5438339e6d0SRichard Tran Mills 
5448339e6d0SRichard Tran Mills    Input Arguments
5458339e6d0SRichard Tran Mills +  dm - the shell DM
5468339e6d0SRichard Tran Mills .  begin - the routine that begins the local to global scatter
5478339e6d0SRichard Tran Mills -  end - the routine that ends the local to global scatter
5488339e6d0SRichard Tran Mills 
54995452b02SPatrick Sanan    Notes:
55095452b02SPatrick Sanan     If these functions are not provided but DMShellSetLocalToGlobalVecScatter() is called then
551f3db62a7SRichard Tran Mills    DMLocalToGlobalBeginDefaultShell()/DMLocalToGlobalEndDefaultShell() are used to to perform the transfers
552f3db62a7SRichard Tran Mills 
5538339e6d0SRichard Tran Mills    Level: advanced
5548339e6d0SRichard Tran Mills 
5558339e6d0SRichard Tran Mills .seealso: DMShellSetGlobalToLocal()
5568339e6d0SRichard Tran Mills @*/
557bdb10af2SPierre Jolivet PetscErrorCode DMShellSetLocalToGlobal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec))
558bdb10af2SPierre Jolivet {
5598339e6d0SRichard Tran Mills   PetscFunctionBegin;
5602d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5618339e6d0SRichard Tran Mills   dm->ops->localtoglobalbegin = begin;
5628339e6d0SRichard Tran Mills   dm->ops->localtoglobalend = end;
5638339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
5648339e6d0SRichard Tran Mills }
5658339e6d0SRichard Tran Mills 
566f3db62a7SRichard Tran Mills /*@C
567f3db62a7SRichard Tran Mills    DMShellSetLocalToLocal - Sets the routines used to perform a local to local scatter
568f3db62a7SRichard Tran Mills 
569d083f849SBarry Smith    Logically Collective on dm
570f3db62a7SRichard Tran Mills 
571f3db62a7SRichard Tran Mills    Input Arguments
572f3db62a7SRichard Tran Mills +  dm - the shell DM
573f3db62a7SRichard Tran Mills .  begin - the routine that begins the local to local scatter
574f3db62a7SRichard Tran Mills -  end - the routine that ends the local to local scatter
575f3db62a7SRichard Tran Mills 
57695452b02SPatrick Sanan    Notes:
57795452b02SPatrick Sanan     If these functions are not provided but DMShellSetLocalToLocalVecScatter() is called then
578f3db62a7SRichard Tran Mills    DMLocalToLocalBeginDefaultShell()/DMLocalToLocalEndDefaultShell() are used to to perform the transfers
579f3db62a7SRichard Tran Mills 
580f3db62a7SRichard Tran Mills    Level: advanced
581f3db62a7SRichard Tran Mills 
582f3db62a7SRichard Tran Mills .seealso: DMShellSetGlobalToLocal(), DMLocalToLocalBeginDefaultShell(), DMLocalToLocalEndDefaultShell()
583f3db62a7SRichard Tran Mills @*/
584bdb10af2SPierre Jolivet PetscErrorCode DMShellSetLocalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec))
585bdb10af2SPierre Jolivet {
586f3db62a7SRichard Tran Mills   PetscFunctionBegin;
5872d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
588f3db62a7SRichard Tran Mills   dm->ops->localtolocalbegin = begin;
589f3db62a7SRichard Tran Mills   dm->ops->localtolocalend = end;
590f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
591f3db62a7SRichard Tran Mills }
592f3db62a7SRichard Tran Mills 
59381634712SRichard Tran Mills /*@
59481634712SRichard Tran Mills    DMShellSetGlobalToLocalVecScatter - Sets a VecScatter context for global to local communication
59581634712SRichard Tran Mills 
596d083f849SBarry Smith    Logically Collective on dm
59781634712SRichard Tran Mills 
59881634712SRichard Tran Mills    Input Arguments
59981634712SRichard Tran Mills +  dm - the shell DM
60081634712SRichard Tran Mills -  gtol - the global to local VecScatter context
60181634712SRichard Tran Mills 
60281634712SRichard Tran Mills    Level: advanced
60381634712SRichard Tran Mills 
604f3db62a7SRichard Tran Mills .seealso: DMShellSetGlobalToLocal(), DMGlobalToLocalBeginDefaultShell(), DMGlobalToLocalEndDefaultShell()
60581634712SRichard Tran Mills @*/
606a94b16f6SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter gtol)
60781634712SRichard Tran Mills {
60881634712SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
609d885d199SRichard Tran Mills   PetscErrorCode ierr;
61081634712SRichard Tran Mills 
611b300e4a8SRichard Tran Mills   PetscFunctionBegin;
6122d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
61397929ea7SJunchao Zhang   PetscValidHeaderSpecific(gtol,PETSCSF_CLASSID,2);
614d885d199SRichard Tran Mills   ierr = PetscObjectReference((PetscObject)gtol);CHKERRQ(ierr);
615d885d199SRichard Tran Mills   ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr);
61681634712SRichard Tran Mills   shell->gtol = gtol;
61781634712SRichard Tran Mills   PetscFunctionReturn(0);
61881634712SRichard Tran Mills }
61981634712SRichard Tran Mills 
620988ea7d6SRichard Tran Mills /*@
621988ea7d6SRichard Tran Mills    DMShellSetLocalToGlobalVecScatter - Sets a VecScatter context for local to global communication
622988ea7d6SRichard Tran Mills 
623d083f849SBarry Smith    Logically Collective on dm
624988ea7d6SRichard Tran Mills 
625988ea7d6SRichard Tran Mills    Input Arguments
626988ea7d6SRichard Tran Mills +  dm - the shell DM
627988ea7d6SRichard Tran Mills -  ltog - the local to global VecScatter context
628988ea7d6SRichard Tran Mills 
629988ea7d6SRichard Tran Mills    Level: advanced
630988ea7d6SRichard Tran Mills 
631f3db62a7SRichard Tran Mills .seealso: DMShellSetLocalToGlobal(), DMLocalToGlobalBeginDefaultShell(), DMLocalToGlobalEndDefaultShell()
632988ea7d6SRichard Tran Mills @*/
633a94b16f6SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM dm, VecScatter ltog)
634988ea7d6SRichard Tran Mills {
635988ea7d6SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
636d885d199SRichard Tran Mills   PetscErrorCode ierr;
637988ea7d6SRichard Tran Mills 
638988ea7d6SRichard Tran Mills   PetscFunctionBegin;
6392d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
64097929ea7SJunchao Zhang   PetscValidHeaderSpecific(ltog,PETSCSF_CLASSID,2);
641d885d199SRichard Tran Mills   ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr);
642d885d199SRichard Tran Mills   ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr);
643988ea7d6SRichard Tran Mills   shell->ltog = ltog;
644988ea7d6SRichard Tran Mills   PetscFunctionReturn(0);
645988ea7d6SRichard Tran Mills }
646988ea7d6SRichard Tran Mills 
647f3db62a7SRichard Tran Mills /*@
648f3db62a7SRichard Tran Mills    DMShellSetLocalToLocalVecScatter - Sets a VecScatter context for local to local communication
649f3db62a7SRichard Tran Mills 
650d083f849SBarry Smith    Logically Collective on dm
651f3db62a7SRichard Tran Mills 
652f3db62a7SRichard Tran Mills    Input Arguments
653f3db62a7SRichard Tran Mills +  dm - the shell DM
654f3db62a7SRichard Tran Mills -  ltol - the local to local VecScatter context
655f3db62a7SRichard Tran Mills 
656f3db62a7SRichard Tran Mills    Level: advanced
657f3db62a7SRichard Tran Mills 
658f3db62a7SRichard Tran Mills .seealso: DMShellSetLocalToLocal(), DMLocalToLocalBeginDefaultShell(), DMLocalToLocalEndDefaultShell()
659f3db62a7SRichard Tran Mills @*/
660f3db62a7SRichard Tran Mills PetscErrorCode DMShellSetLocalToLocalVecScatter(DM dm, VecScatter ltol)
661f3db62a7SRichard Tran Mills {
662f3db62a7SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
663f3db62a7SRichard Tran Mills   PetscErrorCode ierr;
664f3db62a7SRichard Tran Mills 
665f3db62a7SRichard Tran Mills   PetscFunctionBegin;
6662d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
66797929ea7SJunchao Zhang   PetscValidHeaderSpecific(ltol,PETSCSF_CLASSID,2);
668f3db62a7SRichard Tran Mills   ierr = PetscObjectReference((PetscObject)ltol);CHKERRQ(ierr);
669f3db62a7SRichard Tran Mills   ierr = VecScatterDestroy(&shell->ltol);CHKERRQ(ierr);
670f3db62a7SRichard Tran Mills   shell->ltol = ltol;
671f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
672f3db62a7SRichard Tran Mills }
673f3db62a7SRichard Tran Mills 
6749bf9660cSLawrence Mitchell /*@C
6759bf9660cSLawrence Mitchell    DMShellSetCoarsen - Set the routine used to coarsen the shell DM
6769bf9660cSLawrence Mitchell 
677d083f849SBarry Smith    Logically Collective on dm
6789bf9660cSLawrence Mitchell 
6799bf9660cSLawrence Mitchell    Input Arguments
6809bf9660cSLawrence Mitchell +  dm - the shell DM
6819bf9660cSLawrence Mitchell -  coarsen - the routine that coarsens the DM
6829bf9660cSLawrence Mitchell 
6839bf9660cSLawrence Mitchell    Level: advanced
6849bf9660cSLawrence Mitchell 
685bf890c61SBoris Boutkov .seealso: DMShellSetRefine(), DMCoarsen(), DMShellGetCoarsen(), DMShellSetContext(), DMShellGetContext()
6869bf9660cSLawrence Mitchell @*/
687f572501eSLawrence Mitchell PetscErrorCode DMShellSetCoarsen(DM dm, PetscErrorCode (*coarsen)(DM,MPI_Comm,DM*))
688f572501eSLawrence Mitchell {
689f572501eSLawrence Mitchell   PetscErrorCode ierr;
690f572501eSLawrence Mitchell   PetscBool      isshell;
691f572501eSLawrence Mitchell 
692f572501eSLawrence Mitchell   PetscFunctionBegin;
693f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
694f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
695f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
696f572501eSLawrence Mitchell   dm->ops->coarsen = coarsen;
697f572501eSLawrence Mitchell   PetscFunctionReturn(0);
698f572501eSLawrence Mitchell }
699f572501eSLawrence Mitchell 
7009bf9660cSLawrence Mitchell /*@C
7014363ddcaSBoris Boutkov    DMShellGetCoarsen - Get the routine used to coarsen the shell DM
7024363ddcaSBoris Boutkov 
703d083f849SBarry Smith    Logically Collective on dm
7044363ddcaSBoris Boutkov 
705a4a986ddSBoris Boutkov    Input Argument:
7064363ddcaSBoris Boutkov .  dm - the shell DM
7074363ddcaSBoris Boutkov 
708a4a986ddSBoris Boutkov    Output Argument:
7094363ddcaSBoris Boutkov .  coarsen - the routine that coarsens the DM
7104363ddcaSBoris Boutkov 
7114363ddcaSBoris Boutkov    Level: advanced
7124363ddcaSBoris Boutkov 
7134363ddcaSBoris Boutkov .seealso: DMShellSetCoarsen(), DMCoarsen(), DMShellSetRefine(), DMRefine()
7144363ddcaSBoris Boutkov @*/
7154363ddcaSBoris Boutkov PetscErrorCode DMShellGetCoarsen(DM dm, PetscErrorCode (**coarsen)(DM,MPI_Comm,DM*))
7164363ddcaSBoris Boutkov {
7174363ddcaSBoris Boutkov   PetscErrorCode ierr;
7184363ddcaSBoris Boutkov   PetscBool      isshell;
7194363ddcaSBoris Boutkov 
7204363ddcaSBoris Boutkov   PetscFunctionBegin;
7214363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7224363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
7238dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
7244363ddcaSBoris Boutkov   *coarsen = dm->ops->coarsen;
7254363ddcaSBoris Boutkov   PetscFunctionReturn(0);
7264363ddcaSBoris Boutkov }
7274363ddcaSBoris Boutkov 
7284363ddcaSBoris Boutkov /*@C
7299bf9660cSLawrence Mitchell    DMShellSetRefine - Set the routine used to refine the shell DM
7309bf9660cSLawrence Mitchell 
731d083f849SBarry Smith    Logically Collective on dm
7329bf9660cSLawrence Mitchell 
7339bf9660cSLawrence Mitchell    Input Arguments
7349bf9660cSLawrence Mitchell +  dm - the shell DM
7359bf9660cSLawrence Mitchell -  refine - the routine that refines the DM
7369bf9660cSLawrence Mitchell 
7379bf9660cSLawrence Mitchell    Level: advanced
7389bf9660cSLawrence Mitchell 
739bf890c61SBoris Boutkov .seealso: DMShellSetCoarsen(), DMRefine(), DMShellGetRefine(), DMShellSetContext(), DMShellGetContext()
7409bf9660cSLawrence Mitchell @*/
741f572501eSLawrence Mitchell PetscErrorCode DMShellSetRefine(DM dm, PetscErrorCode (*refine)(DM,MPI_Comm,DM*))
742f572501eSLawrence Mitchell {
743f572501eSLawrence Mitchell   PetscErrorCode ierr;
744f572501eSLawrence Mitchell   PetscBool      isshell;
745f572501eSLawrence Mitchell 
746f572501eSLawrence Mitchell   PetscFunctionBegin;
747f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
748f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
749f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
750f572501eSLawrence Mitchell   dm->ops->refine = refine;
751f572501eSLawrence Mitchell   PetscFunctionReturn(0);
752f572501eSLawrence Mitchell }
753f572501eSLawrence Mitchell 
7549bf9660cSLawrence Mitchell /*@C
7554363ddcaSBoris Boutkov    DMShellGetRefine - Get the routine used to refine the shell DM
7564363ddcaSBoris Boutkov 
757d083f849SBarry Smith    Logically Collective on dm
7584363ddcaSBoris Boutkov 
759a4a986ddSBoris Boutkov    Input Argument:
7604363ddcaSBoris Boutkov .  dm - the shell DM
7614363ddcaSBoris Boutkov 
762a4a986ddSBoris Boutkov    Output Argument:
7634363ddcaSBoris Boutkov .  refine - the routine that refines the DM
7644363ddcaSBoris Boutkov 
7654363ddcaSBoris Boutkov    Level: advanced
7664363ddcaSBoris Boutkov 
7674363ddcaSBoris Boutkov .seealso: DMShellSetCoarsen(), DMCoarsen(), DMShellSetRefine(), DMRefine()
7684363ddcaSBoris Boutkov @*/
7694363ddcaSBoris Boutkov PetscErrorCode DMShellGetRefine(DM dm, PetscErrorCode (**refine)(DM,MPI_Comm,DM*))
7704363ddcaSBoris Boutkov {
7714363ddcaSBoris Boutkov   PetscErrorCode ierr;
7724363ddcaSBoris Boutkov   PetscBool      isshell;
7734363ddcaSBoris Boutkov 
7744363ddcaSBoris Boutkov   PetscFunctionBegin;
7754363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7764363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
7778dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
7784363ddcaSBoris Boutkov   *refine = dm->ops->refine;
7794363ddcaSBoris Boutkov   PetscFunctionReturn(0);
7804363ddcaSBoris Boutkov }
7814363ddcaSBoris Boutkov 
7824363ddcaSBoris Boutkov /*@C
7839bf9660cSLawrence Mitchell    DMShellSetCreateInterpolation - Set the routine used to create the interpolation operator
7849bf9660cSLawrence Mitchell 
785d083f849SBarry Smith    Logically Collective on dm
7869bf9660cSLawrence Mitchell 
7879bf9660cSLawrence Mitchell    Input Arguments
7889bf9660cSLawrence Mitchell +  dm - the shell DM
7899bf9660cSLawrence Mitchell -  interp - the routine to create the interpolation
7909bf9660cSLawrence Mitchell 
7919bf9660cSLawrence Mitchell    Level: advanced
7929bf9660cSLawrence Mitchell 
793bf890c61SBoris Boutkov .seealso: DMShellSetCreateInjection(), DMCreateInterpolation(), DMShellGetCreateInterpolation(), DMShellSetCreateRestriction(), DMShellSetContext(), DMShellGetContext()
7949bf9660cSLawrence Mitchell @*/
795f572501eSLawrence Mitchell PetscErrorCode DMShellSetCreateInterpolation(DM dm, PetscErrorCode (*interp)(DM,DM,Mat*,Vec*))
796f572501eSLawrence Mitchell {
797f572501eSLawrence Mitchell   PetscErrorCode ierr;
798f572501eSLawrence Mitchell   PetscBool      isshell;
799f572501eSLawrence Mitchell 
800f572501eSLawrence Mitchell   PetscFunctionBegin;
801f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
802f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
803f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
804f572501eSLawrence Mitchell   dm->ops->createinterpolation = interp;
805f572501eSLawrence Mitchell   PetscFunctionReturn(0);
806f572501eSLawrence Mitchell }
807f572501eSLawrence Mitchell 
8083ad4599aSBarry Smith /*@C
8094363ddcaSBoris Boutkov    DMShellGetCreateInterpolation - Get the routine used to create the interpolation operator
8104363ddcaSBoris Boutkov 
811d083f849SBarry Smith    Logically Collective on dm
8124363ddcaSBoris Boutkov 
813a4a986ddSBoris Boutkov    Input Argument:
8144363ddcaSBoris Boutkov +  dm - the shell DM
815a4a986ddSBoris Boutkov 
816a4a986ddSBoris Boutkov    Output Argument:
8174363ddcaSBoris Boutkov -  interp - the routine to create the interpolation
8184363ddcaSBoris Boutkov 
8194363ddcaSBoris Boutkov    Level: advanced
8204363ddcaSBoris Boutkov 
8214363ddcaSBoris Boutkov .seealso: DMShellGetCreateInjection(), DMCreateInterpolation(), DMShellGetCreateRestriction(), DMShellSetContext(), DMShellGetContext()
8224363ddcaSBoris Boutkov @*/
8234363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateInterpolation(DM dm, PetscErrorCode (**interp)(DM,DM,Mat*,Vec*))
8244363ddcaSBoris Boutkov {
8254363ddcaSBoris Boutkov   PetscErrorCode ierr;
8264363ddcaSBoris Boutkov   PetscBool      isshell;
8274363ddcaSBoris Boutkov 
8284363ddcaSBoris Boutkov   PetscFunctionBegin;
8294363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8304363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
8318dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
8324363ddcaSBoris Boutkov   *interp = dm->ops->createinterpolation;
8334363ddcaSBoris Boutkov   PetscFunctionReturn(0);
8344363ddcaSBoris Boutkov }
8354363ddcaSBoris Boutkov 
8364363ddcaSBoris Boutkov /*@C
8373ad4599aSBarry Smith    DMShellSetCreateRestriction - Set the routine used to create the restriction operator
8383ad4599aSBarry Smith 
839d083f849SBarry Smith    Logically Collective on dm
8403ad4599aSBarry Smith 
8413ad4599aSBarry Smith    Input Arguments
8423ad4599aSBarry Smith +  dm - the shell DM
8433ad4599aSBarry Smith -  striction- the routine to create the restriction
8443ad4599aSBarry Smith 
8453ad4599aSBarry Smith    Level: advanced
8463ad4599aSBarry Smith 
847bf890c61SBoris Boutkov .seealso: DMShellSetCreateInjection(), DMCreateInterpolation(), DMShellGetCreateRestriction(), DMShellSetContext(), DMShellGetContext()
8483ad4599aSBarry Smith @*/
8493ad4599aSBarry Smith PetscErrorCode DMShellSetCreateRestriction(DM dm, PetscErrorCode (*restriction)(DM,DM,Mat*))
8503ad4599aSBarry Smith {
8513ad4599aSBarry Smith   PetscErrorCode ierr;
8523ad4599aSBarry Smith   PetscBool      isshell;
8533ad4599aSBarry Smith 
8543ad4599aSBarry Smith   PetscFunctionBegin;
8553ad4599aSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8563ad4599aSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
8573ad4599aSBarry Smith   if (!isshell) PetscFunctionReturn(0);
8583ad4599aSBarry Smith   dm->ops->createrestriction = restriction;
8593ad4599aSBarry Smith   PetscFunctionReturn(0);
8603ad4599aSBarry Smith }
8613ad4599aSBarry Smith 
8629bf9660cSLawrence Mitchell /*@C
8634363ddcaSBoris Boutkov    DMShellGetCreateRestriction - Get the routine used to create the restriction operator
8644363ddcaSBoris Boutkov 
865d083f849SBarry Smith    Logically Collective on dm
8664363ddcaSBoris Boutkov 
867a4a986ddSBoris Boutkov    Input Argument:
8684363ddcaSBoris Boutkov +  dm - the shell DM
869a4a986ddSBoris Boutkov 
870a4a986ddSBoris Boutkov    Output Argument:
871a4a986ddSBoris Boutkov -  restriction - the routine to create the restriction
8724363ddcaSBoris Boutkov 
8734363ddcaSBoris Boutkov    Level: advanced
8744363ddcaSBoris Boutkov 
8754363ddcaSBoris Boutkov .seealso: DMShellSetCreateInjection(), DMCreateInterpolation(), DMShellSetContext(), DMShellGetContext()
8764363ddcaSBoris Boutkov @*/
8774363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateRestriction(DM dm, PetscErrorCode (**restriction)(DM,DM,Mat*))
8784363ddcaSBoris Boutkov {
8794363ddcaSBoris Boutkov   PetscErrorCode ierr;
8804363ddcaSBoris Boutkov   PetscBool      isshell;
8814363ddcaSBoris Boutkov 
8824363ddcaSBoris Boutkov   PetscFunctionBegin;
8834363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8844363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
8858dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
8864363ddcaSBoris Boutkov   *restriction = dm->ops->createrestriction;
8874363ddcaSBoris Boutkov   PetscFunctionReturn(0);
8884363ddcaSBoris Boutkov }
8894363ddcaSBoris Boutkov 
8904363ddcaSBoris Boutkov /*@C
8919bf9660cSLawrence Mitchell    DMShellSetCreateInjection - Set the routine used to create the injection operator
8929bf9660cSLawrence Mitchell 
893d083f849SBarry Smith    Logically Collective on dm
8949bf9660cSLawrence Mitchell 
8959bf9660cSLawrence Mitchell    Input Arguments
8969bf9660cSLawrence Mitchell +  dm - the shell DM
8979bf9660cSLawrence Mitchell -  inject - the routine to create the injection
8989bf9660cSLawrence Mitchell 
8999bf9660cSLawrence Mitchell    Level: advanced
9009bf9660cSLawrence Mitchell 
901bf890c61SBoris Boutkov .seealso: DMShellSetCreateInterpolation(), DMCreateInjection(), DMShellGetCreateInjection(), DMShellSetContext(), DMShellGetContext()
9029bf9660cSLawrence Mitchell @*/
903f572501eSLawrence Mitchell PetscErrorCode DMShellSetCreateInjection(DM dm, PetscErrorCode (*inject)(DM,DM,Mat*))
904f572501eSLawrence Mitchell {
905f572501eSLawrence Mitchell   PetscErrorCode ierr;
906f572501eSLawrence Mitchell   PetscBool      isshell;
907f572501eSLawrence Mitchell 
908f572501eSLawrence Mitchell   PetscFunctionBegin;
909f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
910f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
911f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
9125a84ad33SLisandro Dalcin   dm->ops->createinjection = inject;
913f572501eSLawrence Mitchell   PetscFunctionReturn(0);
914f572501eSLawrence Mitchell }
915f572501eSLawrence Mitchell 
9164363ddcaSBoris Boutkov /*@C
9174363ddcaSBoris Boutkov    DMShellGetCreateInjection - Get the routine used to create the injection operator
9184363ddcaSBoris Boutkov 
919d083f849SBarry Smith    Logically Collective on dm
9204363ddcaSBoris Boutkov 
921a4a986ddSBoris Boutkov    Input Argument:
9224363ddcaSBoris Boutkov +  dm - the shell DM
923a4a986ddSBoris Boutkov 
924a4a986ddSBoris Boutkov    Output Argument:
9254363ddcaSBoris Boutkov -  inject - the routine to create the injection
9264363ddcaSBoris Boutkov 
9274363ddcaSBoris Boutkov    Level: advanced
9284363ddcaSBoris Boutkov 
9294363ddcaSBoris Boutkov .seealso: DMShellGetCreateInterpolation(), DMCreateInjection(), DMShellSetContext(), DMShellGetContext()
9304363ddcaSBoris Boutkov @*/
9314363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateInjection(DM dm, PetscErrorCode (**inject)(DM,DM,Mat*))
9324363ddcaSBoris Boutkov {
9334363ddcaSBoris Boutkov   PetscErrorCode ierr;
9344363ddcaSBoris Boutkov   PetscBool      isshell;
9354363ddcaSBoris Boutkov 
9364363ddcaSBoris Boutkov   PetscFunctionBegin;
9374363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9384363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
9398dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
9405a84ad33SLisandro Dalcin   *inject = dm->ops->createinjection;
9414363ddcaSBoris Boutkov   PetscFunctionReturn(0);
9424363ddcaSBoris Boutkov }
9434363ddcaSBoris Boutkov 
9449bf9660cSLawrence Mitchell /*@C
9459bf9660cSLawrence Mitchell    DMShellSetCreateFieldDecomposition - Set the routine used to create a decomposition of fields for the shell DM
9469bf9660cSLawrence Mitchell 
947d083f849SBarry Smith    Logically Collective on dm
9489bf9660cSLawrence Mitchell 
9499bf9660cSLawrence Mitchell    Input Arguments
9509bf9660cSLawrence Mitchell +  dm - the shell DM
9519bf9660cSLawrence Mitchell -  decomp - the routine to create the decomposition
9529bf9660cSLawrence Mitchell 
9539bf9660cSLawrence Mitchell    Level: advanced
9549bf9660cSLawrence Mitchell 
955fef3a512SBarry Smith .seealso: DMCreateFieldDecomposition(), DMShellSetContext(), DMShellGetContext()
9569bf9660cSLawrence Mitchell @*/
9575e2259d5SLawrence Mitchell PetscErrorCode DMShellSetCreateFieldDecomposition(DM dm, PetscErrorCode (*decomp)(DM,PetscInt*,char***, IS**,DM**))
9585e2259d5SLawrence Mitchell {
9595e2259d5SLawrence Mitchell   PetscErrorCode ierr;
9605e2259d5SLawrence Mitchell   PetscBool      isshell;
9615e2259d5SLawrence Mitchell 
9625e2259d5SLawrence Mitchell   PetscFunctionBegin;
9635e2259d5SLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9645e2259d5SLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
9655e2259d5SLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
9665e2259d5SLawrence Mitchell   dm->ops->createfielddecomposition = decomp;
9675e2259d5SLawrence Mitchell   PetscFunctionReturn(0);
9685e2259d5SLawrence Mitchell }
9695e2259d5SLawrence Mitchell 
970c00061e5SLawrence Mitchell /*@C
971e734121bSPatrick Farrell    DMShellSetCreateDomainDecomposition - Set the routine used to create a domain decomposition for the shell DM
972e734121bSPatrick Farrell 
973d083f849SBarry Smith    Logically Collective on dm
974e734121bSPatrick Farrell 
975e734121bSPatrick Farrell    Input Arguments
976e734121bSPatrick Farrell +  dm - the shell DM
977e734121bSPatrick Farrell -  decomp - the routine to create the decomposition
978e734121bSPatrick Farrell 
979e734121bSPatrick Farrell    Level: advanced
980e734121bSPatrick Farrell 
981e734121bSPatrick Farrell .seealso: DMCreateDomainDecomposition(), DMShellSetContext(), DMShellGetContext()
982e734121bSPatrick Farrell @*/
983e734121bSPatrick Farrell PetscErrorCode DMShellSetCreateDomainDecomposition(DM dm, PetscErrorCode (*decomp)(DM,PetscInt*,char***, IS**,IS**,DM**))
984e734121bSPatrick Farrell {
985e734121bSPatrick Farrell   PetscErrorCode ierr;
986e734121bSPatrick Farrell   PetscBool      isshell;
987e734121bSPatrick Farrell 
988e734121bSPatrick Farrell   PetscFunctionBegin;
989e734121bSPatrick Farrell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
990e734121bSPatrick Farrell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
991e734121bSPatrick Farrell   if (!isshell) PetscFunctionReturn(0);
992e734121bSPatrick Farrell   dm->ops->createdomaindecomposition = decomp;
993e734121bSPatrick Farrell   PetscFunctionReturn(0);
994e734121bSPatrick Farrell }
995e734121bSPatrick Farrell 
996e734121bSPatrick Farrell /*@C
997eef9d6cdSPatrick Farrell    DMShellSetCreateDomainDecompositionScatters - Set the routine used to create the scatter contexts for domain decomposition with a shell DM
998eef9d6cdSPatrick Farrell 
999d083f849SBarry Smith    Logically Collective on dm
1000eef9d6cdSPatrick Farrell 
1001eef9d6cdSPatrick Farrell    Input Arguments
1002eef9d6cdSPatrick Farrell +  dm - the shell DM
1003eef9d6cdSPatrick Farrell -  scatter - the routine to create the scatters
1004eef9d6cdSPatrick Farrell 
1005eef9d6cdSPatrick Farrell    Level: advanced
1006eef9d6cdSPatrick Farrell 
1007448b6425SPatrick Farrell .seealso: DMCreateDomainDecompositionScatters(), DMShellSetContext(), DMShellGetContext()
1008eef9d6cdSPatrick Farrell @*/
1009eef9d6cdSPatrick Farrell PetscErrorCode DMShellSetCreateDomainDecompositionScatters(DM dm, PetscErrorCode (*scatter)(DM,PetscInt,DM*,VecScatter**,VecScatter**,VecScatter**))
1010eef9d6cdSPatrick Farrell {
1011eef9d6cdSPatrick Farrell   PetscErrorCode ierr;
1012eef9d6cdSPatrick Farrell   PetscBool      isshell;
1013eef9d6cdSPatrick Farrell 
1014eef9d6cdSPatrick Farrell   PetscFunctionBegin;
1015eef9d6cdSPatrick Farrell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1016eef9d6cdSPatrick Farrell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
1017eef9d6cdSPatrick Farrell   if (!isshell) PetscFunctionReturn(0);
1018eef9d6cdSPatrick Farrell   dm->ops->createddscatters = scatter;
1019eef9d6cdSPatrick Farrell   PetscFunctionReturn(0);
1020eef9d6cdSPatrick Farrell }
1021eef9d6cdSPatrick Farrell 
1022eef9d6cdSPatrick Farrell /*@C
1023c00061e5SLawrence Mitchell    DMShellSetCreateSubDM - Set the routine used to create a sub DM from the shell DM
1024c00061e5SLawrence Mitchell 
1025d083f849SBarry Smith    Logically Collective on dm
1026c00061e5SLawrence Mitchell 
1027c00061e5SLawrence Mitchell    Input Arguments
1028c00061e5SLawrence Mitchell +  dm - the shell DM
1029c00061e5SLawrence Mitchell -  subdm - the routine to create the decomposition
1030c00061e5SLawrence Mitchell 
1031c00061e5SLawrence Mitchell    Level: advanced
1032c00061e5SLawrence Mitchell 
1033bf890c61SBoris Boutkov .seealso: DMCreateSubDM(), DMShellGetCreateSubDM(), DMShellSetContext(), DMShellGetContext()
1034c00061e5SLawrence Mitchell @*/
1035276c5506SMatthew G. Knepley PetscErrorCode DMShellSetCreateSubDM(DM dm, PetscErrorCode (*subdm)(DM,PetscInt,const PetscInt[],IS*,DM*))
1036c00061e5SLawrence Mitchell {
1037c00061e5SLawrence Mitchell   PetscErrorCode ierr;
1038c00061e5SLawrence Mitchell   PetscBool      isshell;
1039c00061e5SLawrence Mitchell 
1040c00061e5SLawrence Mitchell   PetscFunctionBegin;
1041c00061e5SLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1042c00061e5SLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
1043c00061e5SLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
1044c00061e5SLawrence Mitchell   dm->ops->createsubdm = subdm;
1045c00061e5SLawrence Mitchell   PetscFunctionReturn(0);
1046c00061e5SLawrence Mitchell }
1047c00061e5SLawrence Mitchell 
10484363ddcaSBoris Boutkov /*@C
10494363ddcaSBoris Boutkov    DMShellGetCreateSubDM - Get the routine used to create a sub DM from the shell DM
10504363ddcaSBoris Boutkov 
1051d083f849SBarry Smith    Logically Collective on dm
10524363ddcaSBoris Boutkov 
1053a4a986ddSBoris Boutkov    Input Argument:
10544363ddcaSBoris Boutkov +  dm - the shell DM
1055a4a986ddSBoris Boutkov 
1056a4a986ddSBoris Boutkov    Output Argument:
10574363ddcaSBoris Boutkov -  subdm - the routine to create the decomposition
10584363ddcaSBoris Boutkov 
10594363ddcaSBoris Boutkov    Level: advanced
10604363ddcaSBoris Boutkov 
10614363ddcaSBoris Boutkov .seealso: DMCreateSubDM(), DMShellSetCreateSubDM(), DMShellSetContext(), DMShellGetContext()
10624363ddcaSBoris Boutkov @*/
10634363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateSubDM(DM dm, PetscErrorCode (**subdm)(DM,PetscInt,const PetscInt[],IS*,DM*))
10644363ddcaSBoris Boutkov {
10654363ddcaSBoris Boutkov   PetscErrorCode ierr;
10664363ddcaSBoris Boutkov   PetscBool      isshell;
10674363ddcaSBoris Boutkov 
10684363ddcaSBoris Boutkov   PetscFunctionBegin;
10694363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10704363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
10718dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
10724363ddcaSBoris Boutkov   *subdm = dm->ops->createsubdm;
10734363ddcaSBoris Boutkov   PetscFunctionReturn(0);
10744363ddcaSBoris Boutkov }
10754363ddcaSBoris Boutkov 
1076fe1899a2SJed Brown static PetscErrorCode DMDestroy_Shell(DM dm)
1077fe1899a2SJed Brown {
1078fe1899a2SJed Brown   PetscErrorCode ierr;
1079fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
1080fe1899a2SJed Brown 
1081fe1899a2SJed Brown   PetscFunctionBegin;
1082fe1899a2SJed Brown   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
1083fe1899a2SJed Brown   ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
1084dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
1085a94b16f6SRichard Tran Mills   ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr);
1086a94b16f6SRichard Tran Mills   ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr);
1087294a6417SLawrence Mitchell   ierr = VecScatterDestroy(&shell->ltol);CHKERRQ(ierr);
10887b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
10897b6ad80cSMatthew G Knepley   ierr = PetscFree(shell);CHKERRQ(ierr);
1090fe1899a2SJed Brown   PetscFunctionReturn(0);
1091fe1899a2SJed Brown }
1092fe1899a2SJed Brown 
10932d53ad75SBarry Smith static PetscErrorCode DMView_Shell(DM dm,PetscViewer v)
10942d53ad75SBarry Smith {
10952d53ad75SBarry Smith   PetscErrorCode ierr;
10962d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
10972d53ad75SBarry Smith 
10982d53ad75SBarry Smith   PetscFunctionBegin;
10992d53ad75SBarry Smith   ierr = VecView(shell->Xglobal,v);CHKERRQ(ierr);
11002d53ad75SBarry Smith   PetscFunctionReturn(0);
11012d53ad75SBarry Smith }
11022d53ad75SBarry Smith 
11032d53ad75SBarry Smith static PetscErrorCode DMLoad_Shell(DM dm,PetscViewer v)
11042d53ad75SBarry Smith {
11052d53ad75SBarry Smith   PetscErrorCode ierr;
11062d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
11072d53ad75SBarry Smith 
11082d53ad75SBarry Smith   PetscFunctionBegin;
1109ce94432eSBarry Smith   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&shell->Xglobal);CHKERRQ(ierr);
11102d53ad75SBarry Smith   ierr = VecLoad(shell->Xglobal,v);CHKERRQ(ierr);
11112d53ad75SBarry Smith   PetscFunctionReturn(0);
11122d53ad75SBarry Smith }
1113fe1899a2SJed Brown 
1114276c5506SMatthew G. Knepley PetscErrorCode DMCreateSubDM_Shell(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm)
11156e44b4cfSMatthew G. Knepley {
11166e44b4cfSMatthew G. Knepley   PetscErrorCode ierr;
11176e44b4cfSMatthew G. Knepley 
11186e44b4cfSMatthew G. Knepley   PetscFunctionBegin;
11196e44b4cfSMatthew G. Knepley   if (subdm) {ierr = DMShellCreate(PetscObjectComm((PetscObject) dm), subdm);CHKERRQ(ierr);}
1120792b654fSMatthew G. Knepley   ierr = DMCreateSectionSubDM(dm, numFields, fields, is, subdm);CHKERRQ(ierr);
11216e44b4cfSMatthew G. Knepley   PetscFunctionReturn(0);
11226e44b4cfSMatthew G. Knepley }
11236e44b4cfSMatthew G. Knepley 
11248cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm)
1125fe1899a2SJed Brown {
1126fe1899a2SJed Brown   PetscErrorCode ierr;
1127fe1899a2SJed Brown   DM_Shell       *shell;
1128fe1899a2SJed Brown 
1129fe1899a2SJed Brown   PetscFunctionBegin;
1130b00a9115SJed Brown   ierr     = PetscNewLog(dm,&shell);CHKERRQ(ierr);
11318c87107bSJed Brown   dm->data = shell;
1132fe1899a2SJed Brown 
11338c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
11348c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
1135dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
11368c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
11372d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
11382d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
11397a108d1dSBarry Smith   dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell;
11407a108d1dSBarry Smith   dm->ops->globaltolocalend   = DMGlobalToLocalEndDefaultShell;
114155daaa54SRichard Tran Mills   dm->ops->localtoglobalbegin = DMLocalToGlobalBeginDefaultShell;
114255daaa54SRichard Tran Mills   dm->ops->localtoglobalend   = DMLocalToGlobalEndDefaultShell;
114363731094SRichard Tran Mills   dm->ops->localtolocalbegin  = DMLocalToLocalBeginDefaultShell;
114463731094SRichard Tran Mills   dm->ops->localtolocalend    = DMLocalToLocalEndDefaultShell;
11456e44b4cfSMatthew G. Knepley   dm->ops->createsubdm        = DMCreateSubDM_Shell;
11462a350339SBarry Smith   ierr = DMSetMatType(dm,MATDENSE);CHKERRQ(ierr);
1147fe1899a2SJed Brown   PetscFunctionReturn(0);
1148fe1899a2SJed Brown }
1149fe1899a2SJed Brown 
1150fe1899a2SJed Brown /*@
1151fe1899a2SJed Brown     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
1152fe1899a2SJed Brown 
1153d083f849SBarry Smith     Collective
1154fe1899a2SJed Brown 
1155fe1899a2SJed Brown     Input Parameter:
1156fe1899a2SJed Brown .   comm - the processors that will share the global vector
1157fe1899a2SJed Brown 
1158fe1899a2SJed Brown     Output Parameters:
1159fe1899a2SJed Brown .   shell - the shell DM
1160fe1899a2SJed Brown 
1161fe1899a2SJed Brown     Level: advanced
1162fe1899a2SJed Brown 
1163fef3a512SBarry Smith .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateLocalVector(), DMShellSetContext(), DMShellGetContext()
1164fe1899a2SJed Brown @*/
1165fe1899a2SJed Brown PetscErrorCode  DMShellCreate(MPI_Comm comm,DM *dm)
1166fe1899a2SJed Brown {
1167fe1899a2SJed Brown   PetscErrorCode ierr;
1168fe1899a2SJed Brown 
1169fe1899a2SJed Brown   PetscFunctionBegin;
1170fe1899a2SJed Brown   PetscValidPointer(dm,2);
1171fe1899a2SJed Brown   ierr = DMCreate(comm,dm);CHKERRQ(ierr);
1172fe1899a2SJed Brown   ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr);
117381a566bfSMatthew G. Knepley   ierr = DMSetUp(*dm);CHKERRQ(ierr);
1174fe1899a2SJed Brown   PetscFunctionReturn(0);
1175fe1899a2SJed Brown }
1176