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