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