xref: /petsc/src/sys/objects/inherit.c (revision 95c0884e6f7665b705eebf88174e89dc920c2fc0)
1 
2 /*
3      Provides utility routines for manipulating any type of PETSc object.
4 */
5 #include <petsc/private/petscimpl.h>  /*I   "petscsys.h"    I*/
6 #include <petscviewer.h>
7 
8 #if defined(PETSC_USE_LOG)
9 PETSC_INTERN PetscObject *PetscObjects;
10 PETSC_INTERN PetscInt    PetscObjectsCounts, PetscObjectsMaxCounts;
11 PETSC_INTERN PetscBool   PetscObjectsLog;
12 #endif
13 
14 #if defined(PETSC_USE_LOG)
15 PetscObject *PetscObjects      = 0;
16 PetscInt    PetscObjectsCounts = 0, PetscObjectsMaxCounts = 0;
17 PetscBool   PetscObjectsLog    = PETSC_FALSE;
18 #endif
19 
20 PETSC_EXTERN PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm*);
21 PETSC_EXTERN PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject);
22 PETSC_EXTERN PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject*);
23 PETSC_EXTERN PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],void (*)(void));
24 PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void));
25 
26 /*
27    PetscHeaderCreate_Private - Creates a base PETSc object header and fills
28    in the default values.  Called by the macro PetscHeaderCreate().
29 */
30 PetscErrorCode  PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,const char class_name[],const char descr[],const char mansec[],
31                                           MPI_Comm comm,PetscObjectDestroyFunction destroy,PetscObjectViewFunction view)
32 {
33   static PetscInt idcnt = 1;
34   PetscErrorCode  ierr;
35 #if defined(PETSC_USE_LOG)
36   PetscObject     *newPetscObjects;
37   PetscInt         newPetscObjectsMaxCounts,i;
38 #endif
39 
40   PetscFunctionBegin;
41   h->classid               = classid;
42   h->type                  = 0;
43   h->class_name            = (char*)class_name;
44   h->description           = (char*)descr;
45   h->mansec                = (char*)mansec;
46   h->prefix                = 0;
47   h->refct                 = 1;
48 #if defined(PETSC_HAVE_SAWS)
49   h->amsmem                = PETSC_FALSE;
50 #endif
51   h->id                    = idcnt++;
52   h->parentid              = 0;
53   h->qlist                 = 0;
54   h->olist                 = 0;
55   h->bops->destroy         = destroy;
56   h->bops->view            = view;
57   h->bops->getcomm         = PetscObjectGetComm_Petsc;
58   h->bops->compose         = PetscObjectCompose_Petsc;
59   h->bops->query           = PetscObjectQuery_Petsc;
60   h->bops->composefunction = PetscObjectComposeFunction_Petsc;
61   h->bops->queryfunction   = PetscObjectQueryFunction_Petsc;
62 
63   ierr = PetscCommDuplicate(comm,&h->comm,&h->tag);CHKERRQ(ierr);
64 
65 #if defined(PETSC_USE_LOG)
66   /* Keep a record of object created */
67   if (PetscObjectsLog) {
68     PetscObjectsCounts++;
69     for (i=0; i<PetscObjectsMaxCounts; i++) {
70       if (!PetscObjects[i]) {
71         PetscObjects[i] = h;
72         PetscFunctionReturn(0);
73       }
74     }
75     /* Need to increase the space for storing PETSc objects */
76     if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100;
77     else                        newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts;
78     ierr = PetscMalloc1(newPetscObjectsMaxCounts,&newPetscObjects);CHKERRQ(ierr);
79     ierr = PetscMemcpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts*sizeof(PetscObject));CHKERRQ(ierr);
80     ierr = PetscMemzero(newPetscObjects+PetscObjectsMaxCounts,(newPetscObjectsMaxCounts - PetscObjectsMaxCounts)*sizeof(PetscObject));CHKERRQ(ierr);
81     ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
82 
83     PetscObjects                        = newPetscObjects;
84     PetscObjects[PetscObjectsMaxCounts] = h;
85     PetscObjectsMaxCounts               = newPetscObjectsMaxCounts;
86   }
87 #endif
88   PetscFunctionReturn(0);
89 }
90 
91 PETSC_INTERN PetscBool      PetscMemoryCollectMaximumUsage;
92 PETSC_INTERN PetscLogDouble PetscMemoryMaximumUsage;
93 
94 /*
95     PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
96     the macro PetscHeaderDestroy().
97 */
98 PetscErrorCode  PetscHeaderDestroy_Private(PetscObject h)
99 {
100   PetscErrorCode ierr;
101 
102   PetscFunctionBegin;
103   PetscValidHeader(h,1);
104   ierr = PetscLogObjectDestroy(h);CHKERRQ(ierr);
105   ierr = PetscComposedQuantitiesDestroy(h);CHKERRQ(ierr);
106   if (PetscMemoryCollectMaximumUsage) {
107     PetscLogDouble usage;
108     ierr = PetscMemoryGetCurrentUsage(&usage);CHKERRQ(ierr);
109     if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
110   }
111   /* first destroy things that could execute arbitrary code */
112   if (h->python_destroy) {
113     void           *python_context = h->python_context;
114     PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
115     h->python_context = 0;
116     h->python_destroy = 0;
117 
118     ierr = (*python_destroy)(python_context);CHKERRQ(ierr);
119   }
120   ierr = PetscObjectDestroyOptionsHandlers(h);CHKERRQ(ierr);
121   ierr = PetscObjectListDestroy(&h->olist);CHKERRQ(ierr);
122   ierr = PetscCommDestroy(&h->comm);CHKERRQ(ierr);
123   /* next destroy other things */
124   h->classid = PETSCFREEDHEADER;
125 
126   ierr = PetscFunctionListDestroy(&h->qlist);CHKERRQ(ierr);
127   ierr = PetscFree(h->type_name);CHKERRQ(ierr);
128   ierr = PetscFree(h->name);CHKERRQ(ierr);
129   ierr = PetscFree(h->prefix);CHKERRQ(ierr);
130   ierr = PetscFree(h->fortran_func_pointers);CHKERRQ(ierr);
131   ierr = PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_CLASS]);CHKERRQ(ierr);
132   ierr = PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_SUBTYPE]);CHKERRQ(ierr);
133 
134 #if defined(PETSC_USE_LOG)
135   if (PetscObjectsLog) {
136     PetscInt i;
137     /* Record object removal from list of all objects */
138     for (i=0; i<PetscObjectsMaxCounts; i++) {
139       if (PetscObjects[i] == h) {
140         PetscObjects[i] = 0;
141         PetscObjectsCounts--;
142         break;
143       }
144     }
145     if (!PetscObjectsCounts) {
146       ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
147       PetscObjectsMaxCounts = 0;
148     }
149   }
150 #endif
151   PetscFunctionReturn(0);
152 }
153 
154 /*@C
155    PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object
156 
157    Logically Collective on PetscObject
158 
159    Input Parameter:
160 +  src - source object
161 -  dest - destination object
162 
163    Level: developer
164 
165    Note:
166    Both objects must have the same class.
167 @*/
168 PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest)
169 {
170   PetscErrorCode ierr;
171   PetscInt       cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE];
172 
173   PetscFunctionBegin;
174   PetscValidHeader(src,1);
175   PetscValidHeader(dest,2);
176   if (src->classid != dest->classid) SETERRQ(src->comm,PETSC_ERR_ARG_INCOMP,"Objects must be of the same class");
177 
178   ierr = PetscFree(dest->fortran_func_pointers);CHKERRQ(ierr);
179   ierr = PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);CHKERRQ(ierr);
180   ierr = PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));CHKERRQ(ierr);
181 
182   dest->num_fortran_func_pointers = src->num_fortran_func_pointers;
183 
184   ierr = PetscFortranCallbackGetSizes(src->classid,&numcb[PETSC_FORTRAN_CALLBACK_CLASS],&numcb[PETSC_FORTRAN_CALLBACK_SUBTYPE]);CHKERRQ(ierr);
185   for (cbtype=PETSC_FORTRAN_CALLBACK_CLASS; cbtype<PETSC_FORTRAN_CALLBACK_MAXTYPE; cbtype++) {
186     ierr = PetscFree(dest->fortrancallback[cbtype]);CHKERRQ(ierr);
187     ierr = PetscCalloc1(numcb[cbtype],&dest->fortrancallback[cbtype]);CHKERRQ(ierr);
188     ierr = PetscMemcpy(dest->fortrancallback[cbtype],src->fortrancallback[cbtype],src->num_fortrancallback[cbtype]*sizeof(PetscFortranCallback));CHKERRQ(ierr);
189     dest->num_fortrancallback[cbtype] = src->num_fortrancallback[cbtype];
190   }
191   PetscFunctionReturn(0);
192 }
193 
194 /*@C
195    PetscObjectSetFortranCallback - set fortran callback function pointer and context
196 
197    Logically Collective
198 
199    Input Arguments:
200 +  obj - object on which to set callback
201 .  cbtype - callback type (class or subtype)
202 .  cid - address of callback Id, updated if not yet initialized (zero)
203 .  func - Fortran function
204 -  ctx - Fortran context
205 
206    Level: developer
207 
208 .seealso: PetscObjectGetFortranCallback()
209 @*/
210 PetscErrorCode PetscObjectSetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId *cid,void (*func)(void),void *ctx)
211 {
212   PetscErrorCode ierr;
213   const char     *subtype = NULL;
214 
215   PetscFunctionBegin;
216   PetscValidHeader(obj,1);
217   if (cbtype == PETSC_FORTRAN_CALLBACK_SUBTYPE) subtype = obj->type_name;
218   if (!*cid) {ierr = PetscFortranCallbackRegister(obj->classid,subtype,cid);CHKERRQ(ierr);}
219   if (*cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype]) {
220     PetscInt             oldnum = obj->num_fortrancallback[cbtype],newnum = PetscMax(1,2*oldnum);
221     PetscFortranCallback *callback;
222     ierr = PetscMalloc1(newnum,&callback);CHKERRQ(ierr);
223     ierr = PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));CHKERRQ(ierr);
224     ierr = PetscFree(obj->fortrancallback[cbtype]);CHKERRQ(ierr);
225 
226     obj->fortrancallback[cbtype] = callback;
227     obj->num_fortrancallback[cbtype] = newnum;
228   }
229   obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func;
230   obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx;
231   PetscFunctionReturn(0);
232 }
233 
234 /*@C
235    PetscObjectGetFortranCallback - get fortran callback function pointer and context
236 
237    Logically Collective
238 
239    Input Arguments:
240 +  obj - object on which to get callback
241 .  cbtype - callback type
242 -  cid - address of callback Id
243 
244    Output Arguments:
245 +  func - Fortran function (or NULL if not needed)
246 -  ctx - Fortran context (or NULL if not needed)
247 
248    Level: developer
249 
250 .seealso: PetscObjectSetFortranCallback()
251 @*/
252 PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx)
253 {
254   PetscFortranCallback *cb;
255 
256   PetscFunctionBegin;
257   PetscValidHeader(obj,1);
258   if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid");
259   if (PetscUnlikely(cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype])) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback not set on this object");
260   cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK];
261   if (func) *func = cb->func;
262   if (ctx) *ctx = cb->ctx;
263   PetscFunctionReturn(0);
264 }
265 
266 #if defined(PETSC_USE_LOG)
267 /*@C
268    PetscObjectsDump - Prints the currently existing objects.
269 
270    Logically Collective on PetscViewer
271 
272    Input Parameter:
273 +  fd - file pointer
274 -  all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects
275 
276    Options Database:
277 .  -objects_dump <all>
278 
279    Level: advanced
280 
281    Concepts: options database^printing
282 
283 @*/
284 PetscErrorCode  PetscObjectsDump(FILE *fd,PetscBool all)
285 {
286   PetscErrorCode ierr;
287   PetscInt       i;
288 #if defined(PETSC_USE_DEBUG)
289   PetscInt       j,k=0;
290 #endif
291   PetscObject    h;
292 
293   PetscFunctionBegin;
294   if (PetscObjectsCounts) {
295     ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");CHKERRQ(ierr);
296     ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");CHKERRQ(ierr);
297     for (i=0; i<PetscObjectsMaxCounts; i++) {
298       if ((h = PetscObjects[i])) {
299         ierr = PetscObjectName(h);CHKERRQ(ierr);
300         {
301 #if defined(PETSC_USE_DEBUG)
302         PetscStack *stack = 0;
303         char       *create,*rclass;
304 
305         /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */
306         ierr = PetscMallocGetStack(h,&stack);CHKERRQ(ierr);
307         if (stack) {
308           k = stack->currentsize-2;
309           if (!all) {
310             k = 0;
311             while (!stack->petscroutine[k]) k++;
312             ierr = PetscStrstr(stack->function[k],"Create",&create);CHKERRQ(ierr);
313             if (!create) {
314               ierr = PetscStrstr(stack->function[k],"Get",&create);CHKERRQ(ierr);
315             }
316             ierr = PetscStrstr(stack->function[k],h->class_name,&rclass);CHKERRQ(ierr);
317             if (!create) continue;
318             if (!rclass) continue;
319           }
320         }
321 #endif
322 
323         ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);CHKERRQ(ierr);
324 
325 #if defined(PETSC_USE_DEBUG)
326         ierr = PetscMallocGetStack(h,&stack);CHKERRQ(ierr);
327         if (stack) {
328           for (j=k; j>=0; j--) {
329             fprintf(fd,"      [%d]  %s() in %s\n",PetscGlobalRank,stack->function[j],stack->file[j]);
330           }
331         }
332 #endif
333         }
334       }
335     }
336   }
337   PetscFunctionReturn(0);
338 }
339 #endif
340 
341 #if defined(PETSC_USE_LOG)
342 
343 /*@C
344    PetscObjectsView - Prints the currently existing objects.
345 
346    Logically Collective on PetscViewer
347 
348    Input Parameter:
349 .  viewer - must be an PETSCVIEWERASCII viewer
350 
351    Level: advanced
352 
353    Concepts: options database^printing
354 
355 @*/
356 PetscErrorCode  PetscObjectsView(PetscViewer viewer)
357 {
358   PetscErrorCode ierr;
359   PetscBool      isascii;
360   FILE           *fd;
361 
362   PetscFunctionBegin;
363   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
364   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
365   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
366   ierr = PetscViewerASCIIGetPointer(viewer,&fd);CHKERRQ(ierr);
367   ierr = PetscObjectsDump(fd,PETSC_TRUE);CHKERRQ(ierr);
368   PetscFunctionReturn(0);
369 }
370 
371 /*@C
372    PetscObjectsGetObject - Get a pointer to a named object
373 
374    Not collective
375 
376    Input Parameter:
377 .  name - the name of an object
378 
379    Output Parameter:
380 .   obj - the object or null if there is no object
381 
382    Level: advanced
383 
384    Concepts: options database^printing
385 
386 @*/
387 PetscErrorCode  PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
388 {
389   PetscErrorCode ierr;
390   PetscInt       i;
391   PetscObject    h;
392   PetscBool      flg;
393 
394   PetscFunctionBegin;
395   *obj = NULL;
396   for (i=0; i<PetscObjectsMaxCounts; i++) {
397     if ((h = PetscObjects[i])) {
398       ierr = PetscObjectName(h);CHKERRQ(ierr);
399       ierr = PetscStrcmp(h->name,name,&flg);CHKERRQ(ierr);
400       if (flg) {
401         *obj = h;
402         if (classname) *classname = h->class_name;
403         PetscFunctionReturn(0);
404       }
405     }
406   }
407   PetscFunctionReturn(0);
408 }
409 #endif
410 
411 /*@C
412     PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
413 
414     Not Collective
415 
416     Input Parameter:
417 +   obj - the PETSc object
418 .   handle - function that checks for options
419 .   destroy - function to destroy context if provided
420 -   ctx - optional context for check function
421 
422     Level: developer
423 
424 
425 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()
426 
427 @*/
428 PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscOptionItems*,PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
429 {
430   PetscFunctionBegin;
431   PetscValidHeader(obj,1);
432   if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
433   obj->optionhandler[obj->noptionhandler] = handle;
434   obj->optiondestroy[obj->noptionhandler] = destroy;
435   obj->optionctx[obj->noptionhandler++]   = ctx;
436   PetscFunctionReturn(0);
437 }
438 
439 /*@C
440     PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object
441 
442     Not Collective
443 
444     Input Parameter:
445 .   obj - the PETSc object
446 
447     Level: developer
448 
449 
450 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()
451 
452 @*/
453 PetscErrorCode  PetscObjectProcessOptionsHandlers(PetscOptionItems *PetscOptionsObject,PetscObject obj)
454 {
455   PetscInt       i;
456   PetscErrorCode ierr;
457 
458   PetscFunctionBegin;
459   PetscValidHeader(obj,1);
460   for (i=0; i<obj->noptionhandler; i++) {
461     ierr = (*obj->optionhandler[i])(PetscOptionsObject,obj,obj->optionctx[i]);CHKERRQ(ierr);
462   }
463   PetscFunctionReturn(0);
464 }
465 
466 /*@C
467     PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object
468 
469     Not Collective
470 
471     Input Parameter:
472 .   obj - the PETSc object
473 
474     Level: developer
475 
476 
477 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
478 
479 @*/
480 PetscErrorCode  PetscObjectDestroyOptionsHandlers(PetscObject obj)
481 {
482   PetscInt       i;
483   PetscErrorCode ierr;
484 
485   PetscFunctionBegin;
486   PetscValidHeader(obj,1);
487   for (i=0; i<obj->noptionhandler; i++) {
488     if (obj->optiondestroy[i]) {
489       ierr = (*obj->optiondestroy[i])(obj,obj->optionctx[i]);CHKERRQ(ierr);
490     }
491   }
492   obj->noptionhandler = 0;
493   PetscFunctionReturn(0);
494 }
495 
496 
497 /*@C
498    PetscObjectReference - Indicates to any PetscObject that it is being
499    referenced by another PetscObject. This increases the reference
500    count for that object by one.
501 
502    Logically Collective on PetscObject
503 
504    Input Parameter:
505 .  obj - the PETSc object. This must be cast with (PetscObject), for example,
506          PetscObjectReference((PetscObject)mat);
507 
508    Level: advanced
509 
510 .seealso: PetscObjectCompose(), PetscObjectDereference()
511 @*/
512 PetscErrorCode  PetscObjectReference(PetscObject obj)
513 {
514   PetscFunctionBegin;
515   if (!obj) PetscFunctionReturn(0);
516   PetscValidHeader(obj,1);
517   obj->refct++;
518   PetscFunctionReturn(0);
519 }
520 
521 /*@C
522    PetscObjectGetReference - Gets the current reference count for
523    any PETSc object.
524 
525    Not Collective
526 
527    Input Parameter:
528 .  obj - the PETSc object; this must be cast with (PetscObject), for example,
529          PetscObjectGetReference((PetscObject)mat,&cnt);
530 
531    Output Parameter:
532 .  cnt - the reference count
533 
534    Level: advanced
535 
536 .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
537 @*/
538 PetscErrorCode  PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
539 {
540   PetscFunctionBegin;
541   PetscValidHeader(obj,1);
542   PetscValidIntPointer(cnt,2);
543   *cnt = obj->refct;
544   PetscFunctionReturn(0);
545 }
546 
547 /*@C
548    PetscObjectDereference - Indicates to any PetscObject that it is being
549    referenced by one less PetscObject. This decreases the reference
550    count for that object by one.
551 
552    Collective on PetscObject if reference reaches 0 otherwise Logically Collective
553 
554    Input Parameter:
555 .  obj - the PETSc object; this must be cast with (PetscObject), for example,
556          PetscObjectDereference((PetscObject)mat);
557 
558    Notes:
559     PetscObjectDestroy(PetscObject *obj)  sets the obj pointer to null after the call, this routine does not.
560 
561    Level: advanced
562 
563 .seealso: PetscObjectCompose(), PetscObjectReference()
564 @*/
565 PetscErrorCode  PetscObjectDereference(PetscObject obj)
566 {
567   PetscErrorCode ierr;
568 
569   PetscFunctionBegin;
570   if (!obj) PetscFunctionReturn(0);
571   PetscValidHeader(obj,1);
572   if (obj->bops->destroy) {
573     ierr = (*obj->bops->destroy)(&obj);CHKERRQ(ierr);
574   } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
575   PetscFunctionReturn(0);
576 }
577 
578 /* ----------------------------------------------------------------------- */
579 /*
580      The following routines are the versions private to the PETSc object
581      data structures.
582 */
583 PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
584 {
585   PetscFunctionBegin;
586   PetscValidHeader(obj,1);
587   *comm = obj->comm;
588   PetscFunctionReturn(0);
589 }
590 
591 PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
592 {
593   PetscErrorCode ierr;
594 
595   PetscFunctionBegin;
596   PetscValidHeader(obj,1);
597   ierr = PetscObjectListRemoveReference(&obj->olist,name);CHKERRQ(ierr);
598   PetscFunctionReturn(0);
599 }
600 
601 PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
602 {
603   PetscErrorCode ierr;
604   char           *tname;
605   PetscBool      skipreference;
606 
607   PetscFunctionBegin;
608   if (ptr) {
609     ierr = PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);CHKERRQ(ierr);
610     if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
611   }
612   ierr = PetscObjectListAdd(&obj->olist,name,ptr);CHKERRQ(ierr);
613   PetscFunctionReturn(0);
614 }
615 
616 PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
617 {
618   PetscErrorCode ierr;
619 
620   PetscFunctionBegin;
621   PetscValidHeader(obj,1);
622   ierr = PetscObjectListFind(obj->olist,name,ptr);CHKERRQ(ierr);
623   PetscFunctionReturn(0);
624 }
625 
626 PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
627 {
628   PetscErrorCode ierr;
629 
630   PetscFunctionBegin;
631   PetscValidHeader(obj,1);
632   ierr = PetscFunctionListAdd(&obj->qlist,name,ptr);CHKERRQ(ierr);
633   PetscFunctionReturn(0);
634 }
635 
636 PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
637 {
638   PetscErrorCode ierr;
639 
640   PetscFunctionBegin;
641   PetscValidHeader(obj,1);
642   ierr = PetscFunctionListFind(obj->qlist,name,ptr);CHKERRQ(ierr);
643   PetscFunctionReturn(0);
644 }
645 
646 /*@C
647    PetscObjectCompose - Associates another PETSc object with a given PETSc object.
648 
649    Not Collective
650 
651    Input Parameters:
652 +  obj - the PETSc object; this must be cast with (PetscObject), for example,
653          PetscObjectCompose((PetscObject)mat,...);
654 .  name - name associated with the child object
655 -  ptr - the other PETSc object to associate with the PETSc object; this must also be
656          cast with (PetscObject)
657 
658    Level: advanced
659 
660    Notes:
661    The second objects reference count is automatically increased by one when it is
662    composed.
663 
664    Replaces any previous object that had the same name.
665 
666    If ptr is null and name has previously been composed using an object, then that
667    entry is removed from the obj.
668 
669    PetscObjectCompose() can be used with any PETSc object (such as
670    Mat, Vec, KSP, SNES, etc.) or any user-provided object.  See
671    PetscContainerCreate() for info on how to create an object from a
672    user-provided pointer that may then be composed with PETSc objects.
673 
674    Concepts: objects^composing
675    Concepts: composing objects
676 
677 .seealso: PetscObjectQuery(), PetscContainerCreate()
678 @*/
679 PetscErrorCode  PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
680 {
681   PetscErrorCode ierr;
682 
683   PetscFunctionBegin;
684   PetscValidHeader(obj,1);
685   PetscValidCharPointer(name,2);
686   if (ptr) PetscValidHeader(ptr,3);
687   if (obj == ptr) SETERRQ(PetscObjectComm((PetscObject)obj),PETSC_ERR_SUP,"Cannot compose object with itself");
688   ierr = (*obj->bops->compose)(obj,name,ptr);CHKERRQ(ierr);
689   PetscFunctionReturn(0);
690 }
691 
692 /*@C
693    PetscObjectQuery  - Gets a PETSc object associated with a given object.
694 
695    Not Collective
696 
697    Input Parameters:
698 +  obj - the PETSc object
699          Thus must be cast with a (PetscObject), for example,
700          PetscObjectCompose((PetscObject)mat,...);
701 .  name - name associated with child object
702 -  ptr - the other PETSc object associated with the PETSc object, this must be
703          cast with (PetscObject*)
704 
705    Level: advanced
706 
707    The reference count of neither object is increased in this call
708 
709    Concepts: objects^composing
710    Concepts: composing objects
711    Concepts: objects^querying
712    Concepts: querying objects
713 
714 .seealso: PetscObjectCompose()
715 @*/
716 PetscErrorCode  PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
717 {
718   PetscErrorCode ierr;
719 
720   PetscFunctionBegin;
721   PetscValidHeader(obj,1);
722   PetscValidCharPointer(name,2);
723   PetscValidPointer(ptr,3);
724   ierr = (*obj->bops->query)(obj,name,ptr);CHKERRQ(ierr);
725   PetscFunctionReturn(0);
726 }
727 
728 /*MC
729    PetscObjectComposeFunction - Associates a function with a given PETSc object.
730 
731     Synopsis:
732     #include <petscsys.h>
733     PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))
734 
735    Logically Collective on PetscObject
736 
737    Input Parameters:
738 +  obj - the PETSc object; this must be cast with a (PetscObject), for example,
739          PetscObjectCompose((PetscObject)mat,...);
740 .  name - name associated with the child function
741 .  fname - name of the function
742 -  fptr - function pointer
743 
744    Level: advanced
745 
746    Notes:
747    To remove a registered routine, pass in NULL for fptr().
748 
749    PetscObjectComposeFunction() can be used with any PETSc object (such as
750    Mat, Vec, KSP, SNES, etc.) or any user-provided object.
751 
752    Concepts: objects^composing functions
753    Concepts: composing functions
754    Concepts: functions^querying
755    Concepts: objects^querying
756    Concepts: querying objects
757 
758 .seealso: PetscObjectQueryFunction(), PetscContainerCreate()
759 M*/
760 
761 PetscErrorCode  PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
762 {
763   PetscErrorCode ierr;
764 
765   PetscFunctionBegin;
766   PetscValidHeader(obj,1);
767   PetscValidCharPointer(name,2);
768   ierr = (*obj->bops->composefunction)(obj,name,fptr);CHKERRQ(ierr);
769   PetscFunctionReturn(0);
770 }
771 
772 /*MC
773    PetscObjectQueryFunction - Gets a function associated with a given object.
774 
775     Synopsis:
776     #include <petscsys.h>
777     PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))
778 
779    Logically Collective on PetscObject
780 
781    Input Parameters:
782 +  obj - the PETSc object; this must be cast with (PetscObject), for example,
783          PetscObjectQueryFunction((PetscObject)ksp,...);
784 -  name - name associated with the child function
785 
786    Output Parameter:
787 .  fptr - function pointer
788 
789    Level: advanced
790 
791    Concepts: objects^composing functions
792    Concepts: composing functions
793    Concepts: functions^querying
794    Concepts: objects^querying
795    Concepts: querying objects
796 
797 .seealso: PetscObjectComposeFunction(), PetscFunctionListFind()
798 M*/
799 PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
800 {
801   PetscErrorCode ierr;
802 
803   PetscFunctionBegin;
804   PetscValidHeader(obj,1);
805   PetscValidCharPointer(name,2);
806   ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr);
807   PetscFunctionReturn(0);
808 }
809 
810 struct _p_PetscContainer {
811   PETSCHEADER(int);
812   void           *ptr;
813   PetscErrorCode (*userdestroy)(void*);
814 };
815 
816 /*@C
817    PetscContainerUserDestroyDefault - Default destroy routine for user-provided data that simply calls PetscFree().
818 
819    Logically Collective on PetscContainer
820 
821    Input Parameter:
822 .  ctx - pointer to user-provided data
823 
824    Level: advanced
825 
826 .seealso: PetscContainerDestroy(), PetscContainterSetUserDestroy()
827 @*/
828 PetscErrorCode PetscContainerUserDestroyDefault(void* ctx)
829 {
830   PetscErrorCode ierr;
831 
832   PetscFunctionBegin;
833   PetscValidPointer(ctx,1);
834   ierr = PetscFree(ctx);CHKERRQ(ierr);
835   PetscFunctionReturn(0);
836 }
837 
838 /*@C
839    PetscContainerGetPointer - Gets the pointer value contained in the container.
840 
841    Not Collective
842 
843    Input Parameter:
844 .  obj - the object created with PetscContainerCreate()
845 
846    Output Parameter:
847 .  ptr - the pointer value
848 
849    Level: advanced
850 
851 .seealso: PetscContainerCreate(), PetscContainerDestroy(),
852           PetscContainerSetPointer()
853 @*/
854 PetscErrorCode  PetscContainerGetPointer(PetscContainer obj,void **ptr)
855 {
856   PetscFunctionBegin;
857   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
858   PetscValidPointer(ptr,2);
859   *ptr = obj->ptr;
860   PetscFunctionReturn(0);
861 }
862 
863 
864 /*@C
865    PetscContainerSetPointer - Sets the pointer value contained in the container.
866 
867    Logically Collective on PetscContainer
868 
869    Input Parameters:
870 +  obj - the object created with PetscContainerCreate()
871 -  ptr - the pointer value
872 
873    Level: advanced
874 
875 .seealso: PetscContainerCreate(), PetscContainerDestroy(),
876           PetscContainerGetPointer()
877 @*/
878 PetscErrorCode  PetscContainerSetPointer(PetscContainer obj,void *ptr)
879 {
880   PetscFunctionBegin;
881   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
882   if (ptr) PetscValidPointer(ptr,2);
883   obj->ptr = ptr;
884   PetscFunctionReturn(0);
885 }
886 
887 /*@C
888    PetscContainerDestroy - Destroys a PETSc container object.
889 
890    Collective on PetscContainer
891 
892    Input Parameter:
893 .  obj - an object that was created with PetscContainerCreate()
894 
895    Level: advanced
896 
897 .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
898 @*/
899 PetscErrorCode  PetscContainerDestroy(PetscContainer *obj)
900 {
901   PetscErrorCode ierr;
902 
903   PetscFunctionBegin;
904   if (!*obj) PetscFunctionReturn(0);
905   PetscValidHeaderSpecific(*obj,PETSC_CONTAINER_CLASSID,1);
906   if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; PetscFunctionReturn(0);}
907   if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
908   ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr);
909   PetscFunctionReturn(0);
910 }
911 
912 /*@C
913    PetscContainerSetUserDestroy - Sets name of the user destroy function.
914 
915    Logically Collective on PetscContainer
916 
917    Input Parameter:
918 +  obj - an object that was created with PetscContainerCreate()
919 -  des - name of the user destroy function
920 
921    Notes:
922    Use PetscContainerUserDestroyDefault() if the memory was obtained by calling PetscMalloc or one of its variants for single memory allocation.
923 
924    Level: advanced
925 
926 .seealso: PetscContainerDestroy(), PetscContainerUserDestroyDefault(), PetscMalloc(), PetscMalloc1(), PetscCalloc(), PetscCalloc1()
927 @*/
928 PetscErrorCode  PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
929 {
930   PetscFunctionBegin;
931   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
932   obj->userdestroy = des;
933   PetscFunctionReturn(0);
934 }
935 
936 PetscClassId PETSC_CONTAINER_CLASSID;
937 
938 /*@C
939    PetscContainerCreate - Creates a PETSc object that has room to hold
940    a single pointer. This allows one to attach any type of data (accessible
941    through a pointer) with the PetscObjectCompose() function to a PetscObject.
942    The data item itself is attached by a call to PetscContainerSetPointer().
943 
944    Collective on MPI_Comm
945 
946    Input Parameters:
947 .  comm - MPI communicator that shares the object
948 
949    Output Parameters:
950 .  container - the container created
951 
952    Level: advanced
953 
954 .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
955 @*/
956 PetscErrorCode  PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
957 {
958   PetscErrorCode ierr;
959   PetscContainer contain;
960 
961   PetscFunctionBegin;
962   PetscValidPointer(container,2);
963   ierr = PetscSysInitializePackage();CHKERRQ(ierr);
964   ierr = PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);CHKERRQ(ierr);
965   *container = contain;
966   PetscFunctionReturn(0);
967 }
968 
969 /*@
970    PetscObjectSetFromOptions - Sets generic parameters from user options.
971 
972    Collective on obj
973 
974    Input Parameter:
975 .  obj - the PetscObjcet
976 
977    Options Database Keys:
978 
979    Notes:
980    We have no generic options at present, so this does nothing
981 
982    Level: beginner
983 
984 .keywords: set, options, database
985 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
986 @*/
987 PetscErrorCode  PetscObjectSetFromOptions(PetscObject obj)
988 {
989   PetscFunctionBegin;
990   PetscValidHeader(obj,1);
991   PetscFunctionReturn(0);
992 }
993 
994 /*@
995    PetscObjectSetUp - Sets up the internal data structures for the later use.
996 
997    Collective on PetscObject
998 
999    Input Parameters:
1000 .  obj - the PetscObject
1001 
1002    Notes:
1003    This does nothing at present.
1004 
1005    Level: advanced
1006 
1007 .keywords: setup
1008 .seealso: PetscObjectDestroy()
1009 @*/
1010 PetscErrorCode  PetscObjectSetUp(PetscObject obj)
1011 {
1012   PetscFunctionBegin;
1013   PetscValidHeader(obj,1);
1014   PetscFunctionReturn(0);
1015 }
1016