xref: /petsc/src/dm/impls/shell/dmshell.c (revision bdb10af280b4afb26b8c43c0c73683bd61465084)
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 
399fe1899a2SJed Brown /*@C
400fe1899a2SJed Brown    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM
401fe1899a2SJed Brown 
402fe1899a2SJed Brown    Logically Collective
403fe1899a2SJed Brown 
404fe1899a2SJed Brown    Input Arguments:
405fe1899a2SJed Brown +  dm - the shell DM
406fe1899a2SJed Brown -  func - the creation routine
407fe1899a2SJed Brown 
408fe1899a2SJed Brown    Level: advanced
409fe1899a2SJed Brown 
410fef3a512SBarry Smith .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix(), DMShellSetContext(), DMShellGetContext()
411fe1899a2SJed Brown @*/
412fe1899a2SJed Brown PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
413fe1899a2SJed Brown {
414fe1899a2SJed Brown   PetscFunctionBegin;
415fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
416fe1899a2SJed Brown   dm->ops->createglobalvector = func;
417fe1899a2SJed Brown   PetscFunctionReturn(0);
418fe1899a2SJed Brown }
419fe1899a2SJed Brown 
420dc43b69eSJed Brown /*@
421dc43b69eSJed Brown    DMShellSetLocalVector - sets a template local vector associated with the DMShell
422dc43b69eSJed Brown 
423d083f849SBarry Smith    Logically Collective on dm
424dc43b69eSJed Brown 
425dc43b69eSJed Brown    Input Arguments:
426dc43b69eSJed Brown +  dm - shell DM
427dc43b69eSJed Brown -  X - template vector
428dc43b69eSJed Brown 
429dc43b69eSJed Brown    Level: advanced
430dc43b69eSJed Brown 
431dc43b69eSJed Brown .seealso: DMCreateLocalVector(), DMShellSetMatrix(), DMShellSetCreateLocalVector()
432dc43b69eSJed Brown @*/
433dc43b69eSJed Brown PetscErrorCode DMShellSetLocalVector(DM dm,Vec X)
434dc43b69eSJed Brown {
435dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
436dc43b69eSJed Brown   PetscErrorCode ierr;
437dc43b69eSJed Brown   PetscBool      isshell;
438cca7ec1eSBarry Smith   DM             vdm;
439dc43b69eSJed Brown 
440dc43b69eSJed Brown   PetscFunctionBegin;
441dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
442dc43b69eSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
443dc43b69eSJed Brown   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
444dc43b69eSJed Brown   if (!isshell) PetscFunctionReturn(0);
445cca7ec1eSBarry Smith   ierr = VecGetDM(X,&vdm);CHKERRQ(ierr);
446cca7ec1eSBarry Smith   /*
447cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
448cca7ec1eSBarry 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
449cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
450cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
451cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
452cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
453cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
454cca7ec1eSBarry Smith       for pointing out the problem.
455cca7ec1eSBarry Smith    */
456cca7ec1eSBarry Smith   if (vdm == dm) PetscFunctionReturn(0);
457dc43b69eSJed Brown   ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
458dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
459dc43b69eSJed Brown   shell->Xlocal = X;
460dc43b69eSJed Brown   PetscFunctionReturn(0);
461dc43b69eSJed Brown }
462dc43b69eSJed Brown 
463dc43b69eSJed Brown /*@C
464dc43b69eSJed Brown    DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM
465dc43b69eSJed Brown 
466dc43b69eSJed Brown    Logically Collective
467dc43b69eSJed Brown 
468dc43b69eSJed Brown    Input Arguments:
469dc43b69eSJed Brown +  dm - the shell DM
470dc43b69eSJed Brown -  func - the creation routine
471dc43b69eSJed Brown 
472dc43b69eSJed Brown    Level: advanced
473dc43b69eSJed Brown 
474fef3a512SBarry Smith .seealso: DMShellSetLocalVector(), DMShellSetCreateMatrix(), DMShellSetContext(), DMShellGetContext()
475dc43b69eSJed Brown @*/
476dc43b69eSJed Brown PetscErrorCode DMShellSetCreateLocalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
477dc43b69eSJed Brown {
478dc43b69eSJed Brown   PetscFunctionBegin;
479dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
480dc43b69eSJed Brown   dm->ops->createlocalvector = func;
481dc43b69eSJed Brown   PetscFunctionReturn(0);
482dc43b69eSJed Brown }
483dc43b69eSJed Brown 
4848339e6d0SRichard Tran Mills /*@C
4858339e6d0SRichard Tran Mills    DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter
4868339e6d0SRichard Tran Mills 
487d083f849SBarry Smith    Logically Collective on dm
4888339e6d0SRichard Tran Mills 
4898339e6d0SRichard Tran Mills    Input Arguments
4908339e6d0SRichard Tran Mills +  dm - the shell DM
4918339e6d0SRichard Tran Mills .  begin - the routine that begins the global to local scatter
4928339e6d0SRichard Tran Mills -  end - the routine that ends the global to local scatter
4938339e6d0SRichard Tran Mills 
49495452b02SPatrick Sanan    Notes:
49595452b02SPatrick Sanan     If these functions are not provided but DMShellSetGlobalToLocalVecScatter() is called then
496f3db62a7SRichard Tran Mills    DMGlobalToLocalBeginDefaultShell()/DMGlobalToLocalEndDefaultShell() are used to to perform the transfers
4977a108d1dSBarry Smith 
4988339e6d0SRichard Tran Mills    Level: advanced
4998339e6d0SRichard Tran Mills 
5007a108d1dSBarry Smith .seealso: DMShellSetLocalToGlobal(), DMGlobalToLocalBeginDefaultShell(), DMGlobalToLocalEndDefaultShell()
5018339e6d0SRichard Tran Mills @*/
502*bdb10af2SPierre Jolivet PetscErrorCode DMShellSetGlobalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec))
503*bdb10af2SPierre Jolivet {
5048339e6d0SRichard Tran Mills   PetscFunctionBegin;
5052d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5068339e6d0SRichard Tran Mills   dm->ops->globaltolocalbegin = begin;
5078339e6d0SRichard Tran Mills   dm->ops->globaltolocalend = end;
5088339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
5098339e6d0SRichard Tran Mills }
5108339e6d0SRichard Tran Mills 
5118339e6d0SRichard Tran Mills /*@C
5128339e6d0SRichard Tran Mills    DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter
5138339e6d0SRichard Tran Mills 
514d083f849SBarry Smith    Logically Collective on dm
5158339e6d0SRichard Tran Mills 
5168339e6d0SRichard Tran Mills    Input Arguments
5178339e6d0SRichard Tran Mills +  dm - the shell DM
5188339e6d0SRichard Tran Mills .  begin - the routine that begins the local to global scatter
5198339e6d0SRichard Tran Mills -  end - the routine that ends the local to global scatter
5208339e6d0SRichard Tran Mills 
52195452b02SPatrick Sanan    Notes:
52295452b02SPatrick Sanan     If these functions are not provided but DMShellSetLocalToGlobalVecScatter() is called then
523f3db62a7SRichard Tran Mills    DMLocalToGlobalBeginDefaultShell()/DMLocalToGlobalEndDefaultShell() are used to to perform the transfers
524f3db62a7SRichard Tran Mills 
5258339e6d0SRichard Tran Mills    Level: advanced
5268339e6d0SRichard Tran Mills 
5278339e6d0SRichard Tran Mills .seealso: DMShellSetGlobalToLocal()
5288339e6d0SRichard Tran Mills @*/
529*bdb10af2SPierre Jolivet PetscErrorCode DMShellSetLocalToGlobal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec))
530*bdb10af2SPierre Jolivet {
5318339e6d0SRichard Tran Mills   PetscFunctionBegin;
5322d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5338339e6d0SRichard Tran Mills   dm->ops->localtoglobalbegin = begin;
5348339e6d0SRichard Tran Mills   dm->ops->localtoglobalend = end;
5358339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
5368339e6d0SRichard Tran Mills }
5378339e6d0SRichard Tran Mills 
538f3db62a7SRichard Tran Mills /*@C
539f3db62a7SRichard Tran Mills    DMShellSetLocalToLocal - Sets the routines used to perform a local to local scatter
540f3db62a7SRichard Tran Mills 
541d083f849SBarry Smith    Logically Collective on dm
542f3db62a7SRichard Tran Mills 
543f3db62a7SRichard Tran Mills    Input Arguments
544f3db62a7SRichard Tran Mills +  dm - the shell DM
545f3db62a7SRichard Tran Mills .  begin - the routine that begins the local to local scatter
546f3db62a7SRichard Tran Mills -  end - the routine that ends the local to local scatter
547f3db62a7SRichard Tran Mills 
54895452b02SPatrick Sanan    Notes:
54995452b02SPatrick Sanan     If these functions are not provided but DMShellSetLocalToLocalVecScatter() is called then
550f3db62a7SRichard Tran Mills    DMLocalToLocalBeginDefaultShell()/DMLocalToLocalEndDefaultShell() are used to to perform the transfers
551f3db62a7SRichard Tran Mills 
552f3db62a7SRichard Tran Mills    Level: advanced
553f3db62a7SRichard Tran Mills 
554f3db62a7SRichard Tran Mills .seealso: DMShellSetGlobalToLocal(), DMLocalToLocalBeginDefaultShell(), DMLocalToLocalEndDefaultShell()
555f3db62a7SRichard Tran Mills @*/
556*bdb10af2SPierre Jolivet PetscErrorCode DMShellSetLocalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec))
557*bdb10af2SPierre Jolivet {
558f3db62a7SRichard Tran Mills   PetscFunctionBegin;
5592d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
560f3db62a7SRichard Tran Mills   dm->ops->localtolocalbegin = begin;
561f3db62a7SRichard Tran Mills   dm->ops->localtolocalend = end;
562f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
563f3db62a7SRichard Tran Mills }
564f3db62a7SRichard Tran Mills 
56581634712SRichard Tran Mills /*@
56681634712SRichard Tran Mills    DMShellSetGlobalToLocalVecScatter - Sets a VecScatter context for global to local communication
56781634712SRichard Tran Mills 
568d083f849SBarry Smith    Logically Collective on dm
56981634712SRichard Tran Mills 
57081634712SRichard Tran Mills    Input Arguments
57181634712SRichard Tran Mills +  dm - the shell DM
57281634712SRichard Tran Mills -  gtol - the global to local VecScatter context
57381634712SRichard Tran Mills 
57481634712SRichard Tran Mills    Level: advanced
57581634712SRichard Tran Mills 
576f3db62a7SRichard Tran Mills .seealso: DMShellSetGlobalToLocal(), DMGlobalToLocalBeginDefaultShell(), DMGlobalToLocalEndDefaultShell()
57781634712SRichard Tran Mills @*/
578a94b16f6SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter gtol)
57981634712SRichard Tran Mills {
58081634712SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
581d885d199SRichard Tran Mills   PetscErrorCode ierr;
58281634712SRichard Tran Mills 
583b300e4a8SRichard Tran Mills   PetscFunctionBegin;
5842d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
58597929ea7SJunchao Zhang   PetscValidHeaderSpecific(gtol,PETSCSF_CLASSID,2);
586d885d199SRichard Tran Mills   ierr = PetscObjectReference((PetscObject)gtol);CHKERRQ(ierr);
587d885d199SRichard Tran Mills   ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr);
58881634712SRichard Tran Mills   shell->gtol = gtol;
58981634712SRichard Tran Mills   PetscFunctionReturn(0);
59081634712SRichard Tran Mills }
59181634712SRichard Tran Mills 
592988ea7d6SRichard Tran Mills /*@
593988ea7d6SRichard Tran Mills    DMShellSetLocalToGlobalVecScatter - Sets a VecScatter context for local to global communication
594988ea7d6SRichard Tran Mills 
595d083f849SBarry Smith    Logically Collective on dm
596988ea7d6SRichard Tran Mills 
597988ea7d6SRichard Tran Mills    Input Arguments
598988ea7d6SRichard Tran Mills +  dm - the shell DM
599988ea7d6SRichard Tran Mills -  ltog - the local to global VecScatter context
600988ea7d6SRichard Tran Mills 
601988ea7d6SRichard Tran Mills    Level: advanced
602988ea7d6SRichard Tran Mills 
603f3db62a7SRichard Tran Mills .seealso: DMShellSetLocalToGlobal(), DMLocalToGlobalBeginDefaultShell(), DMLocalToGlobalEndDefaultShell()
604988ea7d6SRichard Tran Mills @*/
605a94b16f6SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM dm, VecScatter ltog)
606988ea7d6SRichard Tran Mills {
607988ea7d6SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
608d885d199SRichard Tran Mills   PetscErrorCode ierr;
609988ea7d6SRichard Tran Mills 
610988ea7d6SRichard Tran Mills   PetscFunctionBegin;
6112d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
61297929ea7SJunchao Zhang   PetscValidHeaderSpecific(ltog,PETSCSF_CLASSID,2);
613d885d199SRichard Tran Mills   ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr);
614d885d199SRichard Tran Mills   ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr);
615988ea7d6SRichard Tran Mills   shell->ltog = ltog;
616988ea7d6SRichard Tran Mills   PetscFunctionReturn(0);
617988ea7d6SRichard Tran Mills }
618988ea7d6SRichard Tran Mills 
619f3db62a7SRichard Tran Mills /*@
620f3db62a7SRichard Tran Mills    DMShellSetLocalToLocalVecScatter - Sets a VecScatter context for local to local communication
621f3db62a7SRichard Tran Mills 
622d083f849SBarry Smith    Logically Collective on dm
623f3db62a7SRichard Tran Mills 
624f3db62a7SRichard Tran Mills    Input Arguments
625f3db62a7SRichard Tran Mills +  dm - the shell DM
626f3db62a7SRichard Tran Mills -  ltol - the local to local VecScatter context
627f3db62a7SRichard Tran Mills 
628f3db62a7SRichard Tran Mills    Level: advanced
629f3db62a7SRichard Tran Mills 
630f3db62a7SRichard Tran Mills .seealso: DMShellSetLocalToLocal(), DMLocalToLocalBeginDefaultShell(), DMLocalToLocalEndDefaultShell()
631f3db62a7SRichard Tran Mills @*/
632f3db62a7SRichard Tran Mills PetscErrorCode DMShellSetLocalToLocalVecScatter(DM dm, VecScatter ltol)
633f3db62a7SRichard Tran Mills {
634f3db62a7SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
635f3db62a7SRichard Tran Mills   PetscErrorCode ierr;
636f3db62a7SRichard Tran Mills 
637f3db62a7SRichard Tran Mills   PetscFunctionBegin;
6382d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
63997929ea7SJunchao Zhang   PetscValidHeaderSpecific(ltol,PETSCSF_CLASSID,2);
640f3db62a7SRichard Tran Mills   ierr = PetscObjectReference((PetscObject)ltol);CHKERRQ(ierr);
641f3db62a7SRichard Tran Mills   ierr = VecScatterDestroy(&shell->ltol);CHKERRQ(ierr);
642f3db62a7SRichard Tran Mills   shell->ltol = ltol;
643f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
644f3db62a7SRichard Tran Mills }
645f3db62a7SRichard Tran Mills 
6469bf9660cSLawrence Mitchell /*@C
6479bf9660cSLawrence Mitchell    DMShellSetCoarsen - Set the routine used to coarsen the shell DM
6489bf9660cSLawrence Mitchell 
649d083f849SBarry Smith    Logically Collective on dm
6509bf9660cSLawrence Mitchell 
6519bf9660cSLawrence Mitchell    Input Arguments
6529bf9660cSLawrence Mitchell +  dm - the shell DM
6539bf9660cSLawrence Mitchell -  coarsen - the routine that coarsens the DM
6549bf9660cSLawrence Mitchell 
6559bf9660cSLawrence Mitchell    Level: advanced
6569bf9660cSLawrence Mitchell 
657bf890c61SBoris Boutkov .seealso: DMShellSetRefine(), DMCoarsen(), DMShellGetCoarsen(), DMShellSetContext(), DMShellGetContext()
6589bf9660cSLawrence Mitchell @*/
659f572501eSLawrence Mitchell PetscErrorCode DMShellSetCoarsen(DM dm, PetscErrorCode (*coarsen)(DM,MPI_Comm,DM*))
660f572501eSLawrence Mitchell {
661f572501eSLawrence Mitchell   PetscErrorCode ierr;
662f572501eSLawrence Mitchell   PetscBool      isshell;
663f572501eSLawrence Mitchell 
664f572501eSLawrence Mitchell   PetscFunctionBegin;
665f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
666f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
667f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
668f572501eSLawrence Mitchell   dm->ops->coarsen = coarsen;
669f572501eSLawrence Mitchell   PetscFunctionReturn(0);
670f572501eSLawrence Mitchell }
671f572501eSLawrence Mitchell 
6729bf9660cSLawrence Mitchell /*@C
6734363ddcaSBoris Boutkov    DMShellGetCoarsen - Get the routine used to coarsen the shell DM
6744363ddcaSBoris Boutkov 
675d083f849SBarry Smith    Logically Collective on dm
6764363ddcaSBoris Boutkov 
677a4a986ddSBoris Boutkov    Input Argument:
6784363ddcaSBoris Boutkov .  dm - the shell DM
6794363ddcaSBoris Boutkov 
680a4a986ddSBoris Boutkov    Output Argument:
6814363ddcaSBoris Boutkov .  coarsen - the routine that coarsens the DM
6824363ddcaSBoris Boutkov 
6834363ddcaSBoris Boutkov    Level: advanced
6844363ddcaSBoris Boutkov 
6854363ddcaSBoris Boutkov .seealso: DMShellSetCoarsen(), DMCoarsen(), DMShellSetRefine(), DMRefine()
6864363ddcaSBoris Boutkov @*/
6874363ddcaSBoris Boutkov PetscErrorCode DMShellGetCoarsen(DM dm, PetscErrorCode (**coarsen)(DM,MPI_Comm,DM*))
6884363ddcaSBoris Boutkov {
6894363ddcaSBoris Boutkov   PetscErrorCode ierr;
6904363ddcaSBoris Boutkov   PetscBool      isshell;
6914363ddcaSBoris Boutkov 
6924363ddcaSBoris Boutkov   PetscFunctionBegin;
6934363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6944363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
6958dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
6964363ddcaSBoris Boutkov   *coarsen = dm->ops->coarsen;
6974363ddcaSBoris Boutkov   PetscFunctionReturn(0);
6984363ddcaSBoris Boutkov }
6994363ddcaSBoris Boutkov 
7004363ddcaSBoris Boutkov /*@C
7019bf9660cSLawrence Mitchell    DMShellSetRefine - Set the routine used to refine the shell DM
7029bf9660cSLawrence Mitchell 
703d083f849SBarry Smith    Logically Collective on dm
7049bf9660cSLawrence Mitchell 
7059bf9660cSLawrence Mitchell    Input Arguments
7069bf9660cSLawrence Mitchell +  dm - the shell DM
7079bf9660cSLawrence Mitchell -  refine - the routine that refines the DM
7089bf9660cSLawrence Mitchell 
7099bf9660cSLawrence Mitchell    Level: advanced
7109bf9660cSLawrence Mitchell 
711bf890c61SBoris Boutkov .seealso: DMShellSetCoarsen(), DMRefine(), DMShellGetRefine(), DMShellSetContext(), DMShellGetContext()
7129bf9660cSLawrence Mitchell @*/
713f572501eSLawrence Mitchell PetscErrorCode DMShellSetRefine(DM dm, PetscErrorCode (*refine)(DM,MPI_Comm,DM*))
714f572501eSLawrence Mitchell {
715f572501eSLawrence Mitchell   PetscErrorCode ierr;
716f572501eSLawrence Mitchell   PetscBool      isshell;
717f572501eSLawrence Mitchell 
718f572501eSLawrence Mitchell   PetscFunctionBegin;
719f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
720f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
721f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
722f572501eSLawrence Mitchell   dm->ops->refine = refine;
723f572501eSLawrence Mitchell   PetscFunctionReturn(0);
724f572501eSLawrence Mitchell }
725f572501eSLawrence Mitchell 
7269bf9660cSLawrence Mitchell /*@C
7274363ddcaSBoris Boutkov    DMShellGetRefine - Get the routine used to refine the shell DM
7284363ddcaSBoris Boutkov 
729d083f849SBarry Smith    Logically Collective on dm
7304363ddcaSBoris Boutkov 
731a4a986ddSBoris Boutkov    Input Argument:
7324363ddcaSBoris Boutkov .  dm - the shell DM
7334363ddcaSBoris Boutkov 
734a4a986ddSBoris Boutkov    Output Argument:
7354363ddcaSBoris Boutkov .  refine - the routine that refines the DM
7364363ddcaSBoris Boutkov 
7374363ddcaSBoris Boutkov    Level: advanced
7384363ddcaSBoris Boutkov 
7394363ddcaSBoris Boutkov .seealso: DMShellSetCoarsen(), DMCoarsen(), DMShellSetRefine(), DMRefine()
7404363ddcaSBoris Boutkov @*/
7414363ddcaSBoris Boutkov PetscErrorCode DMShellGetRefine(DM dm, PetscErrorCode (**refine)(DM,MPI_Comm,DM*))
7424363ddcaSBoris Boutkov {
7434363ddcaSBoris Boutkov   PetscErrorCode ierr;
7444363ddcaSBoris Boutkov   PetscBool      isshell;
7454363ddcaSBoris Boutkov 
7464363ddcaSBoris Boutkov   PetscFunctionBegin;
7474363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7484363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
7498dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
7504363ddcaSBoris Boutkov   *refine = dm->ops->refine;
7514363ddcaSBoris Boutkov   PetscFunctionReturn(0);
7524363ddcaSBoris Boutkov }
7534363ddcaSBoris Boutkov 
7544363ddcaSBoris Boutkov /*@C
7559bf9660cSLawrence Mitchell    DMShellSetCreateInterpolation - Set the routine used to create the interpolation operator
7569bf9660cSLawrence Mitchell 
757d083f849SBarry Smith    Logically Collective on dm
7589bf9660cSLawrence Mitchell 
7599bf9660cSLawrence Mitchell    Input Arguments
7609bf9660cSLawrence Mitchell +  dm - the shell DM
7619bf9660cSLawrence Mitchell -  interp - the routine to create the interpolation
7629bf9660cSLawrence Mitchell 
7639bf9660cSLawrence Mitchell    Level: advanced
7649bf9660cSLawrence Mitchell 
765bf890c61SBoris Boutkov .seealso: DMShellSetCreateInjection(), DMCreateInterpolation(), DMShellGetCreateInterpolation(), DMShellSetCreateRestriction(), DMShellSetContext(), DMShellGetContext()
7669bf9660cSLawrence Mitchell @*/
767f572501eSLawrence Mitchell PetscErrorCode DMShellSetCreateInterpolation(DM dm, PetscErrorCode (*interp)(DM,DM,Mat*,Vec*))
768f572501eSLawrence Mitchell {
769f572501eSLawrence Mitchell   PetscErrorCode ierr;
770f572501eSLawrence Mitchell   PetscBool      isshell;
771f572501eSLawrence Mitchell 
772f572501eSLawrence Mitchell   PetscFunctionBegin;
773f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
774f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
775f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
776f572501eSLawrence Mitchell   dm->ops->createinterpolation = interp;
777f572501eSLawrence Mitchell   PetscFunctionReturn(0);
778f572501eSLawrence Mitchell }
779f572501eSLawrence Mitchell 
7803ad4599aSBarry Smith /*@C
7814363ddcaSBoris Boutkov    DMShellGetCreateInterpolation - Get the routine used to create the interpolation operator
7824363ddcaSBoris Boutkov 
783d083f849SBarry Smith    Logically Collective on dm
7844363ddcaSBoris Boutkov 
785a4a986ddSBoris Boutkov    Input Argument:
7864363ddcaSBoris Boutkov +  dm - the shell DM
787a4a986ddSBoris Boutkov 
788a4a986ddSBoris Boutkov    Output Argument:
7894363ddcaSBoris Boutkov -  interp - the routine to create the interpolation
7904363ddcaSBoris Boutkov 
7914363ddcaSBoris Boutkov    Level: advanced
7924363ddcaSBoris Boutkov 
7934363ddcaSBoris Boutkov .seealso: DMShellGetCreateInjection(), DMCreateInterpolation(), DMShellGetCreateRestriction(), DMShellSetContext(), DMShellGetContext()
7944363ddcaSBoris Boutkov @*/
7954363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateInterpolation(DM dm, PetscErrorCode (**interp)(DM,DM,Mat*,Vec*))
7964363ddcaSBoris Boutkov {
7974363ddcaSBoris Boutkov   PetscErrorCode ierr;
7984363ddcaSBoris Boutkov   PetscBool      isshell;
7994363ddcaSBoris Boutkov 
8004363ddcaSBoris Boutkov   PetscFunctionBegin;
8014363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8024363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
8038dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
8044363ddcaSBoris Boutkov   *interp = dm->ops->createinterpolation;
8054363ddcaSBoris Boutkov   PetscFunctionReturn(0);
8064363ddcaSBoris Boutkov }
8074363ddcaSBoris Boutkov 
8084363ddcaSBoris Boutkov /*@C
8093ad4599aSBarry Smith    DMShellSetCreateRestriction - Set the routine used to create the restriction operator
8103ad4599aSBarry Smith 
811d083f849SBarry Smith    Logically Collective on dm
8123ad4599aSBarry Smith 
8133ad4599aSBarry Smith    Input Arguments
8143ad4599aSBarry Smith +  dm - the shell DM
8153ad4599aSBarry Smith -  striction- the routine to create the restriction
8163ad4599aSBarry Smith 
8173ad4599aSBarry Smith    Level: advanced
8183ad4599aSBarry Smith 
819bf890c61SBoris Boutkov .seealso: DMShellSetCreateInjection(), DMCreateInterpolation(), DMShellGetCreateRestriction(), DMShellSetContext(), DMShellGetContext()
8203ad4599aSBarry Smith @*/
8213ad4599aSBarry Smith PetscErrorCode DMShellSetCreateRestriction(DM dm, PetscErrorCode (*restriction)(DM,DM,Mat*))
8223ad4599aSBarry Smith {
8233ad4599aSBarry Smith   PetscErrorCode ierr;
8243ad4599aSBarry Smith   PetscBool      isshell;
8253ad4599aSBarry Smith 
8263ad4599aSBarry Smith   PetscFunctionBegin;
8273ad4599aSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8283ad4599aSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
8293ad4599aSBarry Smith   if (!isshell) PetscFunctionReturn(0);
8303ad4599aSBarry Smith   dm->ops->createrestriction = restriction;
8313ad4599aSBarry Smith   PetscFunctionReturn(0);
8323ad4599aSBarry Smith }
8333ad4599aSBarry Smith 
8349bf9660cSLawrence Mitchell /*@C
8354363ddcaSBoris Boutkov    DMShellGetCreateRestriction - Get the routine used to create the restriction operator
8364363ddcaSBoris Boutkov 
837d083f849SBarry Smith    Logically Collective on dm
8384363ddcaSBoris Boutkov 
839a4a986ddSBoris Boutkov    Input Argument:
8404363ddcaSBoris Boutkov +  dm - the shell DM
841a4a986ddSBoris Boutkov 
842a4a986ddSBoris Boutkov    Output Argument:
843a4a986ddSBoris Boutkov -  restriction - the routine to create the restriction
8444363ddcaSBoris Boutkov 
8454363ddcaSBoris Boutkov    Level: advanced
8464363ddcaSBoris Boutkov 
8474363ddcaSBoris Boutkov .seealso: DMShellSetCreateInjection(), DMCreateInterpolation(), DMShellSetContext(), DMShellGetContext()
8484363ddcaSBoris Boutkov @*/
8494363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateRestriction(DM dm, PetscErrorCode (**restriction)(DM,DM,Mat*))
8504363ddcaSBoris Boutkov {
8514363ddcaSBoris Boutkov   PetscErrorCode ierr;
8524363ddcaSBoris Boutkov   PetscBool      isshell;
8534363ddcaSBoris Boutkov 
8544363ddcaSBoris Boutkov   PetscFunctionBegin;
8554363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8564363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
8578dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
8584363ddcaSBoris Boutkov   *restriction = dm->ops->createrestriction;
8594363ddcaSBoris Boutkov   PetscFunctionReturn(0);
8604363ddcaSBoris Boutkov }
8614363ddcaSBoris Boutkov 
8624363ddcaSBoris Boutkov /*@C
8639bf9660cSLawrence Mitchell    DMShellSetCreateInjection - Set the routine used to create the injection operator
8649bf9660cSLawrence Mitchell 
865d083f849SBarry Smith    Logically Collective on dm
8669bf9660cSLawrence Mitchell 
8679bf9660cSLawrence Mitchell    Input Arguments
8689bf9660cSLawrence Mitchell +  dm - the shell DM
8699bf9660cSLawrence Mitchell -  inject - the routine to create the injection
8709bf9660cSLawrence Mitchell 
8719bf9660cSLawrence Mitchell    Level: advanced
8729bf9660cSLawrence Mitchell 
873bf890c61SBoris Boutkov .seealso: DMShellSetCreateInterpolation(), DMCreateInjection(), DMShellGetCreateInjection(), DMShellSetContext(), DMShellGetContext()
8749bf9660cSLawrence Mitchell @*/
875f572501eSLawrence Mitchell PetscErrorCode DMShellSetCreateInjection(DM dm, PetscErrorCode (*inject)(DM,DM,Mat*))
876f572501eSLawrence Mitchell {
877f572501eSLawrence Mitchell   PetscErrorCode ierr;
878f572501eSLawrence Mitchell   PetscBool      isshell;
879f572501eSLawrence Mitchell 
880f572501eSLawrence Mitchell   PetscFunctionBegin;
881f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
882f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
883f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
8845a84ad33SLisandro Dalcin   dm->ops->createinjection = inject;
885f572501eSLawrence Mitchell   PetscFunctionReturn(0);
886f572501eSLawrence Mitchell }
887f572501eSLawrence Mitchell 
8884363ddcaSBoris Boutkov /*@C
8894363ddcaSBoris Boutkov    DMShellGetCreateInjection - Get the routine used to create the injection operator
8904363ddcaSBoris Boutkov 
891d083f849SBarry Smith    Logically Collective on dm
8924363ddcaSBoris Boutkov 
893a4a986ddSBoris Boutkov    Input Argument:
8944363ddcaSBoris Boutkov +  dm - the shell DM
895a4a986ddSBoris Boutkov 
896a4a986ddSBoris Boutkov    Output Argument:
8974363ddcaSBoris Boutkov -  inject - the routine to create the injection
8984363ddcaSBoris Boutkov 
8994363ddcaSBoris Boutkov    Level: advanced
9004363ddcaSBoris Boutkov 
9014363ddcaSBoris Boutkov .seealso: DMShellGetCreateInterpolation(), DMCreateInjection(), DMShellSetContext(), DMShellGetContext()
9024363ddcaSBoris Boutkov @*/
9034363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateInjection(DM dm, PetscErrorCode (**inject)(DM,DM,Mat*))
9044363ddcaSBoris Boutkov {
9054363ddcaSBoris Boutkov   PetscErrorCode ierr;
9064363ddcaSBoris Boutkov   PetscBool      isshell;
9074363ddcaSBoris Boutkov 
9084363ddcaSBoris Boutkov   PetscFunctionBegin;
9094363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9104363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
9118dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(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 
9219bf9660cSLawrence Mitchell    Input Arguments
9229bf9660cSLawrence Mitchell +  dm - the shell DM
9239bf9660cSLawrence Mitchell -  decomp - the routine to create the decomposition
9249bf9660cSLawrence Mitchell 
9259bf9660cSLawrence Mitchell    Level: advanced
9269bf9660cSLawrence Mitchell 
927fef3a512SBarry Smith .seealso: DMCreateFieldDecomposition(), DMShellSetContext(), DMShellGetContext()
9289bf9660cSLawrence Mitchell @*/
9295e2259d5SLawrence Mitchell PetscErrorCode DMShellSetCreateFieldDecomposition(DM dm, PetscErrorCode (*decomp)(DM,PetscInt*,char***, IS**,DM**))
9305e2259d5SLawrence Mitchell {
9315e2259d5SLawrence Mitchell   PetscErrorCode ierr;
9325e2259d5SLawrence Mitchell   PetscBool      isshell;
9335e2259d5SLawrence Mitchell 
9345e2259d5SLawrence Mitchell   PetscFunctionBegin;
9355e2259d5SLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9365e2259d5SLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
9375e2259d5SLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
9385e2259d5SLawrence Mitchell   dm->ops->createfielddecomposition = decomp;
9395e2259d5SLawrence Mitchell   PetscFunctionReturn(0);
9405e2259d5SLawrence Mitchell }
9415e2259d5SLawrence Mitchell 
942c00061e5SLawrence Mitchell /*@C
943e734121bSPatrick Farrell    DMShellSetCreateDomainDecomposition - Set the routine used to create a domain decomposition for the shell DM
944e734121bSPatrick Farrell 
945d083f849SBarry Smith    Logically Collective on dm
946e734121bSPatrick Farrell 
947e734121bSPatrick Farrell    Input Arguments
948e734121bSPatrick Farrell +  dm - the shell DM
949e734121bSPatrick Farrell -  decomp - the routine to create the decomposition
950e734121bSPatrick Farrell 
951e734121bSPatrick Farrell    Level: advanced
952e734121bSPatrick Farrell 
953e734121bSPatrick Farrell .seealso: DMCreateDomainDecomposition(), DMShellSetContext(), DMShellGetContext()
954e734121bSPatrick Farrell @*/
955e734121bSPatrick Farrell PetscErrorCode DMShellSetCreateDomainDecomposition(DM dm, PetscErrorCode (*decomp)(DM,PetscInt*,char***, IS**,IS**,DM**))
956e734121bSPatrick Farrell {
957e734121bSPatrick Farrell   PetscErrorCode ierr;
958e734121bSPatrick Farrell   PetscBool      isshell;
959e734121bSPatrick Farrell 
960e734121bSPatrick Farrell   PetscFunctionBegin;
961e734121bSPatrick Farrell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
962e734121bSPatrick Farrell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
963e734121bSPatrick Farrell   if (!isshell) PetscFunctionReturn(0);
964e734121bSPatrick Farrell   dm->ops->createdomaindecomposition = decomp;
965e734121bSPatrick Farrell   PetscFunctionReturn(0);
966e734121bSPatrick Farrell }
967e734121bSPatrick Farrell 
968e734121bSPatrick Farrell /*@C
969eef9d6cdSPatrick Farrell    DMShellSetCreateDomainDecompositionScatters - Set the routine used to create the scatter contexts for domain decomposition with a shell DM
970eef9d6cdSPatrick Farrell 
971d083f849SBarry Smith    Logically Collective on dm
972eef9d6cdSPatrick Farrell 
973eef9d6cdSPatrick Farrell    Input Arguments
974eef9d6cdSPatrick Farrell +  dm - the shell DM
975eef9d6cdSPatrick Farrell -  scatter - the routine to create the scatters
976eef9d6cdSPatrick Farrell 
977eef9d6cdSPatrick Farrell    Level: advanced
978eef9d6cdSPatrick Farrell 
979448b6425SPatrick Farrell .seealso: DMCreateDomainDecompositionScatters(), DMShellSetContext(), DMShellGetContext()
980eef9d6cdSPatrick Farrell @*/
981eef9d6cdSPatrick Farrell PetscErrorCode DMShellSetCreateDomainDecompositionScatters(DM dm, PetscErrorCode (*scatter)(DM,PetscInt,DM*,VecScatter**,VecScatter**,VecScatter**))
982eef9d6cdSPatrick Farrell {
983eef9d6cdSPatrick Farrell   PetscErrorCode ierr;
984eef9d6cdSPatrick Farrell   PetscBool      isshell;
985eef9d6cdSPatrick Farrell 
986eef9d6cdSPatrick Farrell   PetscFunctionBegin;
987eef9d6cdSPatrick Farrell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
988eef9d6cdSPatrick Farrell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
989eef9d6cdSPatrick Farrell   if (!isshell) PetscFunctionReturn(0);
990eef9d6cdSPatrick Farrell   dm->ops->createddscatters = scatter;
991eef9d6cdSPatrick Farrell   PetscFunctionReturn(0);
992eef9d6cdSPatrick Farrell }
993eef9d6cdSPatrick Farrell 
994eef9d6cdSPatrick Farrell /*@C
995c00061e5SLawrence Mitchell    DMShellSetCreateSubDM - Set the routine used to create a sub DM from the shell DM
996c00061e5SLawrence Mitchell 
997d083f849SBarry Smith    Logically Collective on dm
998c00061e5SLawrence Mitchell 
999c00061e5SLawrence Mitchell    Input Arguments
1000c00061e5SLawrence Mitchell +  dm - the shell DM
1001c00061e5SLawrence Mitchell -  subdm - the routine to create the decomposition
1002c00061e5SLawrence Mitchell 
1003c00061e5SLawrence Mitchell    Level: advanced
1004c00061e5SLawrence Mitchell 
1005bf890c61SBoris Boutkov .seealso: DMCreateSubDM(), DMShellGetCreateSubDM(), DMShellSetContext(), DMShellGetContext()
1006c00061e5SLawrence Mitchell @*/
1007276c5506SMatthew G. Knepley PetscErrorCode DMShellSetCreateSubDM(DM dm, PetscErrorCode (*subdm)(DM,PetscInt,const PetscInt[],IS*,DM*))
1008c00061e5SLawrence Mitchell {
1009c00061e5SLawrence Mitchell   PetscErrorCode ierr;
1010c00061e5SLawrence Mitchell   PetscBool      isshell;
1011c00061e5SLawrence Mitchell 
1012c00061e5SLawrence Mitchell   PetscFunctionBegin;
1013c00061e5SLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1014c00061e5SLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
1015c00061e5SLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
1016c00061e5SLawrence Mitchell   dm->ops->createsubdm = subdm;
1017c00061e5SLawrence Mitchell   PetscFunctionReturn(0);
1018c00061e5SLawrence Mitchell }
1019c00061e5SLawrence Mitchell 
10204363ddcaSBoris Boutkov /*@C
10214363ddcaSBoris Boutkov    DMShellGetCreateSubDM - Get the routine used to create a sub DM from the shell DM
10224363ddcaSBoris Boutkov 
1023d083f849SBarry Smith    Logically Collective on dm
10244363ddcaSBoris Boutkov 
1025a4a986ddSBoris Boutkov    Input Argument:
10264363ddcaSBoris Boutkov +  dm - the shell DM
1027a4a986ddSBoris Boutkov 
1028a4a986ddSBoris Boutkov    Output Argument:
10294363ddcaSBoris Boutkov -  subdm - the routine to create the decomposition
10304363ddcaSBoris Boutkov 
10314363ddcaSBoris Boutkov    Level: advanced
10324363ddcaSBoris Boutkov 
10334363ddcaSBoris Boutkov .seealso: DMCreateSubDM(), DMShellSetCreateSubDM(), DMShellSetContext(), DMShellGetContext()
10344363ddcaSBoris Boutkov @*/
10354363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateSubDM(DM dm, PetscErrorCode (**subdm)(DM,PetscInt,const PetscInt[],IS*,DM*))
10364363ddcaSBoris Boutkov {
10374363ddcaSBoris Boutkov   PetscErrorCode ierr;
10384363ddcaSBoris Boutkov   PetscBool      isshell;
10394363ddcaSBoris Boutkov 
10404363ddcaSBoris Boutkov   PetscFunctionBegin;
10414363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10424363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
10438dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
10444363ddcaSBoris Boutkov   *subdm = dm->ops->createsubdm;
10454363ddcaSBoris Boutkov   PetscFunctionReturn(0);
10464363ddcaSBoris Boutkov }
10474363ddcaSBoris Boutkov 
1048fe1899a2SJed Brown static PetscErrorCode DMDestroy_Shell(DM dm)
1049fe1899a2SJed Brown {
1050fe1899a2SJed Brown   PetscErrorCode ierr;
1051fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
1052fe1899a2SJed Brown 
1053fe1899a2SJed Brown   PetscFunctionBegin;
1054fe1899a2SJed Brown   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
1055fe1899a2SJed Brown   ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
1056dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
1057a94b16f6SRichard Tran Mills   ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr);
1058a94b16f6SRichard Tran Mills   ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr);
1059294a6417SLawrence Mitchell   ierr = VecScatterDestroy(&shell->ltol);CHKERRQ(ierr);
10607b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
10617b6ad80cSMatthew G Knepley   ierr = PetscFree(shell);CHKERRQ(ierr);
1062fe1899a2SJed Brown   PetscFunctionReturn(0);
1063fe1899a2SJed Brown }
1064fe1899a2SJed Brown 
10652d53ad75SBarry Smith static PetscErrorCode DMView_Shell(DM dm,PetscViewer v)
10662d53ad75SBarry Smith {
10672d53ad75SBarry Smith   PetscErrorCode ierr;
10682d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
10692d53ad75SBarry Smith 
10702d53ad75SBarry Smith   PetscFunctionBegin;
10712d53ad75SBarry Smith   ierr = VecView(shell->Xglobal,v);CHKERRQ(ierr);
10722d53ad75SBarry Smith   PetscFunctionReturn(0);
10732d53ad75SBarry Smith }
10742d53ad75SBarry Smith 
10752d53ad75SBarry Smith static PetscErrorCode DMLoad_Shell(DM dm,PetscViewer v)
10762d53ad75SBarry Smith {
10772d53ad75SBarry Smith   PetscErrorCode ierr;
10782d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
10792d53ad75SBarry Smith 
10802d53ad75SBarry Smith   PetscFunctionBegin;
1081ce94432eSBarry Smith   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&shell->Xglobal);CHKERRQ(ierr);
10822d53ad75SBarry Smith   ierr = VecLoad(shell->Xglobal,v);CHKERRQ(ierr);
10832d53ad75SBarry Smith   PetscFunctionReturn(0);
10842d53ad75SBarry Smith }
1085fe1899a2SJed Brown 
1086276c5506SMatthew G. Knepley PetscErrorCode DMCreateSubDM_Shell(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm)
10876e44b4cfSMatthew G. Knepley {
10886e44b4cfSMatthew G. Knepley   PetscErrorCode ierr;
10896e44b4cfSMatthew G. Knepley 
10906e44b4cfSMatthew G. Knepley   PetscFunctionBegin;
10916e44b4cfSMatthew G. Knepley   if (subdm) {ierr = DMShellCreate(PetscObjectComm((PetscObject) dm), subdm);CHKERRQ(ierr);}
1092792b654fSMatthew G. Knepley   ierr = DMCreateSectionSubDM(dm, numFields, fields, is, subdm);CHKERRQ(ierr);
10936e44b4cfSMatthew G. Knepley   PetscFunctionReturn(0);
10946e44b4cfSMatthew G. Knepley }
10956e44b4cfSMatthew G. Knepley 
10968cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm)
1097fe1899a2SJed Brown {
1098fe1899a2SJed Brown   PetscErrorCode ierr;
1099fe1899a2SJed Brown   DM_Shell       *shell;
1100fe1899a2SJed Brown 
1101fe1899a2SJed Brown   PetscFunctionBegin;
1102b00a9115SJed Brown   ierr     = PetscNewLog(dm,&shell);CHKERRQ(ierr);
11038c87107bSJed Brown   dm->data = shell;
1104fe1899a2SJed Brown 
11058c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
11068c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
1107dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
11088c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
11092d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
11102d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
11117a108d1dSBarry Smith   dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell;
11127a108d1dSBarry Smith   dm->ops->globaltolocalend   = DMGlobalToLocalEndDefaultShell;
111355daaa54SRichard Tran Mills   dm->ops->localtoglobalbegin = DMLocalToGlobalBeginDefaultShell;
111455daaa54SRichard Tran Mills   dm->ops->localtoglobalend   = DMLocalToGlobalEndDefaultShell;
111563731094SRichard Tran Mills   dm->ops->localtolocalbegin  = DMLocalToLocalBeginDefaultShell;
111663731094SRichard Tran Mills   dm->ops->localtolocalend    = DMLocalToLocalEndDefaultShell;
11176e44b4cfSMatthew G. Knepley   dm->ops->createsubdm        = DMCreateSubDM_Shell;
11182a350339SBarry Smith   ierr = DMSetMatType(dm,MATDENSE);CHKERRQ(ierr);
1119fe1899a2SJed Brown   PetscFunctionReturn(0);
1120fe1899a2SJed Brown }
1121fe1899a2SJed Brown 
1122fe1899a2SJed Brown /*@
1123fe1899a2SJed Brown     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
1124fe1899a2SJed Brown 
1125d083f849SBarry Smith     Collective
1126fe1899a2SJed Brown 
1127fe1899a2SJed Brown     Input Parameter:
1128fe1899a2SJed Brown .   comm - the processors that will share the global vector
1129fe1899a2SJed Brown 
1130fe1899a2SJed Brown     Output Parameters:
1131fe1899a2SJed Brown .   shell - the shell DM
1132fe1899a2SJed Brown 
1133fe1899a2SJed Brown     Level: advanced
1134fe1899a2SJed Brown 
1135fef3a512SBarry Smith .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateLocalVector(), DMShellSetContext(), DMShellGetContext()
1136fe1899a2SJed Brown @*/
1137fe1899a2SJed Brown PetscErrorCode  DMShellCreate(MPI_Comm comm,DM *dm)
1138fe1899a2SJed Brown {
1139fe1899a2SJed Brown   PetscErrorCode ierr;
1140fe1899a2SJed Brown 
1141fe1899a2SJed Brown   PetscFunctionBegin;
1142fe1899a2SJed Brown   PetscValidPointer(dm,2);
1143fe1899a2SJed Brown   ierr = DMCreate(comm,dm);CHKERRQ(ierr);
1144fe1899a2SJed Brown   ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr);
114581a566bfSMatthew G. Knepley   ierr = DMSetUp(*dm);CHKERRQ(ierr);
1146fe1899a2SJed Brown   PetscFunctionReturn(0);
1147fe1899a2SJed Brown }
1148