xref: /petsc/src/sys/objects/inherit.c (revision 7d0a6c19129e7069c8a40e210b34ed62989173db)
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    Level: advanced
387 
388 .seealso: PetscObjectCompose(), PetscObjectReference()
389 @*/
390 PetscErrorCode  PetscObjectDereference(PetscObject obj)
391 {
392   PetscErrorCode ierr;
393 
394   PetscFunctionBegin;
395   PetscValidHeader(obj,1);
396   if (obj->bops->destroy) {
397     ierr = (*obj->bops->destroy)(obj);CHKERRQ(ierr);
398   } else if (!--obj->refct) {
399     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
400   }
401   PetscFunctionReturn(0);
402 }
403 
404 /* ----------------------------------------------------------------------- */
405 /*
406      The following routines are the versions private to the PETSc object
407      data structures.
408 */
409 #undef __FUNCT__
410 #define __FUNCT__ "PetscObjectGetComm_Petsc"
411 PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
412 {
413   PetscFunctionBegin;
414   *comm = obj->comm;
415   PetscFunctionReturn(0);
416 }
417 
418 #undef __FUNCT__
419 #define __FUNCT__ "PetscObjectCompose_Petsc"
420 PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
421 {
422   PetscErrorCode ierr;
423   char           *tname;
424 
425   PetscFunctionBegin;
426   if (ptr) {
427     ierr = PetscOListReverseFind(ptr->olist,obj,&tname);CHKERRQ(ierr);
428     if (tname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was compose with it");
429   }
430   ierr = PetscOListAdd(&obj->olist,name,ptr);CHKERRQ(ierr);
431   PetscFunctionReturn(0);
432 }
433 
434 #undef __FUNCT__
435 #define __FUNCT__ "PetscObjectQuery_Petsc"
436 PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
437 {
438   PetscErrorCode ierr;
439 
440   PetscFunctionBegin;
441   ierr = PetscOListFind(obj->olist,name,ptr);CHKERRQ(ierr);
442   PetscFunctionReturn(0);
443 }
444 
445 #undef __FUNCT__
446 #define __FUNCT__ "PetscObjectComposeFunction_Petsc"
447 PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
448 {
449   PetscErrorCode ierr;
450 
451   PetscFunctionBegin;
452   ierr = PetscFListAdd(&obj->qlist,name,fname,ptr);CHKERRQ(ierr);
453   PetscFunctionReturn(0);
454 }
455 
456 #undef __FUNCT__
457 #define __FUNCT__ "PetscObjectQueryFunction_Petsc"
458 PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
459 {
460   PetscErrorCode ierr;
461 
462   PetscFunctionBegin;
463   ierr = PetscFListFind(obj->qlist,obj->comm,name,ptr);CHKERRQ(ierr);
464   PetscFunctionReturn(0);
465 }
466 
467 #undef __FUNCT__
468 #define __FUNCT__ "PetscObjectCompose"
469 /*@C
470    PetscObjectCompose - Associates another PETSc object with a given PETSc object.
471 
472    Not Collective
473 
474    Input Parameters:
475 +  obj - the PETSc object; this must be cast with (PetscObject), for example,
476          PetscObjectCompose((PetscObject)mat,...);
477 .  name - name associated with the child object
478 -  ptr - the other PETSc object to associate with the PETSc object; this must also be
479          cast with (PetscObject)
480 
481    Level: advanced
482 
483    Notes:
484    The second objects reference count is automatically increased by one when it is
485    composed.
486 
487    Replaces any previous object that had the same name.
488 
489    If ptr is null and name has previously been composed using an object, then that
490    entry is removed from the obj.
491 
492    PetscObjectCompose() can be used with any PETSc object (such as
493    Mat, Vec, KSP, SNES, etc.) or any user-provided object.  See
494    PetscContainerCreate() for info on how to create an object from a
495    user-provided pointer that may then be composed with PETSc objects.
496 
497    Concepts: objects^composing
498    Concepts: composing objects
499 
500 .seealso: PetscObjectQuery(), PetscContainerCreate()
501 @*/
502 PetscErrorCode  PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
503 {
504   PetscErrorCode ierr;
505 
506   PetscFunctionBegin;
507   PetscValidHeader(obj,1);
508   PetscValidCharPointer(name,2);
509   if (ptr) PetscValidHeader(ptr,3);
510   ierr = (*obj->bops->compose)(obj,name,ptr);CHKERRQ(ierr);
511   PetscFunctionReturn(0);
512 }
513 
514 #undef __FUNCT__
515 #define __FUNCT__ "PetscObjectSetPrecision"
516 /*@C
517    PetscObjectSetPrecision - sets the precision used within a given object.
518 
519    Collective on the PetscObject
520 
521    Input Parameters:
522 +  obj - the PETSc object; this must be cast with (PetscObject), for example,
523          PetscObjectCompose((PetscObject)mat,...);
524 -  precision - the precision
525 
526    Level: advanced
527 
528 .seealso: PetscObjectQuery(), PetscContainerCreate()
529 @*/
530 PetscErrorCode  PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
531 {
532   PetscFunctionBegin;
533   PetscValidHeader(obj,1);
534   obj->precision = precision;
535   PetscFunctionReturn(0);
536 }
537 
538 #undef __FUNCT__
539 #define __FUNCT__ "PetscObjectQuery"
540 /*@C
541    PetscObjectQuery  - Gets a PETSc object associated with a given object.
542 
543    Not Collective
544 
545    Input Parameters:
546 +  obj - the PETSc object
547          Thus must be cast with a (PetscObject), for example,
548          PetscObjectCompose((PetscObject)mat,...);
549 .  name - name associated with child object
550 -  ptr - the other PETSc object associated with the PETSc object, this must also be
551          cast with (PetscObject)
552 
553    Level: advanced
554 
555    Concepts: objects^composing
556    Concepts: composing objects
557    Concepts: objects^querying
558    Concepts: querying objects
559 
560 .seealso: PetscObjectCompose()
561 @*/
562 PetscErrorCode  PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
563 {
564   PetscErrorCode ierr;
565 
566   PetscFunctionBegin;
567   PetscValidHeader(obj,1);
568   PetscValidCharPointer(name,2);
569   PetscValidPointer(ptr,3);
570   ierr = (*obj->bops->query)(obj,name,ptr);CHKERRQ(ierr);
571   PetscFunctionReturn(0);
572 }
573 
574 #undef __FUNCT__
575 #define __FUNCT__ "PetscObjectComposeFunction"
576 PetscErrorCode  PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
577 {
578   PetscErrorCode ierr;
579 
580   PetscFunctionBegin;
581   PetscValidHeader(obj,1);
582   PetscValidCharPointer(name,2);
583   PetscValidCharPointer(fname,3);
584   ierr = (*obj->bops->composefunction)(obj,name,fname,ptr);CHKERRQ(ierr);
585   PetscFunctionReturn(0);
586 }
587 
588 #undef __FUNCT__
589 #define __FUNCT__ "PetscObjectQueryFunction"
590 /*@C
591    PetscObjectQueryFunction - Gets a function associated with a given object.
592 
593    Logically Collective on PetscObject
594 
595    Input Parameters:
596 +  obj - the PETSc object; this must be cast with (PetscObject), for example,
597          PetscObjectQueryFunction((PetscObject)ksp,...);
598 -  name - name associated with the child function
599 
600    Output Parameter:
601 .  ptr - function pointer
602 
603    Level: advanced
604 
605    Concepts: objects^composing functions
606    Concepts: composing functions
607    Concepts: functions^querying
608    Concepts: objects^querying
609    Concepts: querying objects
610 
611 .seealso: PetscObjectComposeFunctionDynamic()
612 @*/
613 PetscErrorCode  PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void))
614 {
615   PetscErrorCode ierr;
616 
617   PetscFunctionBegin;
618   PetscValidHeader(obj,1);
619   PetscValidCharPointer(name,2);
620   ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr);
621   PetscFunctionReturn(0);
622 }
623 
624 struct _p_PetscContainer {
625   PETSCHEADER(int);
626   void   *ptr;
627   PetscErrorCode (*userdestroy)(void*);
628 };
629 
630 #undef __FUNCT__
631 #define __FUNCT__ "PetscContainerGetPointer"
632 /*@C
633    PetscContainerGetPointer - Gets the pointer value contained in the container.
634 
635    Not Collective
636 
637    Input Parameter:
638 .  obj - the object created with PetscContainerCreate()
639 
640    Output Parameter:
641 .  ptr - the pointer value
642 
643    Level: advanced
644 
645 .seealso: PetscContainerCreate(), PetscContainerDestroy(),
646           PetscContainerSetPointer()
647 @*/
648 PetscErrorCode  PetscContainerGetPointer(PetscContainer obj,void **ptr)
649 {
650   PetscFunctionBegin;
651   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
652   PetscValidPointer(ptr,2);
653   *ptr = obj->ptr;
654   PetscFunctionReturn(0);
655 }
656 
657 
658 #undef __FUNCT__
659 #define __FUNCT__ "PetscContainerSetPointer"
660 /*@C
661    PetscContainerSetPointer - Sets the pointer value contained in the container.
662 
663    Logically Collective on PetscContainer
664 
665    Input Parameters:
666 +  obj - the object created with PetscContainerCreate()
667 -  ptr - the pointer value
668 
669    Level: advanced
670 
671 .seealso: PetscContainerCreate(), PetscContainerDestroy(),
672           PetscContainerGetPointer()
673 @*/
674 PetscErrorCode  PetscContainerSetPointer(PetscContainer obj,void *ptr)
675 {
676   PetscFunctionBegin;
677   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
678   if (ptr) PetscValidPointer(ptr,2);
679   obj->ptr = ptr;
680   PetscFunctionReturn(0);
681 }
682 
683 #undef __FUNCT__
684 #define __FUNCT__ "PetscContainerDestroy"
685 /*@C
686    PetscContainerDestroy - Destroys a PETSc container object.
687 
688    Collective on PetscContainer
689 
690    Input Parameter:
691 .  obj - an object that was created with PetscContainerCreate()
692 
693    Level: advanced
694 
695 .seealso: PetscContainerCreate()
696 @*/
697 PetscErrorCode  PetscContainerDestroy(PetscContainer obj)
698 {
699   PetscErrorCode ierr;
700   PetscFunctionBegin;
701   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
702   if (--((PetscObject)obj)->refct > 0) PetscFunctionReturn(0);
703   if (obj->userdestroy) (*obj->userdestroy)(obj->ptr);
704   ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr);
705   PetscFunctionReturn(0);
706 }
707 
708 #undef __FUNCT__
709 #define __FUNCT__ "PetscContainerSetUserDestroy"
710 /*@C
711    PetscContainerSetUserDestroy - Sets name of the user destroy function.
712 
713    Logically Collective on PetscContainer
714 
715    Input Parameter:
716 +  obj - an object that was created with PetscContainerCreate()
717 -  des - name of the user destroy function
718 
719    Level: advanced
720 
721 .seealso: PetscContainerDestroy()
722 @*/
723 PetscErrorCode  PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
724 {
725   PetscFunctionBegin;
726   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
727   obj->userdestroy = des;
728   PetscFunctionReturn(0);
729 }
730 
731 PetscClassId  PETSC_CONTAINER_CLASSID;
732 
733 #undef __FUNCT__
734 #define __FUNCT__ "PetscContainerCreate"
735 /*@C
736    PetscContainerCreate - Creates a PETSc object that has room to hold
737    a single pointer. This allows one to attach any type of data (accessible
738    through a pointer) with the PetscObjectCompose() function to a PetscObject.
739    The data item itself is attached by a call to PetscContainerSetPointer.
740 
741    Collective on MPI_Comm
742 
743    Input Parameters:
744 .  comm - MPI communicator that shares the object
745 
746    Output Parameters:
747 .  container - the container created
748 
749    Level: advanced
750 
751 .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
752 @*/
753 PetscErrorCode  PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
754 {
755   PetscErrorCode ierr;
756   PetscContainer contain;
757 
758   PetscFunctionBegin;
759   PetscValidPointer(container,2);
760   ierr = PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,0,"PetscContainer",comm,PetscContainerDestroy,0);CHKERRQ(ierr);
761   *container = contain;
762   PetscFunctionReturn(0);
763 }
764 
765 #undef __FUNCT__
766 #define __FUNCT__ "PetscObjectSetFromOptions"
767 /*@
768    PetscObjectSetFromOptions - Sets generic parameters from user options.
769 
770    Collective on obj
771 
772    Input Parameter:
773 .  obj - the PetscObjcet
774 
775    Options Database Keys:
776 
777    Notes:
778    We have no generic options at present, so this does nothing
779 
780    Level: beginner
781 
782 .keywords: set, options, database
783 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
784 @*/
785 PetscErrorCode  PetscObjectSetFromOptions(PetscObject obj)
786 {
787   PetscFunctionBegin;
788   PetscValidHeader(obj,1);
789   PetscFunctionReturn(0);
790 }
791 
792 #undef __FUNCT__
793 #define __FUNCT__ "PetscObjectSetUp"
794 /*@
795    PetscObjectSetUp - Sets up the internal data structures for the later use.
796 
797    Collective on PetscObject
798 
799    Input Parameters:
800 .  obj - the PetscObject
801 
802    Notes:
803    This does nothing at present.
804 
805    Level: advanced
806 
807 .keywords: setup
808 .seealso: PetscObjectDestroy()
809 @*/
810 PetscErrorCode  PetscObjectSetUp(PetscObject obj)
811 {
812   PetscFunctionBegin;
813   PetscValidHeader(obj,1);
814   PetscFunctionReturn(0);
815 }
816