xref: /petsc/src/dm/impls/shell/dmshell.c (revision f089877a000c0949609bd4a1bfd01a0aa8158bb4)
1 #include <petscdmshell.h>       /*I    "petscdmshell.h"  I*/
2 #include <petscmat.h>
3 #include <petsc-private/dmimpl.h>
4 
5 typedef struct  {
6   Vec        Xglobal;
7   Vec        Xlocal;
8   Mat        A;
9   VecScatter gtol;
10   VecScatter ltog;
11   VecScatter ltol;
12 } DM_Shell;
13 
14 #undef __FUNCT__
15 #define __FUNCT__ "DMGlobalToLocalBeginDefaultShell"
16 /*@
17    DMGlobalToLocalBeginDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to begin a global to local scatter
18    Collective
19 
20    Input Arguments:
21 +  dm - shell DM
22 .  g - global vector
23 .  mode - InsertMode
24 -  l - local vector
25 
26    Level: advanced
27 
28    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.
29 
30 .seealso: DMGlobalToLocalEndDefaultShell()
31 @*/
32 PetscErrorCode DMGlobalToLocalBeginDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
33 {
34   PetscErrorCode ierr;
35   DM_Shell       *shell = (DM_Shell*)dm->data;
36 
37   PetscFunctionBegin;
38   if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
39   ierr = VecScatterBegin(shell->gtol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
40   PetscFunctionReturn(0);
41 }
42 
43 #undef __FUNCT__
44 #define __FUNCT__ "DMGlobalToLocalEndDefaultShell"
45 /*@
46    DMGlobalToLocalEndDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to end a global to local scatter
47    Collective
48 
49    Input Arguments:
50 +  dm - shell DM
51 .  g - global vector
52 .  mode - InsertMode
53 -  l - local vector
54 
55    Level: advanced
56 
57 .seealso: DMGlobalToLocalBeginDefaultShell()
58 @*/
59 PetscErrorCode DMGlobalToLocalEndDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
60 {
61   PetscErrorCode ierr;
62   DM_Shell       *shell = (DM_Shell*)dm->data;
63 
64   PetscFunctionBegin;
65    if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
66   ierr = VecScatterEnd(shell->gtol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
67   PetscFunctionReturn(0);
68 }
69 
70 #undef __FUNCT__
71 #define __FUNCT__ "DMLocalToGlobalBeginDefaultShell"
72 /*@
73    DMLocalToGlobalBeginDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to begin a local to global scatter
74    Collective
75 
76    Input Arguments:
77 +  dm - shell DM
78 .  l - local vector
79 .  mode - InsertMode
80 -  g - global vector
81 
82    Level: advanced
83 
84    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.
85 
86 .seealso: DMLocalToGlobalEndDefaultShell()
87 @*/
88 PetscErrorCode DMLocalToGlobalBeginDefaultShell(DM dm,Vec l,InsertMode mode,Vec g)
89 {
90   PetscErrorCode ierr;
91   DM_Shell       *shell = (DM_Shell*)dm->data;
92 
93   PetscFunctionBegin;
94   if (!shell->ltog) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
95   ierr = VecScatterBegin(shell->ltog,l,g,mode,SCATTER_FORWARD);CHKERRQ(ierr);
96   PetscFunctionReturn(0);
97 }
98 
99 #undef __FUNCT__
100 #define __FUNCT__ "DMLocalToGlobalEndDefaultShell"
101 /*@
102    DMLocalToGlobalEndDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to end a local to global scatter
103    Collective
104 
105    Input Arguments:
106 +  dm - shell DM
107 .  l - local vector
108 .  mode - InsertMode
109 -  g - global vector
110 
111    Level: advanced
112 
113 .seealso: DMLocalToGlobalBeginDefaultShell()
114 @*/
115 PetscErrorCode DMLocalToGlobalEndDefaultShell(DM dm,Vec l,InsertMode mode,Vec g)
116 {
117   PetscErrorCode ierr;
118   DM_Shell       *shell = (DM_Shell*)dm->data;
119 
120   PetscFunctionBegin;
121    if (!shell->ltog) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
122   ierr = VecScatterEnd(shell->ltog,l,g,mode,SCATTER_FORWARD);CHKERRQ(ierr);
123   PetscFunctionReturn(0);
124 }
125 
126 
127 #undef __FUNCT__
128 #define __FUNCT__ "DMCreateMatrix_Shell"
129 static PetscErrorCode DMCreateMatrix_Shell(DM dm,MatType mtype,Mat *J)
130 {
131   PetscErrorCode ierr;
132   DM_Shell       *shell = (DM_Shell*)dm->data;
133   Mat            A;
134 
135   PetscFunctionBegin;
136   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
137   PetscValidPointer(J,3);
138   if (!shell->A) {
139     if (shell->Xglobal) {
140       PetscInt m,M;
141       ierr = PetscInfo(dm,"Naively creating matrix using global vector distribution without preallocation");CHKERRQ(ierr);
142       ierr = VecGetSize(shell->Xglobal,&M);CHKERRQ(ierr);
143       ierr = VecGetLocalSize(shell->Xglobal,&m);CHKERRQ(ierr);
144       ierr = MatCreate(PetscObjectComm((PetscObject)dm),&shell->A);CHKERRQ(ierr);
145       ierr = MatSetSizes(shell->A,m,m,M,M);CHKERRQ(ierr);
146       if (mtype) {ierr = MatSetType(shell->A,mtype);CHKERRQ(ierr);}
147       ierr = MatSetUp(shell->A);CHKERRQ(ierr);
148     } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector");
149   }
150   A = shell->A;
151   /* the check below is tacky and incomplete */
152   if (mtype) {
153     PetscBool flg,aij,seqaij,mpiaij;
154     ierr = PetscObjectTypeCompare((PetscObject)A,mtype,&flg);CHKERRQ(ierr);
155     ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
156     ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&mpiaij);CHKERRQ(ierr);
157     ierr = PetscStrcmp(mtype,MATAIJ,&aij);CHKERRQ(ierr);
158     if (!flg) {
159       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);
160     }
161   }
162   if (((PetscObject)A)->refct < 2) { /* We have an exclusive reference so we can give it out */
163     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
164     ierr = MatZeroEntries(A);CHKERRQ(ierr);
165     *J   = A;
166   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
167     ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,J);CHKERRQ(ierr);
168     ierr = MatZeroEntries(*J);CHKERRQ(ierr);
169   }
170   PetscFunctionReturn(0);
171 }
172 
173 #undef __FUNCT__
174 #define __FUNCT__ "DMCreateGlobalVector_Shell"
175 PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec)
176 {
177   PetscErrorCode ierr;
178   DM_Shell       *shell = (DM_Shell*)dm->data;
179   Vec            X;
180 
181   PetscFunctionBegin;
182   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
183   PetscValidPointer(gvec,2);
184   *gvec = 0;
185   X     = shell->Xglobal;
186   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
187   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
188     ierr  = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
189     ierr  = VecZeroEntries(X);CHKERRQ(ierr);
190     *gvec = X;
191   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
192     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
193     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
194   }
195   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
196   PetscFunctionReturn(0);
197 }
198 
199 #undef __FUNCT__
200 #define __FUNCT__ "DMCreateLocalVector_Shell"
201 PetscErrorCode DMCreateLocalVector_Shell(DM dm,Vec *gvec)
202 {
203   PetscErrorCode ierr;
204   DM_Shell       *shell = (DM_Shell*)dm->data;
205   Vec            X;
206 
207   PetscFunctionBegin;
208   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
209   PetscValidPointer(gvec,2);
210   *gvec = 0;
211   X     = shell->Xlocal;
212   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()");
213   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
214     ierr  = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
215     ierr  = VecZeroEntries(X);CHKERRQ(ierr);
216     *gvec = X;
217   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
218     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
219     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
220   }
221   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
222   PetscFunctionReturn(0);
223 }
224 
225 #undef __FUNCT__
226 #define __FUNCT__ "DMShellSetMatrix"
227 /*@
228    DMShellSetMatrix - sets a template matrix associated with the DMShell
229 
230    Collective
231 
232    Input Arguments:
233 +  dm - shell DM
234 -  J - template matrix
235 
236    Level: advanced
237 
238 .seealso: DMCreateMatrix(), DMShellSetCreateMatrix()
239 @*/
240 PetscErrorCode DMShellSetMatrix(DM dm,Mat J)
241 {
242   DM_Shell       *shell = (DM_Shell*)dm->data;
243   PetscErrorCode ierr;
244   PetscBool      isshell;
245 
246   PetscFunctionBegin;
247   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
248   PetscValidHeaderSpecific(J,MAT_CLASSID,2);
249   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
250   if (!isshell) PetscFunctionReturn(0);
251   ierr     = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
252   ierr     = MatDestroy(&shell->A);CHKERRQ(ierr);
253   shell->A = J;
254   PetscFunctionReturn(0);
255 }
256 
257 #undef __FUNCT__
258 #define __FUNCT__ "DMShellSetCreateMatrix"
259 /*@C
260    DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM
261 
262    Logically Collective on DM
263 
264    Input Arguments:
265 +  dm - the shell DM
266 -  func - the function to create a matrix
267 
268    Level: advanced
269 
270 .seealso: DMCreateMatrix(), DMShellSetMatrix()
271 @*/
272 PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,MatType,Mat*))
273 {
274 
275   PetscFunctionBegin;
276   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
277   dm->ops->creatematrix = func;
278   PetscFunctionReturn(0);
279 }
280 
281 #undef __FUNCT__
282 #define __FUNCT__ "DMShellSetGlobalVector"
283 /*@
284    DMShellSetGlobalVector - sets a template global vector associated with the DMShell
285 
286    Logically Collective on DM
287 
288    Input Arguments:
289 +  dm - shell DM
290 -  X - template vector
291 
292    Level: advanced
293 
294 .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector()
295 @*/
296 PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X)
297 {
298   DM_Shell       *shell = (DM_Shell*)dm->data;
299   PetscErrorCode ierr;
300   PetscBool      isshell;
301 
302   PetscFunctionBegin;
303   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
304   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
305   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
306   if (!isshell) PetscFunctionReturn(0);
307   ierr           = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
308   ierr           = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
309   shell->Xglobal = X;
310   PetscFunctionReturn(0);
311 }
312 
313 #undef __FUNCT__
314 #define __FUNCT__ "DMShellSetCreateGlobalVector"
315 /*@C
316    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM
317 
318    Logically Collective
319 
320    Input Arguments:
321 +  dm - the shell DM
322 -  func - the creation routine
323 
324    Level: advanced
325 
326 .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix()
327 @*/
328 PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
329 {
330 
331   PetscFunctionBegin;
332   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
333   dm->ops->createglobalvector = func;
334   PetscFunctionReturn(0);
335 }
336 
337 #undef __FUNCT__
338 #define __FUNCT__ "DMShellSetLocalVector"
339 /*@
340    DMShellSetLocalVector - sets a template local vector associated with the DMShell
341 
342    Logically Collective on DM
343 
344    Input Arguments:
345 +  dm - shell DM
346 -  X - template vector
347 
348    Level: advanced
349 
350 .seealso: DMCreateLocalVector(), DMShellSetMatrix(), DMShellSetCreateLocalVector()
351 @*/
352 PetscErrorCode DMShellSetLocalVector(DM dm,Vec X)
353 {
354   DM_Shell       *shell = (DM_Shell*)dm->data;
355   PetscErrorCode ierr;
356   PetscBool      isshell;
357 
358   PetscFunctionBegin;
359   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
360   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
361   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
362   if (!isshell) PetscFunctionReturn(0);
363   ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
364   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
365   shell->Xlocal = X;
366   PetscFunctionReturn(0);
367 }
368 
369 #undef __FUNCT__
370 #define __FUNCT__ "DMShellSetCreateLocalVector"
371 /*@C
372    DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM
373 
374    Logically Collective
375 
376    Input Arguments:
377 +  dm - the shell DM
378 -  func - the creation routine
379 
380    Level: advanced
381 
382 .seealso: DMShellSetLocalVector(), DMShellSetCreateMatrix()
383 @*/
384 PetscErrorCode DMShellSetCreateLocalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
385 {
386 
387   PetscFunctionBegin;
388   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
389   dm->ops->createlocalvector = func;
390   PetscFunctionReturn(0);
391 }
392 
393 #undef __FUNCT__
394 #define __FUNCT__ "DMShellSetGlobalToLocal"
395 /*@C
396    DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter
397 
398    Logically Collective on DM
399 
400    Input Arguments
401 +  dm - the shell DM
402 .  begin - the routine that begins the global to local scatter
403 -  end - the routine that ends the global to local scatter
404 
405    Notes: If these functions are not provided but DMShellSetGlobalToLocalVecScatter() is called then
406    DMGlobalToLocalBeginDefaultShell() are used to to perform the transfers DMGlobalToLocalEndDefaultShell()
407 
408    Level: advanced
409 
410 .seealso: DMShellSetLocalToGlobal(), DMGlobalToLocalBeginDefaultShell(), DMGlobalToLocalEndDefaultShell()
411 @*/
412 PetscErrorCode DMShellSetGlobalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
413   PetscFunctionBegin;
414   dm->ops->globaltolocalbegin = begin;
415   dm->ops->globaltolocalend = end;
416   PetscFunctionReturn(0);
417 }
418 
419 #undef __FUNCT__
420 #define __FUNCT__ "DMShellSetLocalToGlobal"
421 /*@C
422    DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter
423 
424    Logically Collective on DM
425 
426    Input Arguments
427 +  dm - the shell DM
428 .  begin - the routine that begins the local to global scatter
429 -  end - the routine that ends the local to global scatter
430 
431    Level: advanced
432 
433 .seealso: DMShellSetGlobalToLocal()
434 @*/
435 PetscErrorCode DMShellSetLocalToGlobal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
436   PetscFunctionBegin;
437   dm->ops->localtoglobalbegin = begin;
438   dm->ops->localtoglobalend = end;
439   PetscFunctionReturn(0);
440 }
441 
442 #undef __FUNCT__
443 #define __FUNCT__ "DMShellSetGlobalToLocalVecScatter"
444 /*@
445    DMShellSetGlobalToLocalVecScatter - Sets a VecScatter context for global to local communication
446 
447    Logically Collective on DM
448 
449    Input Arguments
450 +  dm - the shell DM
451 -  gtol - the global to local VecScatter context
452 
453    Level: advanced
454 
455 .seealso: DMShellSetGlobalToLocal()
456 @*/
457 PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter gtol)
458 {
459   DM_Shell       *shell = (DM_Shell*)dm->data;
460   PetscErrorCode ierr;
461 
462   PetscFunctionBegin;
463   ierr = PetscObjectReference((PetscObject)gtol);CHKERRQ(ierr);
464   /* Call VecScatterDestroy() to avoid a memory leak in case of re-setting. */
465   ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr);
466   shell->gtol = gtol;
467   PetscFunctionReturn(0);
468 }
469 
470 #undef __FUNCT__
471 #define __FUNCT__ "DMShellSetLocalToGlobalVecScatter"
472 /*@
473    DMShellSetLocalToGlobalVecScatter - Sets a VecScatter context for local to global communication
474 
475    Logically Collective on DM
476 
477    Input Arguments
478 +  dm - the shell DM
479 -  ltog - the local to global VecScatter context
480 
481    Level: advanced
482 
483 .seealso: DMShellSetLocalToGlobal()
484 @*/
485 PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM dm, VecScatter ltog)
486 {
487   DM_Shell       *shell = (DM_Shell*)dm->data;
488   PetscErrorCode ierr;
489 
490   PetscFunctionBegin;
491   ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr);
492   /* Call VecScatterDestroy() to avoid a memory leak in case of re-setting. */
493   ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr);
494   shell->ltog = ltog;
495   PetscFunctionReturn(0);
496 }
497 
498 #undef __FUNCT__
499 #define __FUNCT__ "DMDestroy_Shell"
500 static PetscErrorCode DMDestroy_Shell(DM dm)
501 {
502   PetscErrorCode ierr;
503   DM_Shell       *shell = (DM_Shell*)dm->data;
504 
505   PetscFunctionBegin;
506   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
507   ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
508   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
509   ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr);
510   ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr);
511   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
512   ierr = PetscFree(shell);CHKERRQ(ierr);
513   PetscFunctionReturn(0);
514 }
515 
516 #undef __FUNCT__
517 #define __FUNCT__ "DMView_Shell"
518 static PetscErrorCode DMView_Shell(DM dm,PetscViewer v)
519 {
520   PetscErrorCode ierr;
521   DM_Shell       *shell = (DM_Shell*)dm->data;
522 
523   PetscFunctionBegin;
524   ierr = VecView(shell->Xglobal,v);CHKERRQ(ierr);
525   PetscFunctionReturn(0);
526 }
527 
528 #undef __FUNCT__
529 #define __FUNCT__ "DMLoad_Shell"
530 static PetscErrorCode DMLoad_Shell(DM dm,PetscViewer v)
531 {
532   PetscErrorCode ierr;
533   DM_Shell       *shell = (DM_Shell*)dm->data;
534 
535   PetscFunctionBegin;
536   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&shell->Xglobal);CHKERRQ(ierr);
537   ierr = VecLoad(shell->Xglobal,v);CHKERRQ(ierr);
538   PetscFunctionReturn(0);
539 }
540 
541 #undef __FUNCT__
542 #define __FUNCT__ "DMCreate_Shell"
543 PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm)
544 {
545   PetscErrorCode ierr;
546   DM_Shell       *shell;
547 
548   PetscFunctionBegin;
549   ierr     = PetscNewLog(dm,DM_Shell,&shell);CHKERRQ(ierr);
550   dm->data = shell;
551 
552   ierr = PetscObjectChangeTypeName((PetscObject)dm,DMSHELL);CHKERRQ(ierr);
553 
554   dm->ops->destroy            = DMDestroy_Shell;
555   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
556   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
557   dm->ops->creatematrix       = DMCreateMatrix_Shell;
558   dm->ops->view               = DMView_Shell;
559   dm->ops->load               = DMLoad_Shell;
560   dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell;
561   dm->ops->globaltolocalend   = DMGlobalToLocalEndDefaultShell;
562   dm->ops->localtoglobalbegin = DMLocalToGlobalBeginDefaultShell;
563   dm->ops->localtoglobalend   = DMLocalToGlobalEndDefaultShell;
564   PetscFunctionReturn(0);
565 }
566 
567 #undef __FUNCT__
568 #define __FUNCT__ "DMShellCreate"
569 /*@
570     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
571 
572     Collective on MPI_Comm
573 
574     Input Parameter:
575 .   comm - the processors that will share the global vector
576 
577     Output Parameters:
578 .   shell - the shell DM
579 
580     Level: advanced
581 
582 .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateLocalVector()
583 @*/
584 PetscErrorCode  DMShellCreate(MPI_Comm comm,DM *dm)
585 {
586   PetscErrorCode ierr;
587 
588   PetscFunctionBegin;
589   PetscValidPointer(dm,2);
590   ierr = DMCreate(comm,dm);CHKERRQ(ierr);
591   ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr);
592   PetscFunctionReturn(0);
593 }
594 
595