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