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