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