xref: /petsc/src/dm/interface/dm.c (revision 08da532b2310464c3bf489aef60f0ccd6d61141d)
1 #include <petscsnes.h>
2 #include <private/dmimpl.h>     /*I      "petscdm.h"     I*/
3 
4 PetscClassId  DM_CLASSID;
5 PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal;
6 
7 #undef __FUNCT__
8 #define __FUNCT__ "DMCreate"
9 /*@
10   DMCreate - Creates an empty DM object. The type can then be set with DMSetType().
11 
12    If you never  call DMSetType()  it will generate an
13    error when you try to use the vector.
14 
15   Collective on MPI_Comm
16 
17   Input Parameter:
18 . comm - The communicator for the DM object
19 
20   Output Parameter:
21 . dm - The DM object
22 
23   Level: beginner
24 
25 .seealso: DMSetType(), DMDA, DMSLICED, DMCOMPOSITE
26 @*/
27 PetscErrorCode  DMCreate(MPI_Comm comm,DM *dm)
28 {
29   DM             v;
30   PetscErrorCode ierr;
31 
32   PetscFunctionBegin;
33   PetscValidPointer(dm,2);
34   *dm = PETSC_NULL;
35 #ifndef PETSC_USE_DYNAMIC_LIBRARIES
36   ierr = VecInitializePackage(PETSC_NULL);CHKERRQ(ierr);
37   ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr);
38   ierr = DMInitializePackage(PETSC_NULL);CHKERRQ(ierr);
39 #endif
40 
41   ierr = PetscHeaderCreate(v, _p_DM, struct _DMOps, DM_CLASSID, -1, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView);CHKERRQ(ierr);
42   ierr = PetscMemzero(v->ops, sizeof(struct _DMOps));CHKERRQ(ierr);
43 
44   v->workSize     = 0;
45   v->workArray    = PETSC_NULL;
46   v->ltogmap      = PETSC_NULL;
47   v->ltogmapb     = PETSC_NULL;
48   v->bs           = 1;
49   v->coloringtype = IS_COLORING_GLOBAL;
50 
51   *dm = v;
52   PetscFunctionReturn(0);
53 }
54 
55 
56 #undef __FUNCT__
57 #define __FUNCT__ "DMSetVecType"
58 /*@C
59        DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector()
60 
61    Logically Collective on DMDA
62 
63    Input Parameter:
64 +  da - initial distributed array
65 .  ctype - the vector type, currently either VECSTANDARD or VECCUSP
66 
67    Options Database:
68 .   -dm_vec_type ctype
69 
70    Level: intermediate
71 
72 .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDA, DMDAInterpolationType, VecType
73 @*/
74 PetscErrorCode  DMSetVecType(DM da,const VecType ctype)
75 {
76   PetscErrorCode ierr;
77 
78   PetscFunctionBegin;
79   PetscValidHeaderSpecific(da,DM_CLASSID,1);
80   ierr = PetscFree(da->vectype);CHKERRQ(ierr);
81   ierr = PetscStrallocpy(ctype,&da->vectype);CHKERRQ(ierr);
82   PetscFunctionReturn(0);
83 }
84 
85 #undef __FUNCT__
86 #define __FUNCT__ "DMSetOptionsPrefix"
87 /*@C
88    DMSetOptionsPrefix - Sets the prefix used for searching for all
89    DMDA options in the database.
90 
91    Logically Collective on DMDA
92 
93    Input Parameter:
94 +  da - the DMDA context
95 -  prefix - the prefix to prepend to all option names
96 
97    Notes:
98    A hyphen (-) must NOT be given at the beginning of the prefix name.
99    The first character of all runtime options is AUTOMATICALLY the hyphen.
100 
101    Level: advanced
102 
103 .keywords: DMDA, set, options, prefix, database
104 
105 .seealso: DMSetFromOptions()
106 @*/
107 PetscErrorCode  DMSetOptionsPrefix(DM dm,const char prefix[])
108 {
109   PetscErrorCode ierr;
110 
111   PetscFunctionBegin;
112   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
113   ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
114   PetscFunctionReturn(0);
115 }
116 
117 #undef __FUNCT__
118 #define __FUNCT__ "DMDestroy"
119 /*@
120     DMDestroy - Destroys a vector packer or DMDA.
121 
122     Collective on DM
123 
124     Input Parameter:
125 .   dm - the DM object to destroy
126 
127     Level: developer
128 
129 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
130 
131 @*/
132 PetscErrorCode  DMDestroy(DM *dm)
133 {
134   PetscInt       i, cnt = 0;
135   DMCoarsenHookLink link,next;
136   PetscErrorCode ierr;
137 
138   PetscFunctionBegin;
139   if (!*dm) PetscFunctionReturn(0);
140   PetscValidHeaderSpecific((*dm),DM_CLASSID,1);
141 
142   /* count all the circular references of DM and its contained Vecs */
143   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
144     if ((*dm)->localin[i])  {cnt++;}
145     if ((*dm)->globalin[i]) {cnt++;}
146   }
147   if ((*dm)->x) {
148     PetscObject obj;
149     ierr = PetscObjectQuery((PetscObject)(*dm)->x,"DM",&obj);CHKERRQ(ierr);
150     if (obj == (PetscObject)*dm) cnt++;
151   }
152 
153   if (--((PetscObject)(*dm))->refct - cnt > 0) {*dm = 0; PetscFunctionReturn(0);}
154   /*
155      Need this test because the dm references the vectors that
156      reference the dm, so destroying the dm calls destroy on the
157      vectors that cause another destroy on the dm
158   */
159   if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0);
160   ((PetscObject) (*dm))->refct = 0;
161   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
162     if ((*dm)->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Destroying a DM that has a local vector obtained with DMGetLocalVector()");
163     ierr = VecDestroy(&(*dm)->localin[i]);CHKERRQ(ierr);
164   }
165 
166   /* Destroy the list of hooks */
167   for (link=(*dm)->coarsenhook; link; link=next) {
168     next = link->next;
169     ierr = PetscFree(link);CHKERRQ(ierr);
170   }
171   (*dm)->coarsenhook = PETSC_NULL;
172 
173   if ((*dm)->ctx && (*dm)->ctxdestroy) {
174     ierr = (*(*dm)->ctxdestroy)(&(*dm)->ctx);CHKERRQ(ierr);
175   }
176   ierr = VecDestroy(&(*dm)->x);CHKERRQ(ierr);
177   ierr = MatFDColoringDestroy(&(*dm)->fd);CHKERRQ(ierr);
178   ierr = DMClearGlobalVectors(*dm);CHKERRQ(ierr);
179   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);CHKERRQ(ierr);
180   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmapb);CHKERRQ(ierr);
181   ierr = PetscFree((*dm)->vectype);CHKERRQ(ierr);
182   ierr = PetscFree((*dm)->mattype);CHKERRQ(ierr);
183   ierr = PetscFree((*dm)->workArray);CHKERRQ(ierr);
184   /* if memory was published with AMS then destroy it */
185   ierr = PetscObjectDepublish(*dm);CHKERRQ(ierr);
186 
187   ierr = (*(*dm)->ops->destroy)(*dm);CHKERRQ(ierr);
188   ierr = PetscFree((*dm)->data);CHKERRQ(ierr);
189   ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr);
190   PetscFunctionReturn(0);
191 }
192 
193 #undef __FUNCT__
194 #define __FUNCT__ "DMSetUp"
195 /*@
196     DMSetUp - sets up the data structures inside a DM object
197 
198     Collective on DM
199 
200     Input Parameter:
201 .   dm - the DM object to setup
202 
203     Level: developer
204 
205 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
206 
207 @*/
208 PetscErrorCode  DMSetUp(DM dm)
209 {
210   PetscErrorCode ierr;
211 
212   PetscFunctionBegin;
213   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
214   if (dm->setupcalled) PetscFunctionReturn(0);
215   if (dm->ops->setup) {
216     ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr);
217   }
218   dm->setupcalled = PETSC_TRUE;
219   PetscFunctionReturn(0);
220 }
221 
222 #undef __FUNCT__
223 #define __FUNCT__ "DMSetFromOptions"
224 /*@
225     DMSetFromOptions - sets parameters in a DM from the options database
226 
227     Collective on DM
228 
229     Input Parameter:
230 .   dm - the DM object to set options for
231 
232     Options Database:
233 +   -dm_preallocate_only: Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros
234 .   -dm_vec_type <type>  type of vector to create inside DM
235 .   -dm_mat_type <type>  type of matrix to create inside DM
236 -   -dm_coloring_type <global or ghosted>
237 
238     Level: developer
239 
240 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
241 
242 @*/
243 PetscErrorCode  DMSetFromOptions(DM dm)
244 {
245   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg;
246   PetscErrorCode ierr;
247   char           typeName[256] = MATAIJ;
248 
249   PetscFunctionBegin;
250   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
251   ierr = PetscObjectOptionsBegin((PetscObject)dm);CHKERRQ(ierr);
252     ierr = PetscOptionsBool("-dm_view", "Information on DM", "DMView", flg1, &flg1, PETSC_NULL);CHKERRQ(ierr);
253     ierr = PetscOptionsBool("-dm_view_detail", "Exhaustive mesh description", "DMView", flg2, &flg2, PETSC_NULL);CHKERRQ(ierr);
254     ierr = PetscOptionsBool("-dm_view_vtk", "Output mesh in VTK format", "DMView", flg3, &flg3, PETSC_NULL);CHKERRQ(ierr);
255     ierr = PetscOptionsBool("-dm_view_latex", "Output mesh in LaTeX TikZ format", "DMView", flg4, &flg4, PETSC_NULL);CHKERRQ(ierr);
256     ierr = PetscOptionsBool("-dm_preallocate_only","only preallocate matrix, but do not set column indices","DMSetMatrixPreallocateOnly",dm->prealloc_only,&dm->prealloc_only,PETSC_NULL);CHKERRQ(ierr);
257     ierr = PetscOptionsList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg);CHKERRQ(ierr);
258     if (flg) {
259       ierr = DMSetVecType(dm,typeName);CHKERRQ(ierr);
260     }
261     ierr = PetscOptionsList("-dm_mat_type","Matrix type","MatSetType",MatList,typeName,typeName,sizeof typeName,&flg);CHKERRQ(ierr);
262     if (flg) {
263       ierr = PetscFree(dm->mattype);CHKERRQ(ierr);
264       ierr = PetscStrallocpy(typeName,&dm->mattype);CHKERRQ(ierr);
265     }
266     ierr = PetscOptionsEnum("-dm_is_coloring_type","Global or local coloring of Jacobian","ISColoringType",ISColoringTypes,(PetscEnum)dm->coloringtype,(PetscEnum*)&dm->coloringtype,PETSC_NULL);CHKERRQ(ierr);
267     if (dm->ops->setfromoptions) {
268       ierr = (*dm->ops->setfromoptions)(dm);CHKERRQ(ierr);
269     }
270     /* process any options handlers added with PetscObjectAddOptionsHandler() */
271     ierr = PetscObjectProcessOptionsHandlers((PetscObject) dm);CHKERRQ(ierr);
272   ierr = PetscOptionsEnd();CHKERRQ(ierr);
273   if (flg1) {
274     ierr = DMView(dm, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
275   }
276   if (flg2) {
277     PetscViewer viewer;
278 
279     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
280     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
281     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
282     ierr = DMView(dm, viewer);CHKERRQ(ierr);
283     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
284   }
285   if (flg3) {
286     PetscViewer viewer;
287 
288     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
289     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
290     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_VTK);CHKERRQ(ierr);
291     ierr = PetscViewerFileSetName(viewer, "mesh.vtk");CHKERRQ(ierr);
292     ierr = DMView(dm, viewer);CHKERRQ(ierr);
293     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
294   }
295   if (flg4) {
296     PetscViewer viewer;
297 
298     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
299     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
300     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_LATEX);CHKERRQ(ierr);
301     ierr = PetscViewerFileSetName(viewer, "mesh.tex");CHKERRQ(ierr);
302     ierr = DMView(dm, viewer);CHKERRQ(ierr);
303     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
304   }
305   PetscFunctionReturn(0);
306 }
307 
308 #undef __FUNCT__
309 #define __FUNCT__ "DMView"
310 /*@C
311     DMView - Views a vector packer or DMDA.
312 
313     Collective on DM
314 
315     Input Parameter:
316 +   dm - the DM object to view
317 -   v - the viewer
318 
319     Level: developer
320 
321 .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
322 
323 @*/
324 PetscErrorCode  DMView(DM dm,PetscViewer v)
325 {
326   PetscErrorCode ierr;
327 
328   PetscFunctionBegin;
329   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
330  if (!v) {
331     ierr = PetscViewerASCIIGetStdout(((PetscObject)dm)->comm,&v);CHKERRQ(ierr);
332   }
333   if (dm->ops->view) {
334     ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr);
335   }
336   PetscFunctionReturn(0);
337 }
338 
339 #undef __FUNCT__
340 #define __FUNCT__ "DMCreateGlobalVector"
341 /*@
342     DMCreateGlobalVector - Creates a global vector from a DMDA or DMComposite object
343 
344     Collective on DM
345 
346     Input Parameter:
347 .   dm - the DM object
348 
349     Output Parameter:
350 .   vec - the global vector
351 
352     Level: beginner
353 
354 .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
355 
356 @*/
357 PetscErrorCode  DMCreateGlobalVector(DM dm,Vec *vec)
358 {
359   PetscErrorCode ierr;
360 
361   PetscFunctionBegin;
362   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
363   ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr);
364   PetscFunctionReturn(0);
365 }
366 
367 #undef __FUNCT__
368 #define __FUNCT__ "DMCreateLocalVector"
369 /*@
370     DMCreateLocalVector - Creates a local vector from a DMDA or DMComposite object
371 
372     Not Collective
373 
374     Input Parameter:
375 .   dm - the DM object
376 
377     Output Parameter:
378 .   vec - the local vector
379 
380     Level: beginner
381 
382 .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
383 
384 @*/
385 PetscErrorCode  DMCreateLocalVector(DM dm,Vec *vec)
386 {
387   PetscErrorCode ierr;
388 
389   PetscFunctionBegin;
390   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
391   ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr);
392   PetscFunctionReturn(0);
393 }
394 
395 #undef __FUNCT__
396 #define __FUNCT__ "DMGetLocalToGlobalMapping"
397 /*@
398    DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM.
399 
400    Collective on DM
401 
402    Input Parameter:
403 .  dm - the DM that provides the mapping
404 
405    Output Parameter:
406 .  ltog - the mapping
407 
408    Level: intermediate
409 
410    Notes:
411    This mapping can then be used by VecSetLocalToGlobalMapping() or
412    MatSetLocalToGlobalMapping().
413 
414 .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMappingBlock()
415 @*/
416 PetscErrorCode  DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog)
417 {
418   PetscErrorCode ierr;
419 
420   PetscFunctionBegin;
421   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
422   PetscValidPointer(ltog,2);
423   if (!dm->ltogmap) {
424     if (!dm->ops->createlocaltoglobalmapping) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMapping");
425     ierr = (*dm->ops->createlocaltoglobalmapping)(dm);CHKERRQ(ierr);
426   }
427   *ltog = dm->ltogmap;
428   PetscFunctionReturn(0);
429 }
430 
431 #undef __FUNCT__
432 #define __FUNCT__ "DMGetLocalToGlobalMappingBlock"
433 /*@
434    DMGetLocalToGlobalMappingBlock - Accesses the blocked local-to-global mapping in a DM.
435 
436    Collective on DM
437 
438    Input Parameter:
439 .  da - the distributed array that provides the mapping
440 
441    Output Parameter:
442 .  ltog - the block mapping
443 
444    Level: intermediate
445 
446    Notes:
447    This mapping can then be used by VecSetLocalToGlobalMappingBlock() or
448    MatSetLocalToGlobalMappingBlock().
449 
450 .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMapping(), DMGetBlockSize(), VecSetBlockSize(), MatSetBlockSize()
451 @*/
452 PetscErrorCode  DMGetLocalToGlobalMappingBlock(DM dm,ISLocalToGlobalMapping *ltog)
453 {
454   PetscErrorCode ierr;
455 
456   PetscFunctionBegin;
457   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
458   PetscValidPointer(ltog,2);
459   if (!dm->ltogmapb) {
460     PetscInt bs;
461     ierr = DMGetBlockSize(dm,&bs);CHKERRQ(ierr);
462     if (bs > 1) {
463       if (!dm->ops->createlocaltoglobalmappingblock) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMappingBlock");
464       ierr = (*dm->ops->createlocaltoglobalmappingblock)(dm);CHKERRQ(ierr);
465     } else {
466       ierr = DMGetLocalToGlobalMapping(dm,&dm->ltogmapb);CHKERRQ(ierr);
467       ierr = PetscObjectReference((PetscObject)dm->ltogmapb);CHKERRQ(ierr);
468     }
469   }
470   *ltog = dm->ltogmapb;
471   PetscFunctionReturn(0);
472 }
473 
474 #undef __FUNCT__
475 #define __FUNCT__ "DMGetBlockSize"
476 /*@
477    DMGetBlockSize - Gets the inherent block size associated with a DM
478 
479    Not Collective
480 
481    Input Parameter:
482 .  dm - the DM with block structure
483 
484    Output Parameter:
485 .  bs - the block size, 1 implies no exploitable block structure
486 
487    Level: intermediate
488 
489 .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMappingBlock()
490 @*/
491 PetscErrorCode  DMGetBlockSize(DM dm,PetscInt *bs)
492 {
493   PetscFunctionBegin;
494   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
495   PetscValidPointer(bs,2);
496   if (dm->bs < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"DM does not have enough information to provide a block size yet");
497   *bs = dm->bs;
498   PetscFunctionReturn(0);
499 }
500 
501 #undef __FUNCT__
502 #define __FUNCT__ "DMCreateInterpolation"
503 /*@
504     DMCreateInterpolation - Gets interpolation matrix between two DMDA or DMComposite objects
505 
506     Collective on DM
507 
508     Input Parameter:
509 +   dm1 - the DM object
510 -   dm2 - the second, finer DM object
511 
512     Output Parameter:
513 +  mat - the interpolation
514 -  vec - the scaling (optional)
515 
516     Level: developer
517 
518     Notes:  For DMDA objects this only works for "uniform refinement", that is the refined mesh was obtained DMRefine() or the coarse mesh was obtained by
519         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation.
520 
521         For DMDA objects you can use this interpolation (more precisely the interpolation from the DMDAGetCoordinateDA()) to interpolate the mesh coordinate vectors
522         EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic.
523 
524 
525 .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen()
526 
527 @*/
528 PetscErrorCode  DMCreateInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec)
529 {
530   PetscErrorCode ierr;
531 
532   PetscFunctionBegin;
533   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
534   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
535   ierr = (*dm1->ops->createinterpolation)(dm1,dm2,mat,vec);CHKERRQ(ierr);
536   PetscFunctionReturn(0);
537 }
538 
539 #undef __FUNCT__
540 #define __FUNCT__ "DMCreateInjection"
541 /*@
542     DMCreateInjection - Gets injection matrix between two DMDA or DMComposite objects
543 
544     Collective on DM
545 
546     Input Parameter:
547 +   dm1 - the DM object
548 -   dm2 - the second, finer DM object
549 
550     Output Parameter:
551 .   ctx - the injection
552 
553     Level: developer
554 
555    Notes:  For DMDA objects this only works for "uniform refinement", that is the refined mesh was obtained DMRefine() or the coarse mesh was obtained by
556         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection.
557 
558 .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation()
559 
560 @*/
561 PetscErrorCode  DMCreateInjection(DM dm1,DM dm2,VecScatter *ctx)
562 {
563   PetscErrorCode ierr;
564 
565   PetscFunctionBegin;
566   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
567   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
568   ierr = (*dm1->ops->getinjection)(dm1,dm2,ctx);CHKERRQ(ierr);
569   PetscFunctionReturn(0);
570 }
571 
572 #undef __FUNCT__
573 #define __FUNCT__ "DMCreateColoring"
574 /*@C
575     DMCreateColoring - Gets coloring for a DMDA or DMComposite
576 
577     Collective on DM
578 
579     Input Parameter:
580 +   dm - the DM object
581 .   ctype - IS_COLORING_GHOSTED or IS_COLORING_GLOBAL
582 -   matype - either MATAIJ or MATBAIJ
583 
584     Output Parameter:
585 .   coloring - the coloring
586 
587     Level: developer
588 
589 .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix()
590 
591 @*/
592 PetscErrorCode  DMCreateColoring(DM dm,ISColoringType ctype,const MatType mtype,ISColoring *coloring)
593 {
594   PetscErrorCode ierr;
595 
596   PetscFunctionBegin;
597   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
598   if (!dm->ops->getcoloring) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No coloring for this type of DM yet");
599   ierr = (*dm->ops->getcoloring)(dm,ctype,mtype,coloring);CHKERRQ(ierr);
600   PetscFunctionReturn(0);
601 }
602 
603 #undef __FUNCT__
604 #define __FUNCT__ "DMCreateMatrix"
605 /*@C
606     DMCreateMatrix - Gets empty Jacobian for a DMDA or DMComposite
607 
608     Collective on DM
609 
610     Input Parameter:
611 +   dm - the DM object
612 -   mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, or
613             any type which inherits from one of these (such as MATAIJ)
614 
615     Output Parameter:
616 .   mat - the empty Jacobian
617 
618     Level: beginner
619 
620     Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
621        do not need to do it yourself.
622 
623        By default it also sets the nonzero structure and puts in the zero entries. To prevent setting
624        the nonzero pattern call DMDASetMatPreallocateOnly()
625 
626        For structured grid problems, when you call MatView() on this matrix it is displayed using the global natural ordering, NOT in the ordering used
627        internally by PETSc.
628 
629        For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires
630        the indices for the global numbering for DMDAs which is complicated.
631 
632 .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
633 
634 @*/
635 PetscErrorCode  DMCreateMatrix(DM dm,const MatType mtype,Mat *mat)
636 {
637   PetscErrorCode ierr;
638 
639   PetscFunctionBegin;
640   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
641 #ifndef PETSC_USE_DYNAMIC_LIBRARIES
642   ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr);
643 #endif
644   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
645   PetscValidPointer(mat,3);
646   if (dm->mattype) {
647     ierr = (*dm->ops->creatematrix)(dm,dm->mattype,mat);CHKERRQ(ierr);
648   } else {
649     ierr = (*dm->ops->creatematrix)(dm,mtype,mat);CHKERRQ(ierr);
650   }
651   PetscFunctionReturn(0);
652 }
653 
654 #undef __FUNCT__
655 #define __FUNCT__ "DMSetMatrixPreallocateOnly"
656 /*@
657   DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly
658     preallocated but the nonzero structure and zero values will not be set.
659 
660   Logically Collective on DMDA
661 
662   Input Parameter:
663 + dm - the DM
664 - only - PETSC_TRUE if only want preallocation
665 
666   Level: developer
667 .seealso DMCreateMatrix()
668 @*/
669 PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only)
670 {
671   PetscFunctionBegin;
672   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
673   dm->prealloc_only = only;
674   PetscFunctionReturn(0);
675 }
676 
677 #undef __FUNCT__
678 #define __FUNCT__ "DMGetWorkArray"
679 /*@C
680   DMGetWorkArray - Gets a work array guaranteed to be at least the input size
681 
682   Not Collective
683 
684   Input Parameters:
685 + dm - the DM object
686 - size - The minium size
687 
688   Output Parameter:
689 . array - the work array
690 
691   Level: developer
692 
693 .seealso DMDestroy(), DMCreate()
694 @*/
695 PetscErrorCode DMGetWorkArray(DM dm,PetscInt size,PetscScalar **array)
696 {
697   PetscErrorCode ierr;
698 
699   PetscFunctionBegin;
700   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
701   PetscValidPointer(array,3);
702   if (size > dm->workSize) {
703     dm->workSize = size;
704     ierr = PetscFree(dm->workArray);CHKERRQ(ierr);
705     ierr = PetscMalloc(dm->workSize * sizeof(PetscScalar), &dm->workArray);CHKERRQ(ierr);
706   }
707   *array = dm->workArray;
708   PetscFunctionReturn(0);
709 }
710 
711 
712 #undef __FUNCT__
713 #define __FUNCT__ "DMRefine"
714 /*@
715     DMRefine - Refines a DM object
716 
717     Collective on DM
718 
719     Input Parameter:
720 +   dm - the DM object
721 -   comm - the communicator to contain the new DM object (or PETSC_NULL)
722 
723     Output Parameter:
724 .   dmf - the refined DM
725 
726     Level: developer
727 
728 .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
729 
730 @*/
731 PetscErrorCode  DMRefine(DM dm,MPI_Comm comm,DM *dmf)
732 {
733   PetscErrorCode ierr;
734 
735   PetscFunctionBegin;
736   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
737   ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr);
738   if (*dmf) {
739     (*dmf)->ops->initialguess = dm->ops->initialguess;
740     (*dmf)->ops->function     = dm->ops->function;
741     (*dmf)->ops->functionj    = dm->ops->functionj;
742     if (dm->ops->jacobian != DMComputeJacobianDefault) {
743       (*dmf)->ops->jacobian     = dm->ops->jacobian;
744     }
745     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr);
746     (*dmf)->ctx     = dm->ctx;
747     (*dmf)->levelup = dm->levelup + 1;
748   }
749   PetscFunctionReturn(0);
750 }
751 
752 #undef __FUNCT__
753 #define __FUNCT__ "DMGetRefineLevel"
754 /*@
755     DMGetRefineLevel - Get's the number of refinements that have generated this DM.
756 
757     Not Collective
758 
759     Input Parameter:
760 .   dm - the DM object
761 
762     Output Parameter:
763 .   level - number of refinements
764 
765     Level: developer
766 
767 .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
768 
769 @*/
770 PetscErrorCode  DMGetRefineLevel(DM dm,PetscInt *level)
771 {
772   PetscFunctionBegin;
773   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
774   *level = dm->levelup;
775   PetscFunctionReturn(0);
776 }
777 
778 #undef __FUNCT__
779 #define __FUNCT__ "DMGlobalToLocalBegin"
780 /*@
781     DMGlobalToLocalBegin - Begins updating local vectors from global vector
782 
783     Neighbor-wise Collective on DM
784 
785     Input Parameters:
786 +   dm - the DM object
787 .   g - the global vector
788 .   mode - INSERT_VALUES or ADD_VALUES
789 -   l - the local vector
790 
791 
792     Level: beginner
793 
794 .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
795 
796 @*/
797 PetscErrorCode  DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
798 {
799   PetscErrorCode ierr;
800 
801   PetscFunctionBegin;
802   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
803   ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
804   PetscFunctionReturn(0);
805 }
806 
807 #undef __FUNCT__
808 #define __FUNCT__ "DMGlobalToLocalEnd"
809 /*@
810     DMGlobalToLocalEnd - Ends updating local vectors from global vector
811 
812     Neighbor-wise Collective on DM
813 
814     Input Parameters:
815 +   dm - the DM object
816 .   g - the global vector
817 .   mode - INSERT_VALUES or ADD_VALUES
818 -   l - the local vector
819 
820 
821     Level: beginner
822 
823 .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
824 
825 @*/
826 PetscErrorCode  DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
827 {
828   PetscErrorCode ierr;
829 
830   PetscFunctionBegin;
831   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
832   ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
833   PetscFunctionReturn(0);
834 }
835 
836 #undef __FUNCT__
837 #define __FUNCT__ "DMLocalToGlobalBegin"
838 /*@
839     DMLocalToGlobalBegin - updates global vectors from local vectors
840 
841     Neighbor-wise Collective on DM
842 
843     Input Parameters:
844 +   dm - the DM object
845 .   l - the local vector
846 .   mode - if INSERT_VALUES then no parallel communication is used, if ADD_VALUES then all ghost points from the same base point accumulate into that
847            base point.
848 - - the global vector
849 
850     Notes: In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation. If you would like to simply add the non-ghosted values in the local
851            array into the global array you need to either (1) zero the ghosted locations and use ADD_VALUES or (2) use INSERT_VALUES into a work global array and then add the work
852            global array to the final global array with VecAXPY().
853 
854     Level: beginner
855 
856 .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin()
857 
858 @*/
859 PetscErrorCode  DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g)
860 {
861   PetscErrorCode ierr;
862 
863   PetscFunctionBegin;
864   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
865   ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
866   PetscFunctionReturn(0);
867 }
868 
869 #undef __FUNCT__
870 #define __FUNCT__ "DMLocalToGlobalEnd"
871 /*@
872     DMLocalToGlobalEnd - updates global vectors from local vectors
873 
874     Neighbor-wise Collective on DM
875 
876     Input Parameters:
877 +   dm - the DM object
878 .   l - the local vector
879 .   mode - INSERT_VALUES or ADD_VALUES
880 -   g - the global vector
881 
882 
883     Level: beginner
884 
885 .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd()
886 
887 @*/
888 PetscErrorCode  DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g)
889 {
890   PetscErrorCode ierr;
891 
892   PetscFunctionBegin;
893   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
894   ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
895   PetscFunctionReturn(0);
896 }
897 
898 #undef __FUNCT__
899 #define __FUNCT__ "DMComputeJacobianDefault"
900 /*@
901     DMComputeJacobianDefault - computes the Jacobian using the DMComputeFunction() if Jacobian computer is not provided
902 
903     Collective on DM
904 
905     Input Parameter:
906 +   dm - the DM object
907 .   x - location to compute Jacobian at; may be ignored for linear problems
908 .   A - matrix that defines the operator for the linear solve
909 -   B - the matrix used to construct the preconditioner
910 
911     Level: developer
912 
913 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
914          DMSetFunction()
915 
916 @*/
917 PetscErrorCode  DMComputeJacobianDefault(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag)
918 {
919   PetscErrorCode ierr;
920 
921   PetscFunctionBegin;
922   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
923   *stflag = SAME_NONZERO_PATTERN;
924   ierr  = MatFDColoringApply(B,dm->fd,x,stflag,dm);CHKERRQ(ierr);
925   if (A != B) {
926     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
927     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
928   }
929   PetscFunctionReturn(0);
930 }
931 
932 #undef __FUNCT__
933 #define __FUNCT__ "DMCoarsen"
934 /*@
935     DMCoarsen - Coarsens a DM object
936 
937     Collective on DM
938 
939     Input Parameter:
940 +   dm - the DM object
941 -   comm - the communicator to contain the new DM object (or PETSC_NULL)
942 
943     Output Parameter:
944 .   dmc - the coarsened DM
945 
946     Level: developer
947 
948 .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
949 
950 @*/
951 PetscErrorCode  DMCoarsen(DM dm, MPI_Comm comm, DM *dmc)
952 {
953   PetscErrorCode ierr;
954   DMCoarsenHookLink link;
955 
956   PetscFunctionBegin;
957   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
958   ierr = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr);
959   (*dmc)->ops->initialguess = dm->ops->initialguess;
960   (*dmc)->ops->function     = dm->ops->function;
961   (*dmc)->ops->functionj    = dm->ops->functionj;
962   if (dm->ops->jacobian != DMComputeJacobianDefault) {
963     (*dmc)->ops->jacobian     = dm->ops->jacobian;
964   }
965   ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr);
966   (*dmc)->ctx       = dm->ctx;
967   (*dmc)->leveldown = dm->leveldown + 1;
968   for (link=dm->coarsenhook; link; link=link->next) {
969     if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);}
970   }
971   PetscFunctionReturn(0);
972 }
973 
974 #undef __FUNCT__
975 #define __FUNCT__ "DMCoarsenHookAdd"
976 /*@
977    DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid
978 
979    Logically Collective
980 
981    Input Arguments:
982 +  fine - nonlinear solver context on which to run a hook when restricting to a coarser level
983 .  coarsenhook - function to run when setting up a coarser level
984 .  restricthook - function to run to update data on coarser levels (once per SNESSolve())
985 -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
986 
987    Calling sequence of coarsenhook:
988 $    coarsenhook(DM fine,DM coarse,void *ctx);
989 
990 +  fine - fine level DM
991 .  coarse - coarse level DM to restrict problem to
992 -  ctx - optional user-defined function context
993 
994    Calling sequence for restricthook:
995 $    restricthook(DM fine,Mat mrestrict,Mat inject,DM coarse,void *ctx)
996 
997 +  fine - fine level DM
998 .  mrestrict - matrix restricting a fine-level solution to the coarse grid
999 .  inject - matrix restricting by applying the transpose of injection
1000 .  coarse - coarse level DM to update
1001 -  ctx - optional user-defined function context
1002 
1003    Level: advanced
1004 
1005    Notes:
1006    This function is only needed if auxiliary data needs to be set up on coarse grids.
1007 
1008    If this function is called multiple times, the hooks will be run in the order they are added.
1009 
1010    The
1011 
1012    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
1013    extract the finest level information from its context (instead of from the SNES).
1014 
1015 .seealso: SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1016 @*/
1017 PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx)
1018 {
1019   PetscErrorCode ierr;
1020   DMCoarsenHookLink link,*p;
1021 
1022   PetscFunctionBegin;
1023   PetscValidHeaderSpecific(fine,DM_CLASSID,1);
1024   for (p=&fine->coarsenhook; *p; *p=(*p)->next) {} /* Scan to the end of the current list of hooks */
1025   ierr = PetscMalloc(sizeof(struct _DMCoarsenHookLink),&link);CHKERRQ(ierr);
1026   link->coarsenhook = coarsenhook;
1027   link->restricthook = restricthook;
1028   link->ctx = ctx;
1029   *p = link;
1030   PetscFunctionReturn(0);
1031 }
1032 
1033 #undef __FUNCT__
1034 #define __FUNCT__ "DMRestrict"
1035 /*@
1036    DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd()
1037 
1038    Collective if any hooks are
1039 
1040    Input Arguments:
1041 +  fine - finer DM to use as a base
1042 .  restrct - restriction matrix, apply using MatRestrict()
1043 .  inject - injection matrix, also use MatRestrict()
1044 -  coarse - coarer DM to update
1045 
1046    Level: developer
1047 
1048 .seealso: DMCoarsenHookAdd(), MatRestrict()
1049 @*/
1050 PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse)
1051 {
1052   PetscErrorCode ierr;
1053   DMCoarsenHookLink link;
1054 
1055   PetscFunctionBegin;
1056   for (link=fine->coarsenhook; link; link=link->next) {
1057     if (link->restricthook) {ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr);}
1058   }
1059   PetscFunctionReturn(0);
1060 }
1061 
1062 #undef __FUNCT__
1063 #define __FUNCT__ "DMGetCoarsenLevel"
1064 /*@
1065     DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM.
1066 
1067     Not Collective
1068 
1069     Input Parameter:
1070 .   dm - the DM object
1071 
1072     Output Parameter:
1073 .   level - number of coarsenings
1074 
1075     Level: developer
1076 
1077 .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
1078 
1079 @*/
1080 PetscErrorCode  DMGetCoarsenLevel(DM dm,PetscInt *level)
1081 {
1082   PetscFunctionBegin;
1083   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1084   *level = dm->leveldown;
1085   PetscFunctionReturn(0);
1086 }
1087 
1088 
1089 
1090 #undef __FUNCT__
1091 #define __FUNCT__ "DMRefineHierarchy"
1092 /*@C
1093     DMRefineHierarchy - Refines a DM object, all levels at once
1094 
1095     Collective on DM
1096 
1097     Input Parameter:
1098 +   dm - the DM object
1099 -   nlevels - the number of levels of refinement
1100 
1101     Output Parameter:
1102 .   dmf - the refined DM hierarchy
1103 
1104     Level: developer
1105 
1106 .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
1107 
1108 @*/
1109 PetscErrorCode  DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[])
1110 {
1111   PetscErrorCode ierr;
1112 
1113   PetscFunctionBegin;
1114   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1115   if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
1116   if (nlevels == 0) PetscFunctionReturn(0);
1117   if (dm->ops->refinehierarchy) {
1118     ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr);
1119   } else if (dm->ops->refine) {
1120     PetscInt i;
1121 
1122     ierr = DMRefine(dm,((PetscObject)dm)->comm,&dmf[0]);CHKERRQ(ierr);
1123     for (i=1; i<nlevels; i++) {
1124       ierr = DMRefine(dmf[i-1],((PetscObject)dm)->comm,&dmf[i]);CHKERRQ(ierr);
1125     }
1126   } else {
1127     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No RefineHierarchy for this DM yet");
1128   }
1129   PetscFunctionReturn(0);
1130 }
1131 
1132 #undef __FUNCT__
1133 #define __FUNCT__ "DMCoarsenHierarchy"
1134 /*@C
1135     DMCoarsenHierarchy - Coarsens a DM object, all levels at once
1136 
1137     Collective on DM
1138 
1139     Input Parameter:
1140 +   dm - the DM object
1141 -   nlevels - the number of levels of coarsening
1142 
1143     Output Parameter:
1144 .   dmc - the coarsened DM hierarchy
1145 
1146     Level: developer
1147 
1148 .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
1149 
1150 @*/
1151 PetscErrorCode  DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[])
1152 {
1153   PetscErrorCode ierr;
1154 
1155   PetscFunctionBegin;
1156   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1157   if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
1158   if (nlevels == 0) PetscFunctionReturn(0);
1159   PetscValidPointer(dmc,3);
1160   if (dm->ops->coarsenhierarchy) {
1161     ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr);
1162   } else if (dm->ops->coarsen) {
1163     PetscInt i;
1164 
1165     ierr = DMCoarsen(dm,((PetscObject)dm)->comm,&dmc[0]);CHKERRQ(ierr);
1166     for (i=1; i<nlevels; i++) {
1167       ierr = DMCoarsen(dmc[i-1],((PetscObject)dm)->comm,&dmc[i]);CHKERRQ(ierr);
1168     }
1169   } else {
1170     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet");
1171   }
1172   PetscFunctionReturn(0);
1173 }
1174 
1175 #undef __FUNCT__
1176 #define __FUNCT__ "DMCreateAggregates"
1177 /*@
1178    DMCreateAggregates - Gets the aggregates that map between
1179    grids associated with two DMs.
1180 
1181    Collective on DM
1182 
1183    Input Parameters:
1184 +  dmc - the coarse grid DM
1185 -  dmf - the fine grid DM
1186 
1187    Output Parameters:
1188 .  rest - the restriction matrix (transpose of the projection matrix)
1189 
1190    Level: intermediate
1191 
1192 .keywords: interpolation, restriction, multigrid
1193 
1194 .seealso: DMRefine(), DMCreateInjection(), DMCreateInterpolation()
1195 @*/
1196 PetscErrorCode  DMCreateAggregates(DM dmc, DM dmf, Mat *rest)
1197 {
1198   PetscErrorCode ierr;
1199 
1200   PetscFunctionBegin;
1201   PetscValidHeaderSpecific(dmc,DM_CLASSID,1);
1202   PetscValidHeaderSpecific(dmf,DM_CLASSID,2);
1203   ierr = (*dmc->ops->getaggregates)(dmc, dmf, rest);CHKERRQ(ierr);
1204   PetscFunctionReturn(0);
1205 }
1206 
1207 #undef __FUNCT__
1208 #define __FUNCT__ "DMSetApplicationContextDestroy"
1209 /*@C
1210     DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed
1211 
1212     Not Collective
1213 
1214     Input Parameters:
1215 +   dm - the DM object
1216 -   destroy - the destroy function
1217 
1218     Level: intermediate
1219 
1220 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
1221 
1222 @*/
1223 PetscErrorCode  DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**))
1224 {
1225   PetscFunctionBegin;
1226   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1227   dm->ctxdestroy = destroy;
1228   PetscFunctionReturn(0);
1229 }
1230 
1231 #undef __FUNCT__
1232 #define __FUNCT__ "DMSetApplicationContext"
1233 /*@
1234     DMSetApplicationContext - Set a user context into a DM object
1235 
1236     Not Collective
1237 
1238     Input Parameters:
1239 +   dm - the DM object
1240 -   ctx - the user context
1241 
1242     Level: intermediate
1243 
1244 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
1245 
1246 @*/
1247 PetscErrorCode  DMSetApplicationContext(DM dm,void *ctx)
1248 {
1249   PetscFunctionBegin;
1250   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1251   dm->ctx = ctx;
1252   PetscFunctionReturn(0);
1253 }
1254 
1255 #undef __FUNCT__
1256 #define __FUNCT__ "DMGetApplicationContext"
1257 /*@
1258     DMGetApplicationContext - Gets a user context from a DM object
1259 
1260     Not Collective
1261 
1262     Input Parameter:
1263 .   dm - the DM object
1264 
1265     Output Parameter:
1266 .   ctx - the user context
1267 
1268     Level: intermediate
1269 
1270 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
1271 
1272 @*/
1273 PetscErrorCode  DMGetApplicationContext(DM dm,void *ctx)
1274 {
1275   PetscFunctionBegin;
1276   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1277   *(void**)ctx = dm->ctx;
1278   PetscFunctionReturn(0);
1279 }
1280 
1281 #undef __FUNCT__
1282 #define __FUNCT__ "DMSetInitialGuess"
1283 /*@C
1284     DMSetInitialGuess - sets a function to compute an initial guess vector entries for the solvers
1285 
1286     Logically Collective on DM
1287 
1288     Input Parameter:
1289 +   dm - the DM object to destroy
1290 -   f - the function to compute the initial guess
1291 
1292     Level: intermediate
1293 
1294 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
1295 
1296 @*/
1297 PetscErrorCode  DMSetInitialGuess(DM dm,PetscErrorCode (*f)(DM,Vec))
1298 {
1299   PetscFunctionBegin;
1300   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1301   dm->ops->initialguess = f;
1302   PetscFunctionReturn(0);
1303 }
1304 
1305 #undef __FUNCT__
1306 #define __FUNCT__ "DMSetFunction"
1307 /*@C
1308     DMSetFunction - sets a function to compute the right hand side vector entries for the KSP solver or nonlinear function for SNES
1309 
1310     Logically Collective on DM
1311 
1312     Input Parameter:
1313 +   dm - the DM object
1314 -   f - the function to compute (use PETSC_NULL to cancel a previous function that was set)
1315 
1316     Level: intermediate
1317 
1318     Notes: This sets both the function for function evaluations and the function used to compute Jacobians via finite differences if no Jacobian
1319            computer is provided with DMSetJacobian(). Canceling cancels the function, but not the function used to compute the Jacobian.
1320 
1321 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
1322          DMSetJacobian()
1323 
1324 @*/
1325 PetscErrorCode  DMSetFunction(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
1326 {
1327   PetscFunctionBegin;
1328   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1329   dm->ops->function = f;
1330   if (f) {
1331     dm->ops->functionj = f;
1332   }
1333   PetscFunctionReturn(0);
1334 }
1335 
1336 #undef __FUNCT__
1337 #define __FUNCT__ "DMSetJacobian"
1338 /*@C
1339     DMSetJacobian - sets a function to compute the matrix entries for the KSP solver or Jacobian for SNES
1340 
1341     Logically Collective on DM
1342 
1343     Input Parameter:
1344 +   dm - the DM object to destroy
1345 -   f - the function to compute the matrix entries
1346 
1347     Level: intermediate
1348 
1349 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
1350          DMSetFunction()
1351 
1352 @*/
1353 PetscErrorCode  DMSetJacobian(DM dm,PetscErrorCode (*f)(DM,Vec,Mat,Mat,MatStructure*))
1354 {
1355   PetscFunctionBegin;
1356   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1357   dm->ops->jacobian = f;
1358   PetscFunctionReturn(0);
1359 }
1360 
1361 #undef __FUNCT__
1362 #define __FUNCT__ "DMSetVariableBounds"
1363 /*@C
1364     DMSetVariableBounds - sets a function to compute the the lower and upper bound vectors for SNESVI.
1365 
1366     Logically Collective on DM
1367 
1368     Input Parameter:
1369 +   dm - the DM object
1370 -   f - the function that computes variable bounds used by SNESVI (use PETSC_NULL to cancel a previous function that was set)
1371 
1372     Level: intermediate
1373 
1374 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
1375          DMSetJacobian()
1376 
1377 @*/
1378 PetscErrorCode  DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
1379 {
1380   PetscFunctionBegin;
1381   dm->ops->computevariablebounds = f;
1382   PetscFunctionReturn(0);
1383 }
1384 
1385 #undef __FUNCT__
1386 #define __FUNCT__ "DMHasVariableBounds"
1387 /*@
1388     DMHasVariableBounds - does the DM object have a variable bounds function?
1389 
1390     Not Collective
1391 
1392     Input Parameter:
1393 .   dm - the DM object to destroy
1394 
1395     Output Parameter:
1396 .   flg - PETSC_TRUE if the variable bounds function exists
1397 
1398     Level: developer
1399 
1400 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
1401 
1402 @*/
1403 PetscErrorCode  DMHasVariableBounds(DM dm,PetscBool  *flg)
1404 {
1405   PetscFunctionBegin;
1406   *flg =  (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE;
1407   PetscFunctionReturn(0);
1408 }
1409 
1410 #undef __FUNCT__
1411 #define __FUNCT__ "DMComputeVariableBounds"
1412 /*@C
1413     DMComputeVariableBounds - compute variable bounds used by SNESVI.
1414 
1415     Logically Collective on DM
1416 
1417     Input Parameters:
1418 +   dm - the DM object to destroy
1419 -   x  - current solution at which the bounds are computed
1420 
1421     Output parameters:
1422 +   xl - lower bound
1423 -   xu - upper bound
1424 
1425     Level: intermediate
1426 
1427 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
1428          DMSetFunction(), DMSetVariableBounds()
1429 
1430 @*/
1431 PetscErrorCode  DMComputeVariableBounds(DM dm, Vec xl, Vec xu)
1432 {
1433   PetscErrorCode ierr;
1434   PetscFunctionBegin;
1435   PetscValidHeaderSpecific(xl,VEC_CLASSID,2);
1436   PetscValidHeaderSpecific(xu,VEC_CLASSID,2);
1437   if(dm->ops->computevariablebounds) {
1438     ierr = (*dm->ops->computevariablebounds)(dm, xl,xu); CHKERRQ(ierr);
1439   }
1440   else {
1441     ierr = VecSet(xl,SNES_VI_NINF); CHKERRQ(ierr);
1442     ierr = VecSet(xu,SNES_VI_INF);  CHKERRQ(ierr);
1443   }
1444   PetscFunctionReturn(0);
1445 }
1446 
1447 #undef __FUNCT__
1448 #define __FUNCT__ "DMComputeInitialGuess"
1449 /*@
1450     DMComputeInitialGuess - computes an initial guess vector entries for the KSP solvers
1451 
1452     Collective on DM
1453 
1454     Input Parameter:
1455 +   dm - the DM object to destroy
1456 -   x - the vector to hold the initial guess values
1457 
1458     Level: developer
1459 
1460 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetRhs(), DMSetMat()
1461 
1462 @*/
1463 PetscErrorCode  DMComputeInitialGuess(DM dm,Vec x)
1464 {
1465   PetscErrorCode ierr;
1466   PetscFunctionBegin;
1467   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1468   if (!dm->ops->initialguess) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetInitialGuess()");
1469   ierr = (*dm->ops->initialguess)(dm,x);CHKERRQ(ierr);
1470   PetscFunctionReturn(0);
1471 }
1472 
1473 #undef __FUNCT__
1474 #define __FUNCT__ "DMHasInitialGuess"
1475 /*@
1476     DMHasInitialGuess - does the DM object have an initial guess function
1477 
1478     Not Collective
1479 
1480     Input Parameter:
1481 .   dm - the DM object to destroy
1482 
1483     Output Parameter:
1484 .   flg - PETSC_TRUE if function exists
1485 
1486     Level: developer
1487 
1488 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
1489 
1490 @*/
1491 PetscErrorCode  DMHasInitialGuess(DM dm,PetscBool  *flg)
1492 {
1493   PetscFunctionBegin;
1494   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1495   *flg =  (dm->ops->initialguess) ? PETSC_TRUE : PETSC_FALSE;
1496   PetscFunctionReturn(0);
1497 }
1498 
1499 #undef __FUNCT__
1500 #define __FUNCT__ "DMHasFunction"
1501 /*@
1502     DMHasFunction - does the DM object have a function
1503 
1504     Not Collective
1505 
1506     Input Parameter:
1507 .   dm - the DM object to destroy
1508 
1509     Output Parameter:
1510 .   flg - PETSC_TRUE if function exists
1511 
1512     Level: developer
1513 
1514 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
1515 
1516 @*/
1517 PetscErrorCode  DMHasFunction(DM dm,PetscBool  *flg)
1518 {
1519   PetscFunctionBegin;
1520   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1521   *flg =  (dm->ops->function) ? PETSC_TRUE : PETSC_FALSE;
1522   PetscFunctionReturn(0);
1523 }
1524 
1525 #undef __FUNCT__
1526 #define __FUNCT__ "DMHasJacobian"
1527 /*@
1528     DMHasJacobian - does the DM object have a matrix function
1529 
1530     Not Collective
1531 
1532     Input Parameter:
1533 .   dm - the DM object to destroy
1534 
1535     Output Parameter:
1536 .   flg - PETSC_TRUE if function exists
1537 
1538     Level: developer
1539 
1540 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
1541 
1542 @*/
1543 PetscErrorCode  DMHasJacobian(DM dm,PetscBool  *flg)
1544 {
1545   PetscFunctionBegin;
1546   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1547   *flg =  (dm->ops->jacobian) ? PETSC_TRUE : PETSC_FALSE;
1548   PetscFunctionReturn(0);
1549 }
1550 
1551 #undef  __FUNCT__
1552 #define __FUNCT__ "DMSetVec"
1553 /*@
1554     DMSetVec - set the vector at which to compute residual, Jacobian and VI bounds, if the problem is nonlinear.
1555 
1556     Collective on DM
1557 
1558     Input Parameter:
1559 +   dm - the DM object
1560 -   x - location to compute residual, Jacobian and VI bounds at; will be PETSC_NULL for linear problems.
1561 
1562     Level: developer
1563 
1564 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
1565          DMSetFunction(), DMSetJacobian(), DMSetVariableBounds()
1566 
1567 @*/
1568 PetscErrorCode  DMSetVec(DM dm,Vec x)
1569 {
1570   PetscErrorCode ierr;
1571   PetscFunctionBegin;
1572   if (x) {
1573     if (!dm->x) {
1574       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
1575     }
1576     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
1577   }
1578   else if(dm->x) {
1579     ierr = VecDestroy(&dm->x);  CHKERRQ(ierr);
1580   }
1581   PetscFunctionReturn(0);
1582 }
1583 
1584 
1585 #undef __FUNCT__
1586 #define __FUNCT__ "DMComputeFunction"
1587 /*@
1588     DMComputeFunction - computes the right hand side vector entries for the KSP solver or nonlinear function for SNES
1589 
1590     Collective on DM
1591 
1592     Input Parameter:
1593 +   dm - the DM object to destroy
1594 .   x - the location where the function is evaluationed, may be ignored for linear problems
1595 -   b - the vector to hold the right hand side entries
1596 
1597     Level: developer
1598 
1599 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
1600          DMSetJacobian()
1601 
1602 @*/
1603 PetscErrorCode  DMComputeFunction(DM dm,Vec x,Vec b)
1604 {
1605   PetscErrorCode ierr;
1606   PetscFunctionBegin;
1607   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1608   if (!dm->ops->function) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetFunction()");
1609   PetscStackPush("DM user function");
1610   ierr = (*dm->ops->function)(dm,x,b);CHKERRQ(ierr);
1611   PetscStackPop;
1612   PetscFunctionReturn(0);
1613 }
1614 
1615 
1616 
1617 #undef __FUNCT__
1618 #define __FUNCT__ "DMComputeJacobian"
1619 /*@
1620     DMComputeJacobian - compute the matrix entries for the solver
1621 
1622     Collective on DM
1623 
1624     Input Parameter:
1625 +   dm - the DM object
1626 .   x - location to compute Jacobian at; will be PETSC_NULL for linear problems, for nonlinear problems if not provided then pulled from DM
1627 .   A - matrix that defines the operator for the linear solve
1628 -   B - the matrix used to construct the preconditioner
1629 
1630     Level: developer
1631 
1632 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
1633          DMSetFunction()
1634 
1635 @*/
1636 PetscErrorCode  DMComputeJacobian(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag)
1637 {
1638   PetscErrorCode ierr;
1639 
1640   PetscFunctionBegin;
1641   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1642   if (!dm->ops->jacobian) {
1643     ISColoring     coloring;
1644     MatFDColoring  fd;
1645 
1646     ierr = DMCreateColoring(dm,dm->coloringtype,MATAIJ,&coloring);CHKERRQ(ierr);
1647     ierr = MatFDColoringCreate(B,coloring,&fd);CHKERRQ(ierr);
1648     ierr = ISColoringDestroy(&coloring);CHKERRQ(ierr);
1649     ierr = MatFDColoringSetFunction(fd,(PetscErrorCode (*)(void))dm->ops->functionj,dm);CHKERRQ(ierr);
1650     ierr = PetscObjectSetOptionsPrefix((PetscObject)fd,((PetscObject)dm)->prefix);CHKERRQ(ierr);
1651     ierr = MatFDColoringSetFromOptions(fd);CHKERRQ(ierr);
1652 
1653     dm->fd = fd;
1654     dm->ops->jacobian = DMComputeJacobianDefault;
1655 
1656     /* don't know why this is needed */
1657     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
1658   }
1659   if (!x) x = dm->x;
1660   ierr = (*dm->ops->jacobian)(dm,x,A,B,stflag);CHKERRQ(ierr);
1661 
1662   /* if matrix depends on x; i.e. nonlinear problem, keep copy of input vector since needed by multigrid methods to generate coarse grid matrices */
1663   if (x) {
1664     if (!dm->x) {
1665       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
1666     }
1667     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
1668   }
1669   if (A != B) {
1670     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1671     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1672   }
1673   PetscFunctionReturn(0);
1674 }
1675 
1676 
1677 PetscFList DMList                       = PETSC_NULL;
1678 PetscBool  DMRegisterAllCalled          = PETSC_FALSE;
1679 
1680 #undef __FUNCT__
1681 #define __FUNCT__ "DMSetType"
1682 /*@C
1683   DMSetType - Builds a DM, for a particular DM implementation.
1684 
1685   Collective on DM
1686 
1687   Input Parameters:
1688 + dm     - The DM object
1689 - method - The name of the DM type
1690 
1691   Options Database Key:
1692 . -dm_type <type> - Sets the DM type; use -help for a list of available types
1693 
1694   Notes:
1695   See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D).
1696 
1697   Level: intermediate
1698 
1699 .keywords: DM, set, type
1700 .seealso: DMGetType(), DMCreate()
1701 @*/
1702 PetscErrorCode  DMSetType(DM dm, const DMType method)
1703 {
1704   PetscErrorCode (*r)(DM);
1705   PetscBool      match;
1706   PetscErrorCode ierr;
1707 
1708   PetscFunctionBegin;
1709   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
1710   ierr = PetscTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr);
1711   if (match) PetscFunctionReturn(0);
1712 
1713   if (!DMRegisterAllCalled) {ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
1714   ierr = PetscFListFind(DMList, ((PetscObject)dm)->comm, method,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
1715   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method);
1716 
1717   if (dm->ops->destroy) {
1718     ierr = (*dm->ops->destroy)(dm);CHKERRQ(ierr);
1719     dm->ops->destroy = PETSC_NULL;
1720   }
1721   ierr = (*r)(dm);CHKERRQ(ierr);
1722   ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr);
1723   PetscFunctionReturn(0);
1724 }
1725 
1726 #undef __FUNCT__
1727 #define __FUNCT__ "DMGetType"
1728 /*@C
1729   DMGetType - Gets the DM type name (as a string) from the DM.
1730 
1731   Not Collective
1732 
1733   Input Parameter:
1734 . dm  - The DM
1735 
1736   Output Parameter:
1737 . type - The DM type name
1738 
1739   Level: intermediate
1740 
1741 .keywords: DM, get, type, name
1742 .seealso: DMSetType(), DMCreate()
1743 @*/
1744 PetscErrorCode  DMGetType(DM dm, const DMType *type)
1745 {
1746   PetscErrorCode ierr;
1747 
1748   PetscFunctionBegin;
1749   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
1750   PetscValidCharPointer(type,2);
1751   if (!DMRegisterAllCalled) {
1752     ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);
1753   }
1754   *type = ((PetscObject)dm)->type_name;
1755   PetscFunctionReturn(0);
1756 }
1757 
1758 #undef __FUNCT__
1759 #define __FUNCT__ "DMConvert"
1760 /*@C
1761   DMConvert - Converts a DM to another DM, either of the same or different type.
1762 
1763   Collective on DM
1764 
1765   Input Parameters:
1766 + dm - the DM
1767 - newtype - new DM type (use "same" for the same type)
1768 
1769   Output Parameter:
1770 . M - pointer to new DM
1771 
1772   Notes:
1773   Cannot be used to convert a sequential DM to parallel or parallel to sequential,
1774   the MPI communicator of the generated DM is always the same as the communicator
1775   of the input DM.
1776 
1777   Level: intermediate
1778 
1779 .seealso: DMCreate()
1780 @*/
1781 PetscErrorCode DMConvert(DM dm, const DMType newtype, DM *M)
1782 {
1783   DM             B;
1784   char           convname[256];
1785   PetscBool      sametype, issame;
1786   PetscErrorCode ierr;
1787 
1788   PetscFunctionBegin;
1789   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1790   PetscValidType(dm,1);
1791   PetscValidPointer(M,3);
1792   ierr = PetscTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr);
1793   ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr);
1794   {
1795     PetscErrorCode (*conv)(DM, const DMType, DM *) = PETSC_NULL;
1796 
1797     /*
1798        Order of precedence:
1799        1) See if a specialized converter is known to the current DM.
1800        2) See if a specialized converter is known to the desired DM class.
1801        3) See if a good general converter is registered for the desired class
1802        4) See if a good general converter is known for the current matrix.
1803        5) Use a really basic converter.
1804     */
1805 
1806     /* 1) See if a specialized converter is known to the current DM and the desired class */
1807     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
1808     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
1809     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
1810     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
1811     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
1812     ierr = PetscObjectQueryFunction((PetscObject)dm,convname,(void (**)(void))&conv);CHKERRQ(ierr);
1813     if (conv) goto foundconv;
1814 
1815     /* 2)  See if a specialized converter is known to the desired DM class. */
1816     ierr = DMCreate(((PetscObject) dm)->comm, &B);CHKERRQ(ierr);
1817     ierr = DMSetType(B, newtype);CHKERRQ(ierr);
1818     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
1819     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
1820     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
1821     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
1822     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
1823     ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
1824     if (conv) {
1825       ierr = DMDestroy(&B);CHKERRQ(ierr);
1826       goto foundconv;
1827     }
1828 
1829 #if 0
1830     /* 3) See if a good general converter is registered for the desired class */
1831     conv = B->ops->convertfrom;
1832     ierr = DMDestroy(&B);CHKERRQ(ierr);
1833     if (conv) goto foundconv;
1834 
1835     /* 4) See if a good general converter is known for the current matrix */
1836     if (dm->ops->convert) {
1837       conv = dm->ops->convert;
1838     }
1839     if (conv) goto foundconv;
1840 #endif
1841 
1842     /* 5) Use a really basic converter. */
1843     SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype);
1844 
1845     foundconv:
1846     ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
1847     ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr);
1848     ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
1849   }
1850   ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr);
1851   PetscFunctionReturn(0);
1852 }
1853 
1854 /*--------------------------------------------------------------------------------------------------------------------*/
1855 
1856 #undef __FUNCT__
1857 #define __FUNCT__ "DMRegister"
1858 /*@C
1859   DMRegister - See DMRegisterDynamic()
1860 
1861   Level: advanced
1862 @*/
1863 PetscErrorCode  DMRegister(const char sname[], const char path[], const char name[], PetscErrorCode (*function)(DM))
1864 {
1865   char fullname[PETSC_MAX_PATH_LEN];
1866   PetscErrorCode ierr;
1867 
1868   PetscFunctionBegin;
1869   ierr = PetscStrcpy(fullname, path);CHKERRQ(ierr);
1870   ierr = PetscStrcat(fullname, ":");CHKERRQ(ierr);
1871   ierr = PetscStrcat(fullname, name);CHKERRQ(ierr);
1872   ierr = PetscFListAdd(&DMList, sname, fullname, (void (*)(void)) function);CHKERRQ(ierr);
1873   PetscFunctionReturn(0);
1874 }
1875 
1876 
1877 /*--------------------------------------------------------------------------------------------------------------------*/
1878 #undef __FUNCT__
1879 #define __FUNCT__ "DMRegisterDestroy"
1880 /*@C
1881    DMRegisterDestroy - Frees the list of DM methods that were registered by DMRegister()/DMRegisterDynamic().
1882 
1883    Not Collective
1884 
1885    Level: advanced
1886 
1887 .keywords: DM, register, destroy
1888 .seealso: DMRegister(), DMRegisterAll(), DMRegisterDynamic()
1889 @*/
1890 PetscErrorCode  DMRegisterDestroy(void)
1891 {
1892   PetscErrorCode ierr;
1893 
1894   PetscFunctionBegin;
1895   ierr = PetscFListDestroy(&DMList);CHKERRQ(ierr);
1896   DMRegisterAllCalled = PETSC_FALSE;
1897   PetscFunctionReturn(0);
1898 }
1899 
1900 #if defined(PETSC_HAVE_MATLAB_ENGINE)
1901 #include <mex.h>
1902 
1903 typedef struct {char *funcname; char *jacname; mxArray *ctx;} DMMatlabContext;
1904 
1905 #undef __FUNCT__
1906 #define __FUNCT__ "DMComputeFunction_Matlab"
1907 /*
1908    DMComputeFunction_Matlab - Calls the function that has been set with
1909                          DMSetFunctionMatlab().
1910 
1911    For linear problems x is null
1912 
1913 .seealso: DMSetFunction(), DMGetFunction()
1914 */
1915 PetscErrorCode  DMComputeFunction_Matlab(DM dm,Vec x,Vec y)
1916 {
1917   PetscErrorCode    ierr;
1918   DMMatlabContext   *sctx;
1919   int               nlhs = 1,nrhs = 4;
1920   mxArray	    *plhs[1],*prhs[4];
1921   long long int     lx = 0,ly = 0,ls = 0;
1922 
1923   PetscFunctionBegin;
1924   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1925   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1926   PetscCheckSameComm(dm,1,y,3);
1927 
1928   /* call Matlab function in ctx with arguments x and y */
1929   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
1930   ierr = PetscMemcpy(&ls,&dm,sizeof(dm));CHKERRQ(ierr);
1931   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
1932   ierr = PetscMemcpy(&ly,&y,sizeof(y));CHKERRQ(ierr);
1933   prhs[0] =  mxCreateDoubleScalar((double)ls);
1934   prhs[1] =  mxCreateDoubleScalar((double)lx);
1935   prhs[2] =  mxCreateDoubleScalar((double)ly);
1936   prhs[3] =  mxCreateString(sctx->funcname);
1937   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeFunctionInternal");CHKERRQ(ierr);
1938   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
1939   mxDestroyArray(prhs[0]);
1940   mxDestroyArray(prhs[1]);
1941   mxDestroyArray(prhs[2]);
1942   mxDestroyArray(prhs[3]);
1943   mxDestroyArray(plhs[0]);
1944   PetscFunctionReturn(0);
1945 }
1946 
1947 
1948 #undef __FUNCT__
1949 #define __FUNCT__ "DMSetFunctionMatlab"
1950 /*
1951    DMSetFunctionMatlab - Sets the function evaluation routine
1952 
1953 */
1954 PetscErrorCode  DMSetFunctionMatlab(DM dm,const char *func)
1955 {
1956   PetscErrorCode    ierr;
1957   DMMatlabContext   *sctx;
1958 
1959   PetscFunctionBegin;
1960   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1961   /* currently sctx is memory bleed */
1962   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
1963   if (!sctx) {
1964     ierr = PetscMalloc(sizeof(DMMatlabContext),&sctx);CHKERRQ(ierr);
1965   }
1966   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
1967   ierr = DMSetApplicationContext(dm,sctx);CHKERRQ(ierr);
1968   ierr = DMSetFunction(dm,DMComputeFunction_Matlab);CHKERRQ(ierr);
1969   PetscFunctionReturn(0);
1970 }
1971 
1972 #undef __FUNCT__
1973 #define __FUNCT__ "DMComputeJacobian_Matlab"
1974 /*
1975    DMComputeJacobian_Matlab - Calls the function that has been set with
1976                          DMSetJacobianMatlab().
1977 
1978    For linear problems x is null
1979 
1980 .seealso: DMSetFunction(), DMGetFunction()
1981 */
1982 PetscErrorCode  DMComputeJacobian_Matlab(DM dm,Vec x,Mat A,Mat B,MatStructure *str)
1983 {
1984   PetscErrorCode    ierr;
1985   DMMatlabContext   *sctx;
1986   int               nlhs = 2,nrhs = 5;
1987   mxArray	    *plhs[2],*prhs[5];
1988   long long int     lx = 0,lA = 0,lB = 0,ls = 0;
1989 
1990   PetscFunctionBegin;
1991   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1992   PetscValidHeaderSpecific(A,MAT_CLASSID,3);
1993 
1994   /* call MATLAB function in ctx with arguments x, A, and B */
1995   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
1996   ierr = PetscMemcpy(&ls,&dm,sizeof(dm));CHKERRQ(ierr);
1997   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
1998   ierr = PetscMemcpy(&lA,&A,sizeof(A));CHKERRQ(ierr);
1999   ierr = PetscMemcpy(&lB,&B,sizeof(B));CHKERRQ(ierr);
2000   prhs[0] =  mxCreateDoubleScalar((double)ls);
2001   prhs[1] =  mxCreateDoubleScalar((double)lx);
2002   prhs[2] =  mxCreateDoubleScalar((double)lA);
2003   prhs[3] =  mxCreateDoubleScalar((double)lB);
2004   prhs[4] =  mxCreateString(sctx->jacname);
2005   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeJacobianInternal");CHKERRQ(ierr);
2006   *str    =  (MatStructure) mxGetScalar(plhs[0]);
2007   ierr    =  (PetscInt) mxGetScalar(plhs[1]);CHKERRQ(ierr);
2008   mxDestroyArray(prhs[0]);
2009   mxDestroyArray(prhs[1]);
2010   mxDestroyArray(prhs[2]);
2011   mxDestroyArray(prhs[3]);
2012   mxDestroyArray(prhs[4]);
2013   mxDestroyArray(plhs[0]);
2014   mxDestroyArray(plhs[1]);
2015   PetscFunctionReturn(0);
2016 }
2017 
2018 
2019 #undef __FUNCT__
2020 #define __FUNCT__ "DMSetJacobianMatlab"
2021 /*
2022    DMSetJacobianMatlab - Sets the Jacobian function evaluation routine
2023 
2024 */
2025 PetscErrorCode  DMSetJacobianMatlab(DM dm,const char *func)
2026 {
2027   PetscErrorCode    ierr;
2028   DMMatlabContext   *sctx;
2029 
2030   PetscFunctionBegin;
2031   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2032   /* currently sctx is memory bleed */
2033   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
2034   if (!sctx) {
2035     ierr = PetscMalloc(sizeof(DMMatlabContext),&sctx);CHKERRQ(ierr);
2036   }
2037   ierr = PetscStrallocpy(func,&sctx->jacname);CHKERRQ(ierr);
2038   ierr = DMSetApplicationContext(dm,sctx);CHKERRQ(ierr);
2039   ierr = DMSetJacobian(dm,DMComputeJacobian_Matlab);CHKERRQ(ierr);
2040   PetscFunctionReturn(0);
2041 }
2042 #endif
2043 
2044 #undef __FUNCT__
2045 #define __FUNCT__ "DMLoad"
2046 /*@C
2047   DMLoad - Loads a DM that has been stored in binary or HDF5 format
2048   with DMView().
2049 
2050   Collective on PetscViewer
2051 
2052   Input Parameters:
2053 + newdm - the newly loaded DM, this needs to have been created with DMCreate() or
2054            some related function before a call to DMLoad().
2055 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
2056            HDF5 file viewer, obtained from PetscViewerHDF5Open()
2057 
2058    Level: intermediate
2059 
2060   Notes:
2061   Defaults to the DM DA.
2062 
2063   Notes for advanced users:
2064   Most users should not need to know the details of the binary storage
2065   format, since DMLoad() and DMView() completely hide these details.
2066   But for anyone who's interested, the standard binary matrix storage
2067   format is
2068 .vb
2069      has not yet been determined
2070 .ve
2071 
2072    In addition, PETSc automatically does the byte swapping for
2073 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
2074 linux, Windows and the paragon; thus if you write your own binary
2075 read/write routines you have to swap the bytes; see PetscBinaryRead()
2076 and PetscBinaryWrite() to see how this may be done.
2077 
2078   Concepts: vector^loading from file
2079 
2080 .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad()
2081 @*/
2082 PetscErrorCode  DMLoad(DM newdm, PetscViewer viewer)
2083 {
2084   PetscErrorCode ierr;
2085 
2086   PetscFunctionBegin;
2087   PetscValidHeaderSpecific(newdm,DM_CLASSID,1);
2088   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
2089 
2090   if (!((PetscObject)newdm)->type_name) {
2091     ierr = DMSetType(newdm, DMDA);CHKERRQ(ierr);
2092   }
2093   ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);
2094   PetscFunctionReturn(0);
2095 }
2096 
2097 /******************************** FEM Support **********************************/
2098 
2099 #undef __FUNCT__
2100 #define __FUNCT__ "DMPrintCellVector"
2101 PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) {
2102   PetscInt       f;
2103   PetscErrorCode ierr;
2104 
2105   PetscFunctionBegin;
2106   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
2107   for(f = 0; f < len; ++f) {
2108     ierr = PetscPrintf(PETSC_COMM_SELF, "  | %G |\n", PetscRealPart(x[f]));CHKERRQ(ierr);
2109   }
2110   PetscFunctionReturn(0);
2111 }
2112 
2113 #undef __FUNCT__
2114 #define __FUNCT__ "DMPrintCellMatrix"
2115 PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) {
2116   PetscInt       f, g;
2117   PetscErrorCode ierr;
2118 
2119   PetscFunctionBegin;
2120   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
2121   for(f = 0; f < rows; ++f) {
2122     ierr = PetscPrintf(PETSC_COMM_SELF, "  |");CHKERRQ(ierr);
2123     for(g = 0; g < cols; ++g) {
2124       ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5G", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr);
2125     }
2126     ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr);
2127   }
2128   PetscFunctionReturn(0);
2129 }
2130