xref: /petsc/src/dm/impls/shell/dmshell.c (revision 8339e6d0ff32651904d94f8c68b15d775601541d)
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;
9fe1899a2SJed Brown } DM_Shell;
10fe1899a2SJed Brown 
11fe1899a2SJed Brown #undef __FUNCT__
12fe1899a2SJed Brown #define __FUNCT__ "DMCreateMatrix_Shell"
1319fd82e9SBarry Smith static PetscErrorCode DMCreateMatrix_Shell(DM dm,MatType mtype,Mat *J)
14fe1899a2SJed Brown {
15fe1899a2SJed Brown   PetscErrorCode ierr;
16fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
17fe1899a2SJed Brown   Mat            A;
18fe1899a2SJed Brown 
19fe1899a2SJed Brown   PetscFunctionBegin;
20fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
21fe1899a2SJed Brown   PetscValidPointer(J,3);
227bde9f88SJed Brown   if (!shell->A) {
237bde9f88SJed Brown     if (shell->Xglobal) {
247bde9f88SJed Brown       PetscInt m,M;
257bde9f88SJed Brown       ierr = PetscInfo(dm,"Naively creating matrix using global vector distribution without preallocation");CHKERRQ(ierr);
267bde9f88SJed Brown       ierr = VecGetSize(shell->Xglobal,&M);CHKERRQ(ierr);
277bde9f88SJed Brown       ierr = VecGetLocalSize(shell->Xglobal,&m);CHKERRQ(ierr);
28ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)dm),&shell->A);CHKERRQ(ierr);
297bde9f88SJed Brown       ierr = MatSetSizes(shell->A,m,m,M,M);CHKERRQ(ierr);
307bde9f88SJed Brown       if (mtype) {ierr = MatSetType(shell->A,mtype);CHKERRQ(ierr);}
317bde9f88SJed Brown       ierr = MatSetUp(shell->A);CHKERRQ(ierr);
32ce94432eSBarry Smith     } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector");
337bde9f88SJed Brown   }
34fe1899a2SJed Brown   A = shell->A;
35ad6bc421SBarry Smith   /* the check below is tacky and incomplete */
36fe1899a2SJed Brown   if (mtype) {
37ad6bc421SBarry Smith     PetscBool flg,aij,seqaij,mpiaij;
38251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)A,mtype,&flg);CHKERRQ(ierr);
39ad6bc421SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
40ad6bc421SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&mpiaij);CHKERRQ(ierr);
41ad6bc421SBarry Smith     ierr = PetscStrcmp(mtype,MATAIJ,&aij);CHKERRQ(ierr);
42ad6bc421SBarry Smith     if (!flg) {
43ce94432eSBarry 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);
44ad6bc421SBarry Smith     }
45fe1899a2SJed Brown   }
46fe1899a2SJed Brown   if (((PetscObject)A)->refct < 2) { /* We have an exclusive reference so we can give it out */
47fe1899a2SJed Brown     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
48fe1899a2SJed Brown     ierr = MatZeroEntries(A);CHKERRQ(ierr);
49fe1899a2SJed Brown     *J   = A;
50fe1899a2SJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
51fe1899a2SJed Brown     ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,J);CHKERRQ(ierr);
52fe1899a2SJed Brown     ierr = MatZeroEntries(*J);CHKERRQ(ierr);
53fe1899a2SJed Brown   }
54fe1899a2SJed Brown   PetscFunctionReturn(0);
55fe1899a2SJed Brown }
56fe1899a2SJed Brown 
57fe1899a2SJed Brown #undef __FUNCT__
58fe1899a2SJed Brown #define __FUNCT__ "DMCreateGlobalVector_Shell"
59fe1899a2SJed Brown PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec)
60fe1899a2SJed Brown {
61fe1899a2SJed Brown   PetscErrorCode ierr;
62fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
63fe1899a2SJed Brown   Vec            X;
64fe1899a2SJed Brown 
65fe1899a2SJed Brown   PetscFunctionBegin;
66fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
67fe1899a2SJed Brown   PetscValidPointer(gvec,2);
68fe1899a2SJed Brown   *gvec = 0;
69fe1899a2SJed Brown   X     = shell->Xglobal;
70ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
71fe1899a2SJed Brown   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
72fe1899a2SJed Brown     ierr  = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
73fe1899a2SJed Brown     ierr  = VecZeroEntries(X);CHKERRQ(ierr);
74fe1899a2SJed Brown     *gvec = X;
75fe1899a2SJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
76fe1899a2SJed Brown     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
77fe1899a2SJed Brown     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
78fe1899a2SJed Brown   }
79c688c046SMatthew G Knepley   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
80fe1899a2SJed Brown   PetscFunctionReturn(0);
81fe1899a2SJed Brown }
82fe1899a2SJed Brown 
83fe1899a2SJed Brown #undef __FUNCT__
84dc43b69eSJed Brown #define __FUNCT__ "DMCreateLocalVector_Shell"
85dc43b69eSJed Brown PetscErrorCode DMCreateLocalVector_Shell(DM dm,Vec *gvec)
86dc43b69eSJed Brown {
87dc43b69eSJed Brown   PetscErrorCode ierr;
88dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
89dc43b69eSJed Brown   Vec            X;
90dc43b69eSJed Brown 
91dc43b69eSJed Brown   PetscFunctionBegin;
92dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
93dc43b69eSJed Brown   PetscValidPointer(gvec,2);
94dc43b69eSJed Brown   *gvec = 0;
95dc43b69eSJed Brown   X     = shell->Xlocal;
96ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()");
97dc43b69eSJed Brown   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
98dc43b69eSJed Brown     ierr  = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
99dc43b69eSJed Brown     ierr  = VecZeroEntries(X);CHKERRQ(ierr);
100dc43b69eSJed Brown     *gvec = X;
101dc43b69eSJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
102dc43b69eSJed Brown     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
103dc43b69eSJed Brown     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
104dc43b69eSJed Brown   }
1056e4cbd8bSMark F. Adams   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
106dc43b69eSJed Brown   PetscFunctionReturn(0);
107dc43b69eSJed Brown }
108dc43b69eSJed Brown 
109dc43b69eSJed Brown #undef __FUNCT__
110fe1899a2SJed Brown #define __FUNCT__ "DMShellSetMatrix"
111fe1899a2SJed Brown /*@
112fe1899a2SJed Brown    DMShellSetMatrix - sets a template matrix associated with the DMShell
113fe1899a2SJed Brown 
114fe1899a2SJed Brown    Collective
115fe1899a2SJed Brown 
116fe1899a2SJed Brown    Input Arguments:
117fe1899a2SJed Brown +  dm - shell DM
118fe1899a2SJed Brown -  J - template matrix
119fe1899a2SJed Brown 
120fe1899a2SJed Brown    Level: advanced
121fe1899a2SJed Brown 
122fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetCreateMatrix()
123fe1899a2SJed Brown @*/
124fe1899a2SJed Brown PetscErrorCode DMShellSetMatrix(DM dm,Mat J)
125fe1899a2SJed Brown {
126fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
127fe1899a2SJed Brown   PetscErrorCode ierr;
1288c87107bSJed Brown   PetscBool      isshell;
129fe1899a2SJed Brown 
130fe1899a2SJed Brown   PetscFunctionBegin;
1318c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1328c87107bSJed Brown   PetscValidHeaderSpecific(J,MAT_CLASSID,2);
133251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
1348c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
135fe1899a2SJed Brown   ierr     = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
136fe1899a2SJed Brown   ierr     = MatDestroy(&shell->A);CHKERRQ(ierr);
137fe1899a2SJed Brown   shell->A = J;
138fe1899a2SJed Brown   PetscFunctionReturn(0);
139fe1899a2SJed Brown }
140fe1899a2SJed Brown 
141fe1899a2SJed Brown #undef __FUNCT__
142fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateMatrix"
143fe1899a2SJed Brown /*@C
144fe1899a2SJed Brown    DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM
145fe1899a2SJed Brown 
146fe1899a2SJed Brown    Logically Collective on DM
147fe1899a2SJed Brown 
148fe1899a2SJed Brown    Input Arguments:
149fe1899a2SJed Brown +  dm - the shell DM
150fe1899a2SJed Brown -  func - the function to create a matrix
151fe1899a2SJed Brown 
152fe1899a2SJed Brown    Level: advanced
153fe1899a2SJed Brown 
154fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetMatrix()
155fe1899a2SJed Brown @*/
15619fd82e9SBarry Smith PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,MatType,Mat*))
157fe1899a2SJed Brown {
158fe1899a2SJed Brown 
159fe1899a2SJed Brown   PetscFunctionBegin;
160fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
161fe1899a2SJed Brown   dm->ops->creatematrix = func;
162fe1899a2SJed Brown   PetscFunctionReturn(0);
163fe1899a2SJed Brown }
164fe1899a2SJed Brown 
165fe1899a2SJed Brown #undef __FUNCT__
166fe1899a2SJed Brown #define __FUNCT__ "DMShellSetGlobalVector"
167fe1899a2SJed Brown /*@
168fe1899a2SJed Brown    DMShellSetGlobalVector - sets a template global vector associated with the DMShell
169fe1899a2SJed Brown 
170fe1899a2SJed Brown    Logically Collective on DM
171fe1899a2SJed Brown 
172fe1899a2SJed Brown    Input Arguments:
173fe1899a2SJed Brown +  dm - shell DM
174fe1899a2SJed Brown -  X - template vector
175fe1899a2SJed Brown 
176fe1899a2SJed Brown    Level: advanced
177fe1899a2SJed Brown 
178fe1899a2SJed Brown .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector()
179fe1899a2SJed Brown @*/
180fe1899a2SJed Brown PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X)
181fe1899a2SJed Brown {
182fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
183fe1899a2SJed Brown   PetscErrorCode ierr;
1848c87107bSJed Brown   PetscBool      isshell;
185fe1899a2SJed Brown 
186fe1899a2SJed Brown   PetscFunctionBegin;
1878c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1888c87107bSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
189251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
1908c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
191fe1899a2SJed Brown   ierr           = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
192fe1899a2SJed Brown   ierr           = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
193fe1899a2SJed Brown   shell->Xglobal = X;
194fe1899a2SJed Brown   PetscFunctionReturn(0);
195fe1899a2SJed Brown }
196fe1899a2SJed Brown 
197fe1899a2SJed Brown #undef __FUNCT__
198fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateGlobalVector"
199fe1899a2SJed Brown /*@C
200fe1899a2SJed Brown    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM
201fe1899a2SJed Brown 
202fe1899a2SJed Brown    Logically Collective
203fe1899a2SJed Brown 
204fe1899a2SJed Brown    Input Arguments:
205fe1899a2SJed Brown +  dm - the shell DM
206fe1899a2SJed Brown -  func - the creation routine
207fe1899a2SJed Brown 
208fe1899a2SJed Brown    Level: advanced
209fe1899a2SJed Brown 
210fe1899a2SJed Brown .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix()
211fe1899a2SJed Brown @*/
212fe1899a2SJed Brown PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
213fe1899a2SJed Brown {
214fe1899a2SJed Brown 
215fe1899a2SJed Brown   PetscFunctionBegin;
216fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
217fe1899a2SJed Brown   dm->ops->createglobalvector = func;
218fe1899a2SJed Brown   PetscFunctionReturn(0);
219fe1899a2SJed Brown }
220fe1899a2SJed Brown 
221fe1899a2SJed Brown #undef __FUNCT__
222dc43b69eSJed Brown #define __FUNCT__ "DMShellSetLocalVector"
223dc43b69eSJed Brown /*@
224dc43b69eSJed Brown    DMShellSetLocalVector - sets a template local vector associated with the DMShell
225dc43b69eSJed Brown 
226dc43b69eSJed Brown    Logically Collective on DM
227dc43b69eSJed Brown 
228dc43b69eSJed Brown    Input Arguments:
229dc43b69eSJed Brown +  dm - shell DM
230dc43b69eSJed Brown -  X - template vector
231dc43b69eSJed Brown 
232dc43b69eSJed Brown    Level: advanced
233dc43b69eSJed Brown 
234dc43b69eSJed Brown .seealso: DMCreateLocalVector(), DMShellSetMatrix(), DMShellSetCreateLocalVector()
235dc43b69eSJed Brown @*/
236dc43b69eSJed Brown PetscErrorCode DMShellSetLocalVector(DM dm,Vec X)
237dc43b69eSJed Brown {
238dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
239dc43b69eSJed Brown   PetscErrorCode ierr;
240dc43b69eSJed Brown   PetscBool      isshell;
241dc43b69eSJed Brown 
242dc43b69eSJed Brown   PetscFunctionBegin;
243dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
244dc43b69eSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
245dc43b69eSJed Brown   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
246dc43b69eSJed Brown   if (!isshell) PetscFunctionReturn(0);
247dc43b69eSJed Brown   ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
248dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
249dc43b69eSJed Brown   shell->Xlocal = X;
250dc43b69eSJed Brown   PetscFunctionReturn(0);
251dc43b69eSJed Brown }
252dc43b69eSJed Brown 
253dc43b69eSJed Brown #undef __FUNCT__
254dc43b69eSJed Brown #define __FUNCT__ "DMShellSetCreateLocalVector"
255dc43b69eSJed Brown /*@C
256dc43b69eSJed Brown    DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM
257dc43b69eSJed Brown 
258dc43b69eSJed Brown    Logically Collective
259dc43b69eSJed Brown 
260dc43b69eSJed Brown    Input Arguments:
261dc43b69eSJed Brown +  dm - the shell DM
262dc43b69eSJed Brown -  func - the creation routine
263dc43b69eSJed Brown 
264dc43b69eSJed Brown    Level: advanced
265dc43b69eSJed Brown 
266dc43b69eSJed Brown .seealso: DMShellSetLocalVector(), DMShellSetCreateMatrix()
267dc43b69eSJed Brown @*/
268dc43b69eSJed Brown PetscErrorCode DMShellSetCreateLocalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
269dc43b69eSJed Brown {
270dc43b69eSJed Brown 
271dc43b69eSJed Brown   PetscFunctionBegin;
272dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
273dc43b69eSJed Brown   dm->ops->createlocalvector = func;
274dc43b69eSJed Brown   PetscFunctionReturn(0);
275dc43b69eSJed Brown }
276dc43b69eSJed Brown 
277dc43b69eSJed Brown #undef __FUNCT__
278*8339e6d0SRichard Tran Mills #define __FUNCT__ "DMShellSetGlobalToLocal"
279*8339e6d0SRichard Tran Mills /*@C
280*8339e6d0SRichard Tran Mills    DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter
281*8339e6d0SRichard Tran Mills 
282*8339e6d0SRichard Tran Mills    Logically Collective on DM
283*8339e6d0SRichard Tran Mills 
284*8339e6d0SRichard Tran Mills    Input Arguments
285*8339e6d0SRichard Tran Mills +  dm - the shell DM
286*8339e6d0SRichard Tran Mills .  begin - the routine that begins the global to local scatter
287*8339e6d0SRichard Tran Mills -  end - the routine that ends the global to local scatter
288*8339e6d0SRichard Tran Mills 
289*8339e6d0SRichard Tran Mills    Level: advanced
290*8339e6d0SRichard Tran Mills 
291*8339e6d0SRichard Tran Mills .seealso: DMShellSetLocalToGlobal()
292*8339e6d0SRichard Tran Mills @*/
293*8339e6d0SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
294*8339e6d0SRichard Tran Mills   PetscFunctionBegin;
295*8339e6d0SRichard Tran Mills   dm->ops->globaltolocalbegin = begin;
296*8339e6d0SRichard Tran Mills   dm->ops->globaltolocalend = end;
297*8339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
298*8339e6d0SRichard Tran Mills }
299*8339e6d0SRichard Tran Mills 
300*8339e6d0SRichard Tran Mills #undef __FUNCT__
301*8339e6d0SRichard Tran Mills #define __FUNCT__ "DMShellSetLocalToGlobal"
302*8339e6d0SRichard Tran Mills /*@C
303*8339e6d0SRichard Tran Mills    DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter
304*8339e6d0SRichard Tran Mills 
305*8339e6d0SRichard Tran Mills    Logically Collective on DM
306*8339e6d0SRichard Tran Mills 
307*8339e6d0SRichard Tran Mills    Input Arguments
308*8339e6d0SRichard Tran Mills +  dm - the shell DM
309*8339e6d0SRichard Tran Mills .  begin - the routine that begins the local to global scatter
310*8339e6d0SRichard Tran Mills -  end - the routine that ends the local to global scatter
311*8339e6d0SRichard Tran Mills 
312*8339e6d0SRichard Tran Mills    Level: advanced
313*8339e6d0SRichard Tran Mills 
314*8339e6d0SRichard Tran Mills .seealso: DMShellSetGlobalToLocal()
315*8339e6d0SRichard Tran Mills @*/
316*8339e6d0SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
317*8339e6d0SRichard Tran Mills   PetscFunctionBegin;
318*8339e6d0SRichard Tran Mills   dm->ops->localtoglobalbegin = begin;
319*8339e6d0SRichard Tran Mills   dm->ops->localtoglobalend = end;
320*8339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
321*8339e6d0SRichard Tran Mills }
322*8339e6d0SRichard Tran Mills 
323*8339e6d0SRichard Tran Mills #undef __FUNCT__
324fe1899a2SJed Brown #define __FUNCT__ "DMDestroy_Shell"
325fe1899a2SJed Brown static PetscErrorCode DMDestroy_Shell(DM dm)
326fe1899a2SJed Brown {
327fe1899a2SJed Brown   PetscErrorCode ierr;
328fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
329fe1899a2SJed Brown 
330fe1899a2SJed Brown   PetscFunctionBegin;
331fe1899a2SJed Brown   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
332fe1899a2SJed Brown   ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
333dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
3347b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
3357b6ad80cSMatthew G Knepley   ierr = PetscFree(shell);CHKERRQ(ierr);
336fe1899a2SJed Brown   PetscFunctionReturn(0);
337fe1899a2SJed Brown }
338fe1899a2SJed Brown 
3392d53ad75SBarry Smith #undef __FUNCT__
3402d53ad75SBarry Smith #define __FUNCT__ "DMView_Shell"
3412d53ad75SBarry Smith static PetscErrorCode DMView_Shell(DM dm,PetscViewer v)
3422d53ad75SBarry Smith {
3432d53ad75SBarry Smith   PetscErrorCode ierr;
3442d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
3452d53ad75SBarry Smith 
3462d53ad75SBarry Smith   PetscFunctionBegin;
3472d53ad75SBarry Smith   ierr = VecView(shell->Xglobal,v);CHKERRQ(ierr);
3482d53ad75SBarry Smith   PetscFunctionReturn(0);
3492d53ad75SBarry Smith }
3502d53ad75SBarry Smith 
3512d53ad75SBarry Smith #undef __FUNCT__
3522d53ad75SBarry Smith #define __FUNCT__ "DMLoad_Shell"
3532d53ad75SBarry Smith static PetscErrorCode DMLoad_Shell(DM dm,PetscViewer v)
3542d53ad75SBarry Smith {
3552d53ad75SBarry Smith   PetscErrorCode ierr;
3562d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
3572d53ad75SBarry Smith 
3582d53ad75SBarry Smith   PetscFunctionBegin;
359ce94432eSBarry Smith   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&shell->Xglobal);CHKERRQ(ierr);
3602d53ad75SBarry Smith   ierr = VecLoad(shell->Xglobal,v);CHKERRQ(ierr);
3612d53ad75SBarry Smith   PetscFunctionReturn(0);
3622d53ad75SBarry Smith }
363fe1899a2SJed Brown 
364fe1899a2SJed Brown #undef __FUNCT__
365fe1899a2SJed Brown #define __FUNCT__ "DMCreate_Shell"
3668c87107bSJed Brown PETSC_EXTERN_C PetscErrorCode  DMCreate_Shell(DM dm)
367fe1899a2SJed Brown {
368fe1899a2SJed Brown   PetscErrorCode ierr;
369fe1899a2SJed Brown   DM_Shell       *shell;
370fe1899a2SJed Brown 
371fe1899a2SJed Brown   PetscFunctionBegin;
3728c87107bSJed Brown   ierr     = PetscNewLog(dm,DM_Shell,&shell);CHKERRQ(ierr);
3738c87107bSJed Brown   dm->data = shell;
374fe1899a2SJed Brown 
3758c87107bSJed Brown   ierr = PetscObjectChangeTypeName((PetscObject)dm,DMSHELL);CHKERRQ(ierr);
3768865f1eaSKarl Rupp 
3778c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
3788c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
379dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
3808c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
3812d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
3822d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
383fe1899a2SJed Brown   PetscFunctionReturn(0);
384fe1899a2SJed Brown }
385fe1899a2SJed Brown 
386fe1899a2SJed Brown #undef __FUNCT__
387fe1899a2SJed Brown #define __FUNCT__ "DMShellCreate"
388fe1899a2SJed Brown /*@
389fe1899a2SJed Brown     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
390fe1899a2SJed Brown 
391fe1899a2SJed Brown     Collective on MPI_Comm
392fe1899a2SJed Brown 
393fe1899a2SJed Brown     Input Parameter:
394fe1899a2SJed Brown .   comm - the processors that will share the global vector
395fe1899a2SJed Brown 
396fe1899a2SJed Brown     Output Parameters:
397fe1899a2SJed Brown .   shell - the shell DM
398fe1899a2SJed Brown 
399fe1899a2SJed Brown     Level: advanced
400fe1899a2SJed Brown 
401dc43b69eSJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateLocalVector()
402fe1899a2SJed Brown @*/
403fe1899a2SJed Brown PetscErrorCode  DMShellCreate(MPI_Comm comm,DM *dm)
404fe1899a2SJed Brown {
405fe1899a2SJed Brown   PetscErrorCode ierr;
406fe1899a2SJed Brown 
407fe1899a2SJed Brown   PetscFunctionBegin;
408fe1899a2SJed Brown   PetscValidPointer(dm,2);
409fe1899a2SJed Brown   ierr = DMCreate(comm,dm);CHKERRQ(ierr);
410fe1899a2SJed Brown   ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr);
411fe1899a2SJed Brown   PetscFunctionReturn(0);
412fe1899a2SJed Brown }
413