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