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