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