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