xref: /petsc/src/sys/objects/inherit.c (revision 04d7464b71f14a73adf7cb3f664404cc6936f6d1)
1 
2 /*
3      Provides utility routines for manipulating any type of PETSc object.
4 */
5 #include <petscsys.h>  /*I   "petscsys.h"    I*/
6 
7 PetscObject *PetscObjects = 0;
8 PetscInt    PetscObjectsCounts = 0, PetscObjectsMaxCounts = 0;
9 
10 extern PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm *);
11 extern PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject);
12 extern PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject *);
13 extern PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],const char[],void (*)(void));
14 extern PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void));
15 
16 #undef __FUNCT__
17 #define __FUNCT__ "PetscHeaderCreate_Private"
18 /*
19    PetscHeaderCreate_Private - Creates a base PETSc object header and fills
20    in the default values.  Called by the macro PetscHeaderCreate().
21 */
22 PetscErrorCode  PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,PetscInt type,const char class_name[],const char descr[],const char mansec[],
23                                           MPI_Comm comm,PetscErrorCode (*des)(PetscObject*),PetscErrorCode (*vie)(PetscObject,PetscViewer))
24 {
25   static PetscInt idcnt = 1;
26   PetscErrorCode  ierr;
27   PetscObject     *newPetscObjects;
28   PetscInt         newPetscObjectsMaxCounts,i;
29 
30   PetscFunctionBegin;
31   h->classid                = classid;
32   h->type                   = type;
33   h->class_name             = (char*)class_name;
34   h->description            = (char*)descr;
35   h->mansec                 = (char*)mansec;
36   h->prefix                 = 0;
37   h->refct                  = 1;
38   h->amem                   = -1;
39   h->id                     = idcnt++;
40   h->parentid               = 0;
41   h->qlist                  = 0;
42   h->olist                  = 0;
43   h->precision              = (PetscPrecision) sizeof(PetscScalar);
44   h->bops->destroy          = des;
45   h->bops->view             = vie;
46   h->bops->getcomm          = PetscObjectGetComm_Petsc;
47   h->bops->compose          = PetscObjectCompose_Petsc;
48   h->bops->query            = PetscObjectQuery_Petsc;
49   h->bops->composefunction  = PetscObjectComposeFunction_Petsc;
50   h->bops->queryfunction    = PetscObjectQueryFunction_Petsc;
51   ierr = PetscCommDuplicate(comm,&h->comm,&h->tag);CHKERRQ(ierr);
52 
53   /* Keep a record of object created */
54   PetscObjectsCounts++;
55   for (i=0; i<PetscObjectsMaxCounts; i++) {
56     if (!PetscObjects[i]) {
57       PetscObjects[i] = h;
58       PetscFunctionReturn(0);
59     }
60   }
61   /* Need to increase the space for storing PETSc objects */
62   if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100;
63   else                        newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts;
64   ierr = PetscMalloc(newPetscObjectsMaxCounts*sizeof(PetscObject),&newPetscObjects);CHKERRQ(ierr);
65   ierr = PetscMemcpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts*sizeof(PetscObject));CHKERRQ(ierr);
66   ierr = PetscMemzero(newPetscObjects+PetscObjectsMaxCounts,(newPetscObjectsMaxCounts - PetscObjectsMaxCounts)*sizeof(PetscObject));CHKERRQ(ierr);
67   ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
68   PetscObjects                        = newPetscObjects;
69   PetscObjects[PetscObjectsMaxCounts] = h;
70   PetscObjectsMaxCounts               = newPetscObjectsMaxCounts;
71 
72   PetscFunctionReturn(0);
73 }
74 
75 extern PetscBool      PetscMemoryCollectMaximumUsage;
76 extern PetscLogDouble PetscMemoryMaximumUsage;
77 
78 #undef __FUNCT__
79 #define __FUNCT__ "PetscHeaderDestroy_Private"
80 /*
81     PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
82     the macro PetscHeaderDestroy().
83 */
84 PetscErrorCode  PetscHeaderDestroy_Private(PetscObject h)
85 {
86   PetscErrorCode ierr;
87   PetscInt       i;
88 
89   PetscFunctionBegin;
90   PetscValidHeader(h,1);
91 #if defined(PETSC_HAVE_AMS)
92   if (PetscAMSPublishAll) {
93     ierr = PetscObjectUnPublish((PetscObject)h);CHKERRQ(ierr);
94   }
95 #endif
96   if (PetscMemoryCollectMaximumUsage) {
97     PetscLogDouble usage;
98     ierr = PetscMemoryGetCurrentUsage(&usage);CHKERRQ(ierr);
99     if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
100   }
101   /* first destroy things that could execute arbitrary code */
102   if (h->python_destroy) {
103     void           *python_context          = h->python_context;
104     PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
105     h->python_context = 0;
106     h->python_destroy = 0;
107     ierr = (*python_destroy)(python_context);CHKERRQ(ierr);
108   }
109   ierr = PetscOListDestroy(&h->olist);CHKERRQ(ierr);
110   ierr = PetscCommDestroy(&h->comm);CHKERRQ(ierr);
111   /* next destroy other things */
112   h->classid = PETSCFREEDHEADER;
113   ierr = PetscFree(h->bops);CHKERRQ(ierr);
114   ierr = PetscFListDestroy(&h->qlist);CHKERRQ(ierr);
115   ierr = PetscFree(h->type_name);CHKERRQ(ierr);
116   ierr = PetscFree(h->name);CHKERRQ(ierr);
117   ierr = PetscFree(h->prefix);CHKERRQ(ierr);
118   ierr = PetscFree(h->fortran_func_pointers);CHKERRQ(ierr);
119 
120   /* Record object removal from list of all objects */
121   for (i=0; i<PetscObjectsMaxCounts; i++) {
122     if (PetscObjects[i] == h) {
123       PetscObjects[i] = 0;
124       PetscObjectsCounts--;
125       break;
126     }
127   }
128   if (!PetscObjectsCounts) {
129     ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
130     PetscObjectsMaxCounts = 0;
131   }
132   PetscFunctionReturn(0);
133 }
134 
135 #undef __FUNCT__
136 #define __FUNCT__ "PetscObjectCopyFortranFunctionPointers"
137 /*@C
138    PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object
139 
140    Logically Collective on PetscObject
141 
142    Input Parameter:
143 +  src - source object
144 -  dest - destination object
145 
146    Level: developer
147 
148    Note:
149    Both objects must have the same class.
150 @*/
151 PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest)
152 {
153   PetscErrorCode ierr;
154 
155   PetscFunctionBegin;
156   PetscValidHeader(src,1);
157   PetscValidHeader(dest,2);
158   if (src->classid != dest->classid) SETERRQ(src->comm,PETSC_ERR_ARG_INCOMP,"Objects must be of the same class");
159 
160   ierr = PetscFree(dest->fortran_func_pointers);CHKERRQ(ierr);
161   ierr = PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);CHKERRQ(ierr);
162   ierr = PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));CHKERRQ(ierr);
163   dest->num_fortran_func_pointers = src->num_fortran_func_pointers;
164   PetscFunctionReturn(0);
165 }
166 
167 #undef __FUNCT__
168 #define __FUNCT__ "PetscObjectsView"
169 /*@C
170    PetscObjectsView - Prints the currently existing objects.
171 
172    Logically Collective on PetscViewer
173 
174    Input Parameter:
175 .  viewer - must be an PETSCVIEWERASCII viewer
176 
177    Level: advanced
178 
179    Concepts: options database^printing
180 
181 @*/
182 PetscErrorCode  PetscObjectsView(PetscViewer viewer)
183 {
184   PetscErrorCode ierr;
185   PetscInt       i;
186   PetscBool      isascii;
187   PetscObject    h;
188 
189   PetscFunctionBegin;
190   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
191   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
192   if (!isascii) SETERRQ(((PetscObject)viewer)->comm,PETSC_ERR_SUP,"Only supports ASCII viewer");
193 
194   for (i=0; i<PetscObjectsMaxCounts; i++) {
195     if ((h = PetscObjects[i])) {
196       ierr = PetscObjectName(h);CHKERRQ(ierr);
197       ierr = PetscViewerASCIIPrintf(viewer,"%s %s %s\n",h->class_name,h->type_name,h->name);CHKERRQ(ierr);
198     }
199   }
200   PetscFunctionReturn(0);
201 }
202 
203 #undef __FUNCT__
204 #define __FUNCT__ "PetscObjectsGetObject"
205 /*@C
206    PetscObjectsGetObject - Get a pointer to a named object
207 
208    Not collective
209 
210    Input Parameter:
211 .  name - the name of an object
212 
213    Output Parameter:
214 .   obj - the object or null if there is no object
215 
216    Level: advanced
217 
218    Concepts: options database^printing
219 
220 @*/
221 PetscErrorCode  PetscObjectsGetObject(const char* name,PetscObject *obj,char **classname)
222 {
223   PetscErrorCode ierr;
224   PetscInt       i;
225   PetscObject    h;
226   PetscBool      flg;
227 
228   PetscFunctionBegin;
229   *obj = PETSC_NULL;
230   for (i=0; i<PetscObjectsMaxCounts; i++) {
231     if ((h = PetscObjects[i])) {
232       ierr = PetscObjectName(h);CHKERRQ(ierr);
233       ierr = PetscStrcmp(h->name,name,&flg);CHKERRQ(ierr);
234       if (flg) {
235         *obj = h;
236         if (classname) *classname = h->class_name;
237         PetscFunctionReturn(0);
238       }
239     }
240   }
241   PetscFunctionReturn(0);
242 }
243 
244 #undef __FUNCT__
245 #define __FUNCT__ "PetscObjectsGetObjectMatlab"
246 char* PetscObjectsGetObjectMatlab(const char* name,PetscObject *obj)
247 {
248   PetscErrorCode ierr;
249   PetscInt       i;
250   PetscObject    h;
251   PetscBool      flg;
252 
253   PetscFunctionBegin;
254   *obj = PETSC_NULL;
255   for (i=0; i<PetscObjectsMaxCounts; i++) {
256     if ((h = PetscObjects[i])) {
257       ierr = PetscObjectName(h);if (ierr) PetscFunctionReturn(0);
258       ierr = PetscStrcmp(h->name,name,&flg);if (ierr) PetscFunctionReturn(0);
259       if (flg) {
260         *obj = h;
261         PetscFunctionReturn(h->class_name);
262       }
263     }
264   }
265   PetscFunctionReturn(0);
266 }
267 
268 #undef __FUNCT__
269 #define __FUNCT__ "PetscObjectAddOptionsHandler"
270 /*@C
271     PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
272 
273     Not Collective
274 
275     Input Parameter:
276 +   obj - the PETSc object
277 .   handle - function that checks for options
278 .   destroy - function to destroy context if provided
279 -   ctx - optional context for check function
280 
281     Level: developer
282 
283 
284 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()
285 
286 @*/
287 PetscErrorCode  PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
288 {
289   PetscFunctionBegin;
290   PetscValidHeader(obj,1);
291   if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
292   obj->optionhandler[obj->noptionhandler]   = handle;
293   obj->optiondestroy[obj->noptionhandler]   = destroy;
294   obj->optionctx[obj->noptionhandler++]     = ctx;
295   PetscFunctionReturn(0);
296 }
297 
298 #undef __FUNCT__
299 #define __FUNCT__ "PetscObjectProcessOptionsHandlers"
300 /*@C
301     PetscObjectProcessOptionsHandlers - Calls all the options handler attached to an object
302 
303     Not Collective
304 
305     Input Parameter:
306 .   obj - the PETSc object
307 
308     Level: developer
309 
310 
311 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()
312 
313 @*/
314 PetscErrorCode  PetscObjectProcessOptionsHandlers(PetscObject obj)
315 {
316   PetscInt       i;
317   PetscErrorCode ierr;
318 
319   PetscFunctionBegin;
320   PetscValidHeader(obj,1);
321   for (i=0; i<obj->noptionhandler; i++) {
322     ierr = (*obj->optionhandler[i])(obj,obj->optionctx[i]);CHKERRQ(ierr);
323   }
324   PetscFunctionReturn(0);
325 }
326 
327 #undef __FUNCT__
328 #define __FUNCT__ "PetscObjectDestroyOptionsHandlers"
329 /*@C
330     PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an objeft
331 
332     Not Collective
333 
334     Input Parameter:
335 .   obj - the PETSc object
336 
337     Level: developer
338 
339 
340 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
341 
342 @*/
343 PetscErrorCode  PetscObjectDestroyOptionsHandlers(PetscObject obj)
344 {
345   PetscInt       i;
346   PetscErrorCode ierr;
347 
348   PetscFunctionBegin;
349   PetscValidHeader(obj,1);
350   for (i=0; i<obj->noptionhandler; i++) {
351     ierr = (*obj->optiondestroy[i])(obj,obj->optionctx[i]);CHKERRQ(ierr);
352   }
353   obj->noptionhandler = 0;
354   PetscFunctionReturn(0);
355 }
356 
357 
358 #undef __FUNCT__
359 #define __FUNCT__ "PetscObjectReference"
360 /*@
361    PetscObjectReference - Indicates to any PetscObject that it is being
362    referenced by another PetscObject. This increases the reference
363    count for that object by one.
364 
365    Logically Collective on PetscObject
366 
367    Input Parameter:
368 .  obj - the PETSc object. This must be cast with (PetscObject), for example,
369          PetscObjectReference((PetscObject)mat);
370 
371    Level: advanced
372 
373 .seealso: PetscObjectCompose(), PetscObjectDereference()
374 @*/
375 PetscErrorCode  PetscObjectReference(PetscObject obj)
376 {
377   PetscFunctionBegin;
378   if (!obj) PetscFunctionReturn(0);
379   PetscValidHeader(obj,1);
380   obj->refct++;
381   PetscFunctionReturn(0);
382 }
383 
384 #undef __FUNCT__
385 #define __FUNCT__ "PetscObjectGetReference"
386 /*@
387    PetscObjectGetReference - Gets the current reference count for
388    any PETSc object.
389 
390    Not Collective
391 
392    Input Parameter:
393 .  obj - the PETSc object; this must be cast with (PetscObject), for example,
394          PetscObjectGetReference((PetscObject)mat,&cnt);
395 
396    Output Parameter:
397 .  cnt - the reference count
398 
399    Level: advanced
400 
401 .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
402 @*/
403 PetscErrorCode  PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
404 {
405   PetscFunctionBegin;
406   PetscValidHeader(obj,1);
407   PetscValidIntPointer(cnt,2);
408   *cnt = obj->refct;
409   PetscFunctionReturn(0);
410 }
411 
412 #undef __FUNCT__
413 #define __FUNCT__ "PetscObjectDereference"
414 /*@
415    PetscObjectDereference - Indicates to any PetscObject that it is being
416    referenced by one less PetscObject. This decreases the reference
417    count for that object by one.
418 
419    Collective on PetscObject if reference reaches 0 otherwise Logically Collective
420 
421    Input Parameter:
422 .  obj - the PETSc object; this must be cast with (PetscObject), for example,
423          PetscObjectDereference((PetscObject)mat);
424 
425    Notes: PetscObjectDestroy(PetscObject *obj)  sets the obj pointer to null after the call, this routine does not.
426 
427    Level: advanced
428 
429 .seealso: PetscObjectCompose(), PetscObjectReference()
430 @*/
431 PetscErrorCode  PetscObjectDereference(PetscObject obj)
432 {
433   PetscErrorCode ierr;
434 
435   PetscFunctionBegin;
436   PetscValidHeader(obj,1);
437   if (obj->bops->destroy) {
438     ierr = (*obj->bops->destroy)(&obj);CHKERRQ(ierr);
439   } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
440   PetscFunctionReturn(0);
441 }
442 
443 /* ----------------------------------------------------------------------- */
444 /*
445      The following routines are the versions private to the PETSc object
446      data structures.
447 */
448 #undef __FUNCT__
449 #define __FUNCT__ "PetscObjectGetComm_Petsc"
450 PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
451 {
452   PetscFunctionBegin;
453   PetscValidHeader(obj,1);
454   *comm = obj->comm;
455   PetscFunctionReturn(0);
456 }
457 
458 #undef __FUNCT__
459 #define __FUNCT__ "PetscObjectRemoveReference"
460 PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
461 {
462   PetscErrorCode ierr;
463 
464   PetscFunctionBegin;
465   PetscValidHeader(obj,1);
466   ierr = PetscOListRemoveReference(&obj->olist,name);CHKERRQ(ierr);
467   PetscFunctionReturn(0);
468 }
469 
470 #undef __FUNCT__
471 #define __FUNCT__ "PetscObjectCompose_Petsc"
472 PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
473 {
474   PetscErrorCode ierr;
475   char           *tname;
476   PetscBool      skipreference;
477 
478   PetscFunctionBegin;
479   if (ptr) {
480     ierr = PetscOListReverseFind(ptr->olist,obj,&tname,&skipreference);CHKERRQ(ierr);
481     if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
482   }
483   ierr = PetscOListAdd(&obj->olist,name,ptr);CHKERRQ(ierr);
484   PetscFunctionReturn(0);
485 }
486 
487 #undef __FUNCT__
488 #define __FUNCT__ "PetscObjectQuery_Petsc"
489 PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
490 {
491   PetscErrorCode ierr;
492 
493   PetscFunctionBegin;
494   PetscValidHeader(obj,1);
495   ierr = PetscOListFind(obj->olist,name,ptr);CHKERRQ(ierr);
496   PetscFunctionReturn(0);
497 }
498 
499 #undef __FUNCT__
500 #define __FUNCT__ "PetscObjectComposeFunction_Petsc"
501 PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
502 {
503   PetscErrorCode ierr;
504 
505   PetscFunctionBegin;
506   PetscValidHeader(obj,1);
507   ierr = PetscFListAdd(&obj->qlist,name,fname,ptr);CHKERRQ(ierr);
508   PetscFunctionReturn(0);
509 }
510 
511 #undef __FUNCT__
512 #define __FUNCT__ "PetscObjectQueryFunction_Petsc"
513 PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
514 {
515   PetscErrorCode ierr;
516 
517   PetscFunctionBegin;
518   PetscValidHeader(obj,1);
519   ierr = PetscFListFind(obj->qlist,obj->comm,name,PETSC_FALSE,ptr);CHKERRQ(ierr);
520   PetscFunctionReturn(0);
521 }
522 
523 #undef __FUNCT__
524 #define __FUNCT__ "PetscObjectCompose"
525 /*@C
526    PetscObjectCompose - Associates another PETSc object with a given PETSc object.
527 
528    Not Collective
529 
530    Input Parameters:
531 +  obj - the PETSc object; this must be cast with (PetscObject), for example,
532          PetscObjectCompose((PetscObject)mat,...);
533 .  name - name associated with the child object
534 -  ptr - the other PETSc object to associate with the PETSc object; this must also be
535          cast with (PetscObject)
536 
537    Level: advanced
538 
539    Notes:
540    The second objects reference count is automatically increased by one when it is
541    composed.
542 
543    Replaces any previous object that had the same name.
544 
545    If ptr is null and name has previously been composed using an object, then that
546    entry is removed from the obj.
547 
548    PetscObjectCompose() can be used with any PETSc object (such as
549    Mat, Vec, KSP, SNES, etc.) or any user-provided object.  See
550    PetscContainerCreate() for info on how to create an object from a
551    user-provided pointer that may then be composed with PETSc objects.
552 
553    Concepts: objects^composing
554    Concepts: composing objects
555 
556 .seealso: PetscObjectQuery(), PetscContainerCreate()
557 @*/
558 PetscErrorCode  PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
559 {
560   PetscErrorCode ierr;
561 
562   PetscFunctionBegin;
563   PetscValidHeader(obj,1);
564   PetscValidCharPointer(name,2);
565   if (ptr) PetscValidHeader(ptr,3);
566   ierr = (*obj->bops->compose)(obj,name,ptr);CHKERRQ(ierr);
567   PetscFunctionReturn(0);
568 }
569 
570 #undef __FUNCT__
571 #define __FUNCT__ "PetscObjectSetPrecision"
572 /*@C
573    PetscObjectSetPrecision - sets the precision used within a given object.
574 
575    Collective on the PetscObject
576 
577    Input Parameters:
578 +  obj - the PETSc object; this must be cast with (PetscObject), for example,
579          PetscObjectCompose((PetscObject)mat,...);
580 -  precision - the precision
581 
582    Level: advanced
583 
584 .seealso: PetscObjectQuery(), PetscContainerCreate()
585 @*/
586 PetscErrorCode  PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
587 {
588   PetscFunctionBegin;
589   PetscValidHeader(obj,1);
590   obj->precision = precision;
591   PetscFunctionReturn(0);
592 }
593 
594 #undef __FUNCT__
595 #define __FUNCT__ "PetscObjectQuery"
596 /*@C
597    PetscObjectQuery  - Gets a PETSc object associated with a given object.
598 
599    Not Collective
600 
601    Input Parameters:
602 +  obj - the PETSc object
603          Thus must be cast with a (PetscObject), for example,
604          PetscObjectCompose((PetscObject)mat,...);
605 .  name - name associated with child object
606 -  ptr - the other PETSc object associated with the PETSc object, this must be
607          cast with (PetscObject *)
608 
609    Level: advanced
610 
611    The reference count of neither object is increased in this call
612 
613    Concepts: objects^composing
614    Concepts: composing objects
615    Concepts: objects^querying
616    Concepts: querying objects
617 
618 .seealso: PetscObjectCompose()
619 @*/
620 PetscErrorCode  PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
621 {
622   PetscErrorCode ierr;
623 
624   PetscFunctionBegin;
625   PetscValidHeader(obj,1);
626   PetscValidCharPointer(name,2);
627   PetscValidPointer(ptr,3);
628   ierr = (*obj->bops->query)(obj,name,ptr);CHKERRQ(ierr);
629   PetscFunctionReturn(0);
630 }
631 
632 #undef __FUNCT__
633 #define __FUNCT__ "PetscObjectComposeFunction"
634 PetscErrorCode  PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
635 {
636   PetscErrorCode ierr;
637 
638   PetscFunctionBegin;
639   PetscValidHeader(obj,1);
640   PetscValidCharPointer(name,2);
641   ierr = (*obj->bops->composefunction)(obj,name,fname,ptr);CHKERRQ(ierr);
642   PetscFunctionReturn(0);
643 }
644 
645 #undef __FUNCT__
646 #define __FUNCT__ "PetscObjectQueryFunction"
647 /*@C
648    PetscObjectQueryFunction - Gets a function associated with a given object.
649 
650    Logically Collective on PetscObject
651 
652    Input Parameters:
653 +  obj - the PETSc object; this must be cast with (PetscObject), for example,
654          PetscObjectQueryFunction((PetscObject)ksp,...);
655 -  name - name associated with the child function
656 
657    Output Parameter:
658 .  ptr - function pointer
659 
660    Level: advanced
661 
662    Concepts: objects^composing functions
663    Concepts: composing functions
664    Concepts: functions^querying
665    Concepts: objects^querying
666    Concepts: querying objects
667 
668 .seealso: PetscObjectComposeFunctionDynamic()
669 @*/
670 PetscErrorCode  PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void))
671 {
672   PetscErrorCode ierr;
673 
674   PetscFunctionBegin;
675   PetscValidHeader(obj,1);
676   PetscValidCharPointer(name,2);
677   ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr);
678   PetscFunctionReturn(0);
679 }
680 
681 struct _p_PetscContainer {
682   PETSCHEADER(int);
683   void   *ptr;
684   PetscErrorCode (*userdestroy)(void*);
685 };
686 
687 #undef __FUNCT__
688 #define __FUNCT__ "PetscContainerGetPointer"
689 /*@C
690    PetscContainerGetPointer - Gets the pointer value contained in the container.
691 
692    Not Collective
693 
694    Input Parameter:
695 .  obj - the object created with PetscContainerCreate()
696 
697    Output Parameter:
698 .  ptr - the pointer value
699 
700    Level: advanced
701 
702 .seealso: PetscContainerCreate(), PetscContainerDestroy(),
703           PetscContainerSetPointer()
704 @*/
705 PetscErrorCode  PetscContainerGetPointer(PetscContainer obj,void **ptr)
706 {
707   PetscFunctionBegin;
708   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
709   PetscValidPointer(ptr,2);
710   *ptr = obj->ptr;
711   PetscFunctionReturn(0);
712 }
713 
714 
715 #undef __FUNCT__
716 #define __FUNCT__ "PetscContainerSetPointer"
717 /*@C
718    PetscContainerSetPointer - Sets the pointer value contained in the container.
719 
720    Logically Collective on PetscContainer
721 
722    Input Parameters:
723 +  obj - the object created with PetscContainerCreate()
724 -  ptr - the pointer value
725 
726    Level: advanced
727 
728 .seealso: PetscContainerCreate(), PetscContainerDestroy(),
729           PetscContainerGetPointer()
730 @*/
731 PetscErrorCode  PetscContainerSetPointer(PetscContainer obj,void *ptr)
732 {
733   PetscFunctionBegin;
734   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
735   if (ptr) PetscValidPointer(ptr,2);
736   obj->ptr = ptr;
737   PetscFunctionReturn(0);
738 }
739 
740 #undef __FUNCT__
741 #define __FUNCT__ "PetscContainerDestroy"
742 /*@C
743    PetscContainerDestroy - Destroys a PETSc container object.
744 
745    Collective on PetscContainer
746 
747    Input Parameter:
748 .  obj - an object that was created with PetscContainerCreate()
749 
750    Level: advanced
751 
752 .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
753 @*/
754 PetscErrorCode  PetscContainerDestroy(PetscContainer *obj)
755 {
756   PetscErrorCode ierr;
757   PetscFunctionBegin;
758   if (!*obj) PetscFunctionReturn(0);
759   PetscValidHeaderSpecific(*obj,PETSC_CONTAINER_CLASSID,1);
760   if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; PetscFunctionReturn(0);}
761   if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
762   ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr);
763   PetscFunctionReturn(0);
764 }
765 
766 #undef __FUNCT__
767 #define __FUNCT__ "PetscContainerSetUserDestroy"
768 /*@C
769    PetscContainerSetUserDestroy - Sets name of the user destroy function.
770 
771    Logically Collective on PetscContainer
772 
773    Input Parameter:
774 +  obj - an object that was created with PetscContainerCreate()
775 -  des - name of the user destroy function
776 
777    Level: advanced
778 
779 .seealso: PetscContainerDestroy()
780 @*/
781 PetscErrorCode  PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
782 {
783   PetscFunctionBegin;
784   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
785   obj->userdestroy = des;
786   PetscFunctionReturn(0);
787 }
788 
789 PetscClassId  PETSC_CONTAINER_CLASSID;
790 
791 #undef __FUNCT__
792 #define __FUNCT__ "PetscContainerCreate"
793 /*@C
794    PetscContainerCreate - Creates a PETSc object that has room to hold
795    a single pointer. This allows one to attach any type of data (accessible
796    through a pointer) with the PetscObjectCompose() function to a PetscObject.
797    The data item itself is attached by a call to PetscContainerSetPointer().
798 
799    Collective on MPI_Comm
800 
801    Input Parameters:
802 .  comm - MPI communicator that shares the object
803 
804    Output Parameters:
805 .  container - the container created
806 
807    Level: advanced
808 
809 .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
810 @*/
811 PetscErrorCode  PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
812 {
813   PetscErrorCode ierr;
814   PetscContainer contain;
815 
816   PetscFunctionBegin;
817   PetscValidPointer(container,2);
818   ierr = PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,0,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);CHKERRQ(ierr);
819   *container = contain;
820   PetscFunctionReturn(0);
821 }
822 
823 #undef __FUNCT__
824 #define __FUNCT__ "PetscObjectSetFromOptions"
825 /*@
826    PetscObjectSetFromOptions - Sets generic parameters from user options.
827 
828    Collective on obj
829 
830    Input Parameter:
831 .  obj - the PetscObjcet
832 
833    Options Database Keys:
834 
835    Notes:
836    We have no generic options at present, so this does nothing
837 
838    Level: beginner
839 
840 .keywords: set, options, database
841 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
842 @*/
843 PetscErrorCode  PetscObjectSetFromOptions(PetscObject obj)
844 {
845   PetscFunctionBegin;
846   PetscValidHeader(obj,1);
847   PetscFunctionReturn(0);
848 }
849 
850 #undef __FUNCT__
851 #define __FUNCT__ "PetscObjectSetUp"
852 /*@
853    PetscObjectSetUp - Sets up the internal data structures for the later use.
854 
855    Collective on PetscObject
856 
857    Input Parameters:
858 .  obj - the PetscObject
859 
860    Notes:
861    This does nothing at present.
862 
863    Level: advanced
864 
865 .keywords: setup
866 .seealso: PetscObjectDestroy()
867 @*/
868 PetscErrorCode  PetscObjectSetUp(PetscObject obj)
869 {
870   PetscFunctionBegin;
871   PetscValidHeader(obj,1);
872   PetscFunctionReturn(0);
873 }
874