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