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