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