xref: /petsc/src/dm/impls/shell/dmshell.c (revision 7a108d1d0205d8fcc419d64458dcd971d96738a7)
1fe1899a2SJed Brown #include <petscdmshell.h>       /*I    "petscdmshell.h"  I*/
207475bc1SBarry Smith #include <petscmat.h>
307475bc1SBarry Smith #include <petsc-private/dmimpl.h>
4fe1899a2SJed Brown 
5fe1899a2SJed Brown typedef struct  {
6fe1899a2SJed Brown   Vec        Xglobal;
7dc43b69eSJed Brown   Vec        Xlocal;
8fe1899a2SJed Brown   Mat        A;
981634712SRichard Tran Mills   VecScatter *gtol;
1081634712SRichard Tran Mills   VecScatter *ltog;
11fe1899a2SJed Brown } DM_Shell;
12fe1899a2SJed Brown 
13fe1899a2SJed Brown #undef __FUNCT__
14*7a108d1dSBarry Smith #define __FUNCT__ "DMGlobalToLocalBeginDefaultShell"
15*7a108d1dSBarry Smith /*@
16*7a108d1dSBarry 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 
25*7a108d1dSBarry Smith    Level: advanced
268d359177SBarry Smith 
27*7a108d1dSBarry 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.
28*7a108d1dSBarry Smith 
29*7a108d1dSBarry Smith .seealso: DMGlobalToLocalEndDefaultShell()
308d359177SBarry Smith @*/
31*7a108d1dSBarry 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;
37*7a108d1dSBarry Smith   if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
388d359177SBarry Smith   ierr = VecScatterBegin(*(shell->gtol),g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
398d359177SBarry Smith   PetscFunctionReturn(0);
408d359177SBarry Smith }
418d359177SBarry Smith 
428d359177SBarry Smith #undef __FUNCT__
43*7a108d1dSBarry Smith #define __FUNCT__ "DMGlobalToLocalEndDefaultShell"
44*7a108d1dSBarry Smith /*@
45*7a108d1dSBarry Smith    DMGlobalToLocalEndDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to end a global to local scatter
468d359177SBarry Smith    Collective
478d359177SBarry Smith 
488d359177SBarry Smith    Input Arguments:
498d359177SBarry Smith +  dm - shell DM
508d359177SBarry Smith .  g - global vector
518d359177SBarry Smith .  mode - InsertMode
528d359177SBarry Smith -  l - local vector
538d359177SBarry Smith 
54*7a108d1dSBarry Smith    Level: advanced
558d359177SBarry Smith 
56*7a108d1dSBarry Smith .seealso: DMGlobalToLocalBeginDefaultShell()
578d359177SBarry Smith @*/
58*7a108d1dSBarry Smith PetscErrorCode DMGlobalToLocalEndDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
598d359177SBarry Smith {
608d359177SBarry Smith   PetscErrorCode ierr;
618d359177SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
628d359177SBarry Smith 
638d359177SBarry Smith   PetscFunctionBegin;
64*7a108d1dSBarry Smith    if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
65*7a108d1dSBarry Smith   ierr = VecScatterEnd(*(shell->gtol),g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
668d359177SBarry Smith   PetscFunctionReturn(0);
678d359177SBarry Smith }
688d359177SBarry Smith 
698d359177SBarry Smith #undef __FUNCT__
70fe1899a2SJed Brown #define __FUNCT__ "DMCreateMatrix_Shell"
7119fd82e9SBarry Smith static PetscErrorCode DMCreateMatrix_Shell(DM dm,MatType mtype,Mat *J)
72fe1899a2SJed Brown {
73fe1899a2SJed Brown   PetscErrorCode ierr;
74fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
75fe1899a2SJed Brown   Mat            A;
76fe1899a2SJed Brown 
77fe1899a2SJed Brown   PetscFunctionBegin;
78fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
79fe1899a2SJed Brown   PetscValidPointer(J,3);
807bde9f88SJed Brown   if (!shell->A) {
817bde9f88SJed Brown     if (shell->Xglobal) {
827bde9f88SJed Brown       PetscInt m,M;
837bde9f88SJed Brown       ierr = PetscInfo(dm,"Naively creating matrix using global vector distribution without preallocation");CHKERRQ(ierr);
847bde9f88SJed Brown       ierr = VecGetSize(shell->Xglobal,&M);CHKERRQ(ierr);
857bde9f88SJed Brown       ierr = VecGetLocalSize(shell->Xglobal,&m);CHKERRQ(ierr);
86ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)dm),&shell->A);CHKERRQ(ierr);
877bde9f88SJed Brown       ierr = MatSetSizes(shell->A,m,m,M,M);CHKERRQ(ierr);
887bde9f88SJed Brown       if (mtype) {ierr = MatSetType(shell->A,mtype);CHKERRQ(ierr);}
897bde9f88SJed Brown       ierr = MatSetUp(shell->A);CHKERRQ(ierr);
90ce94432eSBarry Smith     } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector");
917bde9f88SJed Brown   }
92fe1899a2SJed Brown   A = shell->A;
93ad6bc421SBarry Smith   /* the check below is tacky and incomplete */
94fe1899a2SJed Brown   if (mtype) {
95ad6bc421SBarry Smith     PetscBool flg,aij,seqaij,mpiaij;
96251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)A,mtype,&flg);CHKERRQ(ierr);
97ad6bc421SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
98ad6bc421SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&mpiaij);CHKERRQ(ierr);
99ad6bc421SBarry Smith     ierr = PetscStrcmp(mtype,MATAIJ,&aij);CHKERRQ(ierr);
100ad6bc421SBarry Smith     if (!flg) {
101ce94432eSBarry Smith       if (!(aij & (seqaij || mpiaij))) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_NOTSAMETYPE,"Requested matrix of type %s, but only %s available",mtype,((PetscObject)A)->type_name);
102ad6bc421SBarry Smith     }
103fe1899a2SJed Brown   }
104fe1899a2SJed Brown   if (((PetscObject)A)->refct < 2) { /* We have an exclusive reference so we can give it out */
105fe1899a2SJed Brown     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
106fe1899a2SJed Brown     ierr = MatZeroEntries(A);CHKERRQ(ierr);
107fe1899a2SJed Brown     *J   = A;
108fe1899a2SJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
109fe1899a2SJed Brown     ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,J);CHKERRQ(ierr);
110fe1899a2SJed Brown     ierr = MatZeroEntries(*J);CHKERRQ(ierr);
111fe1899a2SJed Brown   }
112fe1899a2SJed Brown   PetscFunctionReturn(0);
113fe1899a2SJed Brown }
114fe1899a2SJed Brown 
115fe1899a2SJed Brown #undef __FUNCT__
116fe1899a2SJed Brown #define __FUNCT__ "DMCreateGlobalVector_Shell"
117fe1899a2SJed Brown PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec)
118fe1899a2SJed Brown {
119fe1899a2SJed Brown   PetscErrorCode ierr;
120fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
121fe1899a2SJed Brown   Vec            X;
122fe1899a2SJed Brown 
123fe1899a2SJed Brown   PetscFunctionBegin;
124fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
125fe1899a2SJed Brown   PetscValidPointer(gvec,2);
126fe1899a2SJed Brown   *gvec = 0;
127fe1899a2SJed Brown   X     = shell->Xglobal;
128ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
129fe1899a2SJed Brown   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
130fe1899a2SJed Brown     ierr  = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
131fe1899a2SJed Brown     ierr  = VecZeroEntries(X);CHKERRQ(ierr);
132fe1899a2SJed Brown     *gvec = X;
133fe1899a2SJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
134fe1899a2SJed Brown     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
135fe1899a2SJed Brown     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
136fe1899a2SJed Brown   }
137c688c046SMatthew G Knepley   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
138fe1899a2SJed Brown   PetscFunctionReturn(0);
139fe1899a2SJed Brown }
140fe1899a2SJed Brown 
141fe1899a2SJed Brown #undef __FUNCT__
142dc43b69eSJed Brown #define __FUNCT__ "DMCreateLocalVector_Shell"
143dc43b69eSJed Brown PetscErrorCode DMCreateLocalVector_Shell(DM dm,Vec *gvec)
144dc43b69eSJed Brown {
145dc43b69eSJed Brown   PetscErrorCode ierr;
146dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
147dc43b69eSJed Brown   Vec            X;
148dc43b69eSJed Brown 
149dc43b69eSJed Brown   PetscFunctionBegin;
150dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
151dc43b69eSJed Brown   PetscValidPointer(gvec,2);
152dc43b69eSJed Brown   *gvec = 0;
153dc43b69eSJed Brown   X     = shell->Xlocal;
154ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()");
155dc43b69eSJed Brown   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
156dc43b69eSJed Brown     ierr  = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
157dc43b69eSJed Brown     ierr  = VecZeroEntries(X);CHKERRQ(ierr);
158dc43b69eSJed Brown     *gvec = X;
159dc43b69eSJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
160dc43b69eSJed Brown     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
161dc43b69eSJed Brown     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
162dc43b69eSJed Brown   }
1636e4cbd8bSMark F. Adams   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
164dc43b69eSJed Brown   PetscFunctionReturn(0);
165dc43b69eSJed Brown }
166dc43b69eSJed Brown 
167dc43b69eSJed Brown #undef __FUNCT__
168fe1899a2SJed Brown #define __FUNCT__ "DMShellSetMatrix"
169fe1899a2SJed Brown /*@
170fe1899a2SJed Brown    DMShellSetMatrix - sets a template matrix associated with the DMShell
171fe1899a2SJed Brown 
172fe1899a2SJed Brown    Collective
173fe1899a2SJed Brown 
174fe1899a2SJed Brown    Input Arguments:
175fe1899a2SJed Brown +  dm - shell DM
176fe1899a2SJed Brown -  J - template matrix
177fe1899a2SJed Brown 
178fe1899a2SJed Brown    Level: advanced
179fe1899a2SJed Brown 
180fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetCreateMatrix()
181fe1899a2SJed Brown @*/
182fe1899a2SJed Brown PetscErrorCode DMShellSetMatrix(DM dm,Mat J)
183fe1899a2SJed Brown {
184fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
185fe1899a2SJed Brown   PetscErrorCode ierr;
1868c87107bSJed Brown   PetscBool      isshell;
187fe1899a2SJed Brown 
188fe1899a2SJed Brown   PetscFunctionBegin;
1898c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1908c87107bSJed Brown   PetscValidHeaderSpecific(J,MAT_CLASSID,2);
191251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
1928c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
193fe1899a2SJed Brown   ierr     = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
194fe1899a2SJed Brown   ierr     = MatDestroy(&shell->A);CHKERRQ(ierr);
195fe1899a2SJed Brown   shell->A = J;
196fe1899a2SJed Brown   PetscFunctionReturn(0);
197fe1899a2SJed Brown }
198fe1899a2SJed Brown 
199fe1899a2SJed Brown #undef __FUNCT__
200fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateMatrix"
201fe1899a2SJed Brown /*@C
202fe1899a2SJed Brown    DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM
203fe1899a2SJed Brown 
204fe1899a2SJed Brown    Logically Collective on DM
205fe1899a2SJed Brown 
206fe1899a2SJed Brown    Input Arguments:
207fe1899a2SJed Brown +  dm - the shell DM
208fe1899a2SJed Brown -  func - the function to create a matrix
209fe1899a2SJed Brown 
210fe1899a2SJed Brown    Level: advanced
211fe1899a2SJed Brown 
212fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetMatrix()
213fe1899a2SJed Brown @*/
21419fd82e9SBarry Smith PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,MatType,Mat*))
215fe1899a2SJed Brown {
216fe1899a2SJed Brown 
217fe1899a2SJed Brown   PetscFunctionBegin;
218fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
219fe1899a2SJed Brown   dm->ops->creatematrix = func;
220fe1899a2SJed Brown   PetscFunctionReturn(0);
221fe1899a2SJed Brown }
222fe1899a2SJed Brown 
223fe1899a2SJed Brown #undef __FUNCT__
224fe1899a2SJed Brown #define __FUNCT__ "DMShellSetGlobalVector"
225fe1899a2SJed Brown /*@
226fe1899a2SJed Brown    DMShellSetGlobalVector - sets a template global vector associated with the DMShell
227fe1899a2SJed Brown 
228fe1899a2SJed Brown    Logically Collective on DM
229fe1899a2SJed Brown 
230fe1899a2SJed Brown    Input Arguments:
231fe1899a2SJed Brown +  dm - shell DM
232fe1899a2SJed Brown -  X - template vector
233fe1899a2SJed Brown 
234fe1899a2SJed Brown    Level: advanced
235fe1899a2SJed Brown 
236fe1899a2SJed Brown .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector()
237fe1899a2SJed Brown @*/
238fe1899a2SJed Brown PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X)
239fe1899a2SJed Brown {
240fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
241fe1899a2SJed Brown   PetscErrorCode ierr;
2428c87107bSJed Brown   PetscBool      isshell;
243fe1899a2SJed Brown 
244fe1899a2SJed Brown   PetscFunctionBegin;
2458c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2468c87107bSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
247251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
2488c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
249fe1899a2SJed Brown   ierr           = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
250fe1899a2SJed Brown   ierr           = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
251fe1899a2SJed Brown   shell->Xglobal = X;
252fe1899a2SJed Brown   PetscFunctionReturn(0);
253fe1899a2SJed Brown }
254fe1899a2SJed Brown 
255fe1899a2SJed Brown #undef __FUNCT__
256fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateGlobalVector"
257fe1899a2SJed Brown /*@C
258fe1899a2SJed Brown    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM
259fe1899a2SJed Brown 
260fe1899a2SJed Brown    Logically Collective
261fe1899a2SJed Brown 
262fe1899a2SJed Brown    Input Arguments:
263fe1899a2SJed Brown +  dm - the shell DM
264fe1899a2SJed Brown -  func - the creation routine
265fe1899a2SJed Brown 
266fe1899a2SJed Brown    Level: advanced
267fe1899a2SJed Brown 
268fe1899a2SJed Brown .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix()
269fe1899a2SJed Brown @*/
270fe1899a2SJed Brown PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
271fe1899a2SJed Brown {
272fe1899a2SJed Brown 
273fe1899a2SJed Brown   PetscFunctionBegin;
274fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
275fe1899a2SJed Brown   dm->ops->createglobalvector = func;
276fe1899a2SJed Brown   PetscFunctionReturn(0);
277fe1899a2SJed Brown }
278fe1899a2SJed Brown 
279fe1899a2SJed Brown #undef __FUNCT__
280dc43b69eSJed Brown #define __FUNCT__ "DMShellSetLocalVector"
281dc43b69eSJed Brown /*@
282dc43b69eSJed Brown    DMShellSetLocalVector - sets a template local vector associated with the DMShell
283dc43b69eSJed Brown 
284dc43b69eSJed Brown    Logically Collective on DM
285dc43b69eSJed Brown 
286dc43b69eSJed Brown    Input Arguments:
287dc43b69eSJed Brown +  dm - shell DM
288dc43b69eSJed Brown -  X - template vector
289dc43b69eSJed Brown 
290dc43b69eSJed Brown    Level: advanced
291dc43b69eSJed Brown 
292dc43b69eSJed Brown .seealso: DMCreateLocalVector(), DMShellSetMatrix(), DMShellSetCreateLocalVector()
293dc43b69eSJed Brown @*/
294dc43b69eSJed Brown PetscErrorCode DMShellSetLocalVector(DM dm,Vec X)
295dc43b69eSJed Brown {
296dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
297dc43b69eSJed Brown   PetscErrorCode ierr;
298dc43b69eSJed Brown   PetscBool      isshell;
299dc43b69eSJed Brown 
300dc43b69eSJed Brown   PetscFunctionBegin;
301dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
302dc43b69eSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
303dc43b69eSJed Brown   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
304dc43b69eSJed Brown   if (!isshell) PetscFunctionReturn(0);
305dc43b69eSJed Brown   ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
306dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
307dc43b69eSJed Brown   shell->Xlocal = X;
308dc43b69eSJed Brown   PetscFunctionReturn(0);
309dc43b69eSJed Brown }
310dc43b69eSJed Brown 
311dc43b69eSJed Brown #undef __FUNCT__
312dc43b69eSJed Brown #define __FUNCT__ "DMShellSetCreateLocalVector"
313dc43b69eSJed Brown /*@C
314dc43b69eSJed Brown    DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM
315dc43b69eSJed Brown 
316dc43b69eSJed Brown    Logically Collective
317dc43b69eSJed Brown 
318dc43b69eSJed Brown    Input Arguments:
319dc43b69eSJed Brown +  dm - the shell DM
320dc43b69eSJed Brown -  func - the creation routine
321dc43b69eSJed Brown 
322dc43b69eSJed Brown    Level: advanced
323dc43b69eSJed Brown 
324dc43b69eSJed Brown .seealso: DMShellSetLocalVector(), DMShellSetCreateMatrix()
325dc43b69eSJed Brown @*/
326dc43b69eSJed Brown PetscErrorCode DMShellSetCreateLocalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
327dc43b69eSJed Brown {
328dc43b69eSJed Brown 
329dc43b69eSJed Brown   PetscFunctionBegin;
330dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
331dc43b69eSJed Brown   dm->ops->createlocalvector = func;
332dc43b69eSJed Brown   PetscFunctionReturn(0);
333dc43b69eSJed Brown }
334dc43b69eSJed Brown 
335dc43b69eSJed Brown #undef __FUNCT__
3368339e6d0SRichard Tran Mills #define __FUNCT__ "DMShellSetGlobalToLocal"
3378339e6d0SRichard Tran Mills /*@C
3388339e6d0SRichard Tran Mills    DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter
3398339e6d0SRichard Tran Mills 
3408339e6d0SRichard Tran Mills    Logically Collective on DM
3418339e6d0SRichard Tran Mills 
3428339e6d0SRichard Tran Mills    Input Arguments
3438339e6d0SRichard Tran Mills +  dm - the shell DM
3448339e6d0SRichard Tran Mills .  begin - the routine that begins the global to local scatter
3458339e6d0SRichard Tran Mills -  end - the routine that ends the global to local scatter
3468339e6d0SRichard Tran Mills 
347*7a108d1dSBarry Smith    Notes: If these functions are not provided but DMShellSetGlobalToLocalVecScatter() is called then
348*7a108d1dSBarry Smith    DMGlobalToLocalBeginDefaultShell() are used to to perform the transfers DMGlobalToLocalEndDefaultShell()
349*7a108d1dSBarry Smith 
3508339e6d0SRichard Tran Mills    Level: advanced
3518339e6d0SRichard Tran Mills 
352*7a108d1dSBarry Smith .seealso: DMShellSetLocalToGlobal(), DMGlobalToLocalBeginDefaultShell(), DMGlobalToLocalEndDefaultShell()
3538339e6d0SRichard Tran Mills @*/
3548339e6d0SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
3558339e6d0SRichard Tran Mills   PetscFunctionBegin;
3568339e6d0SRichard Tran Mills   dm->ops->globaltolocalbegin = begin;
3578339e6d0SRichard Tran Mills   dm->ops->globaltolocalend = end;
3588339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
3598339e6d0SRichard Tran Mills }
3608339e6d0SRichard Tran Mills 
3618339e6d0SRichard Tran Mills #undef __FUNCT__
3628339e6d0SRichard Tran Mills #define __FUNCT__ "DMShellSetLocalToGlobal"
3638339e6d0SRichard Tran Mills /*@C
3648339e6d0SRichard Tran Mills    DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter
3658339e6d0SRichard Tran Mills 
3668339e6d0SRichard Tran Mills    Logically Collective on DM
3678339e6d0SRichard Tran Mills 
3688339e6d0SRichard Tran Mills    Input Arguments
3698339e6d0SRichard Tran Mills +  dm - the shell DM
3708339e6d0SRichard Tran Mills .  begin - the routine that begins the local to global scatter
3718339e6d0SRichard Tran Mills -  end - the routine that ends the local to global scatter
3728339e6d0SRichard Tran Mills 
3738339e6d0SRichard Tran Mills    Level: advanced
3748339e6d0SRichard Tran Mills 
3758339e6d0SRichard Tran Mills .seealso: DMShellSetGlobalToLocal()
3768339e6d0SRichard Tran Mills @*/
3778339e6d0SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
3788339e6d0SRichard Tran Mills   PetscFunctionBegin;
3798339e6d0SRichard Tran Mills   dm->ops->localtoglobalbegin = begin;
3808339e6d0SRichard Tran Mills   dm->ops->localtoglobalend = end;
3818339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
3828339e6d0SRichard Tran Mills }
3838339e6d0SRichard Tran Mills 
3848339e6d0SRichard Tran Mills #undef __FUNCT__
38581634712SRichard Tran Mills #define __FUNCT__ "DMShellSetGlobalToLocalVecScatter"
38681634712SRichard Tran Mills /*@
38781634712SRichard Tran Mills    DMShellSetGlobalToLocalVecScatter - Sets a VecScatter context for global to local communication
38881634712SRichard Tran Mills 
38981634712SRichard Tran Mills    Logically Collective on DM
39081634712SRichard Tran Mills 
39181634712SRichard Tran Mills    Input Arguments
39281634712SRichard Tran Mills +  dm - the shell DM
39381634712SRichard Tran Mills -  gtol - the global to local VecScatter context
39481634712SRichard Tran Mills 
39581634712SRichard Tran Mills    Level: advanced
39681634712SRichard Tran Mills 
39781634712SRichard Tran Mills .seealso: DMShellSetGlobalToLocal()
39881634712SRichard Tran Mills @*/
39981634712SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter *gtol)
40081634712SRichard Tran Mills {
40181634712SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
40281634712SRichard Tran Mills 
403b300e4a8SRichard Tran Mills   PetscFunctionBegin;
40481634712SRichard Tran Mills   shell->gtol = gtol;
40581634712SRichard Tran Mills   PetscFunctionReturn(0);
40681634712SRichard Tran Mills }
40781634712SRichard Tran Mills 
40881634712SRichard Tran Mills #undef __FUNCT__
409fe1899a2SJed Brown #define __FUNCT__ "DMDestroy_Shell"
410fe1899a2SJed Brown static PetscErrorCode DMDestroy_Shell(DM dm)
411fe1899a2SJed Brown {
412fe1899a2SJed Brown   PetscErrorCode ierr;
413fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
414fe1899a2SJed Brown 
415fe1899a2SJed Brown   PetscFunctionBegin;
416fe1899a2SJed Brown   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
417fe1899a2SJed Brown   ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
418dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
4197b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
4207b6ad80cSMatthew G Knepley   ierr = PetscFree(shell);CHKERRQ(ierr);
421fe1899a2SJed Brown   PetscFunctionReturn(0);
422fe1899a2SJed Brown }
423fe1899a2SJed Brown 
4242d53ad75SBarry Smith #undef __FUNCT__
4252d53ad75SBarry Smith #define __FUNCT__ "DMView_Shell"
4262d53ad75SBarry Smith static PetscErrorCode DMView_Shell(DM dm,PetscViewer v)
4272d53ad75SBarry Smith {
4282d53ad75SBarry Smith   PetscErrorCode ierr;
4292d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
4302d53ad75SBarry Smith 
4312d53ad75SBarry Smith   PetscFunctionBegin;
4322d53ad75SBarry Smith   ierr = VecView(shell->Xglobal,v);CHKERRQ(ierr);
4332d53ad75SBarry Smith   PetscFunctionReturn(0);
4342d53ad75SBarry Smith }
4352d53ad75SBarry Smith 
4362d53ad75SBarry Smith #undef __FUNCT__
4372d53ad75SBarry Smith #define __FUNCT__ "DMLoad_Shell"
4382d53ad75SBarry Smith static PetscErrorCode DMLoad_Shell(DM dm,PetscViewer v)
4392d53ad75SBarry Smith {
4402d53ad75SBarry Smith   PetscErrorCode ierr;
4412d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
4422d53ad75SBarry Smith 
4432d53ad75SBarry Smith   PetscFunctionBegin;
444ce94432eSBarry Smith   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&shell->Xglobal);CHKERRQ(ierr);
4452d53ad75SBarry Smith   ierr = VecLoad(shell->Xglobal,v);CHKERRQ(ierr);
4462d53ad75SBarry Smith   PetscFunctionReturn(0);
4472d53ad75SBarry Smith }
448fe1899a2SJed Brown 
449fe1899a2SJed Brown #undef __FUNCT__
450fe1899a2SJed Brown #define __FUNCT__ "DMCreate_Shell"
4518cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm)
452fe1899a2SJed Brown {
453fe1899a2SJed Brown   PetscErrorCode ierr;
454fe1899a2SJed Brown   DM_Shell       *shell;
455fe1899a2SJed Brown 
456fe1899a2SJed Brown   PetscFunctionBegin;
4578c87107bSJed Brown   ierr     = PetscNewLog(dm,DM_Shell,&shell);CHKERRQ(ierr);
4588c87107bSJed Brown   dm->data = shell;
459fe1899a2SJed Brown 
4608c87107bSJed Brown   ierr = PetscObjectChangeTypeName((PetscObject)dm,DMSHELL);CHKERRQ(ierr);
4618865f1eaSKarl Rupp 
4628c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
4638c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
464dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
4658c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
4662d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
4672d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
468*7a108d1dSBarry Smith   dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell;
469*7a108d1dSBarry Smith   dm->ops->globaltolocalend   = DMGlobalToLocalEndDefaultShell;
470fe1899a2SJed Brown   PetscFunctionReturn(0);
471fe1899a2SJed Brown }
472fe1899a2SJed Brown 
473fe1899a2SJed Brown #undef __FUNCT__
474fe1899a2SJed Brown #define __FUNCT__ "DMShellCreate"
475fe1899a2SJed Brown /*@
476fe1899a2SJed Brown     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
477fe1899a2SJed Brown 
478fe1899a2SJed Brown     Collective on MPI_Comm
479fe1899a2SJed Brown 
480fe1899a2SJed Brown     Input Parameter:
481fe1899a2SJed Brown .   comm - the processors that will share the global vector
482fe1899a2SJed Brown 
483fe1899a2SJed Brown     Output Parameters:
484fe1899a2SJed Brown .   shell - the shell DM
485fe1899a2SJed Brown 
486fe1899a2SJed Brown     Level: advanced
487fe1899a2SJed Brown 
488dc43b69eSJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateLocalVector()
489fe1899a2SJed Brown @*/
490fe1899a2SJed Brown PetscErrorCode  DMShellCreate(MPI_Comm comm,DM *dm)
491fe1899a2SJed Brown {
492fe1899a2SJed Brown   PetscErrorCode ierr;
493fe1899a2SJed Brown 
494fe1899a2SJed Brown   PetscFunctionBegin;
495fe1899a2SJed Brown   PetscValidPointer(dm,2);
496fe1899a2SJed Brown   ierr = DMCreate(comm,dm);CHKERRQ(ierr);
497fe1899a2SJed Brown   ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr);
498fe1899a2SJed Brown   PetscFunctionReturn(0);
499fe1899a2SJed Brown }
50081634712SRichard Tran Mills 
501