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