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