xref: /petsc/src/dm/impls/shell/dmshell.c (revision 8865f1ea4ea560cd84ab8db62e98b7095cdff96f)
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);
287bde9f88SJed Brown       ierr = MatCreate(((PetscObject)dm)->comm,&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);
327bde9f88SJed Brown     } else SETERRQ(((PetscObject)dm)->comm,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) {
43ad6bc421SBarry Smith       if (!(aij & (seqaij || mpiaij))) SETERRQ2(((PetscObject)dm)->comm,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;
708c87107bSJed Brown   if (!X) SETERRQ(((PetscObject)dm)->comm,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;
96dc43b69eSJed Brown   if (!X) SETERRQ(((PetscObject)dm)->comm,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__
278fe1899a2SJed Brown #define __FUNCT__ "DMDestroy_Shell"
279fe1899a2SJed Brown static PetscErrorCode DMDestroy_Shell(DM dm)
280fe1899a2SJed Brown {
281fe1899a2SJed Brown   PetscErrorCode ierr;
282fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
283fe1899a2SJed Brown 
284fe1899a2SJed Brown   PetscFunctionBegin;
285fe1899a2SJed Brown   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
286fe1899a2SJed Brown   ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
287dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
2887b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
2897b6ad80cSMatthew G Knepley   ierr = PetscFree(shell);CHKERRQ(ierr);
290fe1899a2SJed Brown   PetscFunctionReturn(0);
291fe1899a2SJed Brown }
292fe1899a2SJed Brown 
2932d53ad75SBarry Smith #undef __FUNCT__
2942d53ad75SBarry Smith #define __FUNCT__ "DMView_Shell"
2952d53ad75SBarry Smith static PetscErrorCode DMView_Shell(DM dm,PetscViewer v)
2962d53ad75SBarry Smith {
2972d53ad75SBarry Smith   PetscErrorCode ierr;
2982d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
2992d53ad75SBarry Smith 
3002d53ad75SBarry Smith   PetscFunctionBegin;
3012d53ad75SBarry Smith   ierr = VecView(shell->Xglobal,v);CHKERRQ(ierr);
3022d53ad75SBarry Smith   PetscFunctionReturn(0);
3032d53ad75SBarry Smith }
3042d53ad75SBarry Smith 
3052d53ad75SBarry Smith #undef __FUNCT__
3062d53ad75SBarry Smith #define __FUNCT__ "DMLoad_Shell"
3072d53ad75SBarry Smith static PetscErrorCode DMLoad_Shell(DM dm,PetscViewer v)
3082d53ad75SBarry Smith {
3092d53ad75SBarry Smith   PetscErrorCode ierr;
3102d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
3112d53ad75SBarry Smith 
3122d53ad75SBarry Smith   PetscFunctionBegin;
3132d53ad75SBarry Smith   ierr = VecCreate(((PetscObject)dm)->comm,&shell->Xglobal);CHKERRQ(ierr);
3142d53ad75SBarry Smith   ierr = VecLoad(shell->Xglobal,v);CHKERRQ(ierr);
3152d53ad75SBarry Smith   PetscFunctionReturn(0);
3162d53ad75SBarry Smith }
317fe1899a2SJed Brown 
318fe1899a2SJed Brown #undef __FUNCT__
319fe1899a2SJed Brown #define __FUNCT__ "DMCreate_Shell"
3208c87107bSJed Brown PETSC_EXTERN_C PetscErrorCode  DMCreate_Shell(DM dm)
321fe1899a2SJed Brown {
322fe1899a2SJed Brown   PetscErrorCode ierr;
323fe1899a2SJed Brown   DM_Shell       *shell;
324fe1899a2SJed Brown 
325fe1899a2SJed Brown   PetscFunctionBegin;
3268c87107bSJed Brown   ierr     = PetscNewLog(dm,DM_Shell,&shell);CHKERRQ(ierr);
3278c87107bSJed Brown   dm->data = shell;
328fe1899a2SJed Brown 
3298c87107bSJed Brown   ierr = PetscObjectChangeTypeName((PetscObject)dm,DMSHELL);CHKERRQ(ierr);
330*8865f1eaSKarl Rupp 
3318c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
3328c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
333dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
3348c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
3352d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
3362d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
337fe1899a2SJed Brown   PetscFunctionReturn(0);
338fe1899a2SJed Brown }
339fe1899a2SJed Brown 
340fe1899a2SJed Brown #undef __FUNCT__
341fe1899a2SJed Brown #define __FUNCT__ "DMShellCreate"
342fe1899a2SJed Brown /*@
343fe1899a2SJed Brown     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
344fe1899a2SJed Brown 
345fe1899a2SJed Brown     Collective on MPI_Comm
346fe1899a2SJed Brown 
347fe1899a2SJed Brown     Input Parameter:
348fe1899a2SJed Brown .   comm - the processors that will share the global vector
349fe1899a2SJed Brown 
350fe1899a2SJed Brown     Output Parameters:
351fe1899a2SJed Brown .   shell - the shell DM
352fe1899a2SJed Brown 
353fe1899a2SJed Brown     Level: advanced
354fe1899a2SJed Brown 
355dc43b69eSJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateLocalVector()
356fe1899a2SJed Brown @*/
357fe1899a2SJed Brown PetscErrorCode  DMShellCreate(MPI_Comm comm,DM *dm)
358fe1899a2SJed Brown {
359fe1899a2SJed Brown   PetscErrorCode ierr;
360fe1899a2SJed Brown 
361fe1899a2SJed Brown   PetscFunctionBegin;
362fe1899a2SJed Brown   PetscValidPointer(dm,2);
363fe1899a2SJed Brown   ierr = DMCreate(comm,dm);CHKERRQ(ierr);
364fe1899a2SJed Brown   ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr);
365fe1899a2SJed Brown   PetscFunctionReturn(0);
366fe1899a2SJed Brown }
367