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