xref: /petsc/src/sys/objects/inherit.c (revision 487a658c8b32ba712a1dc8280daad2fd70c1dcd9)
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   PetscValidPointer(ctx,1);
885   ierr = PetscFree(ctx);CHKERRQ(ierr);
886   PetscFunctionReturn(0);
887 }
888 
889 /*@C
890    PetscContainerGetPointer - Gets the pointer value contained in the container.
891 
892    Not Collective
893 
894    Input Parameter:
895 .  obj - the object created with PetscContainerCreate()
896 
897    Output Parameter:
898 .  ptr - the pointer value
899 
900    Level: advanced
901 
902 .seealso: PetscContainerCreate(), PetscContainerDestroy(),
903           PetscContainerSetPointer()
904 @*/
905 PetscErrorCode  PetscContainerGetPointer(PetscContainer obj,void **ptr)
906 {
907   PetscFunctionBegin;
908   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
909   PetscValidPointer(ptr,2);
910   *ptr = obj->ptr;
911   PetscFunctionReturn(0);
912 }
913 
914 
915 /*@C
916    PetscContainerSetPointer - Sets the pointer value contained in the container.
917 
918    Logically Collective on PetscContainer
919 
920    Input Parameters:
921 +  obj - the object created with PetscContainerCreate()
922 -  ptr - the pointer value
923 
924    Level: advanced
925 
926 .seealso: PetscContainerCreate(), PetscContainerDestroy(),
927           PetscContainerGetPointer()
928 @*/
929 PetscErrorCode  PetscContainerSetPointer(PetscContainer obj,void *ptr)
930 {
931   PetscFunctionBegin;
932   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
933   if (ptr) PetscValidPointer(ptr,2);
934   obj->ptr = ptr;
935   PetscFunctionReturn(0);
936 }
937 
938 /*@C
939    PetscContainerDestroy - Destroys a PETSc container object.
940 
941    Collective on PetscContainer
942 
943    Input Parameter:
944 .  obj - an object that was created with PetscContainerCreate()
945 
946    Level: advanced
947 
948 .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
949 @*/
950 PetscErrorCode  PetscContainerDestroy(PetscContainer *obj)
951 {
952   PetscErrorCode ierr;
953 
954   PetscFunctionBegin;
955   if (!*obj) PetscFunctionReturn(0);
956   PetscValidHeaderSpecific(*obj,PETSC_CONTAINER_CLASSID,1);
957   if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; PetscFunctionReturn(0);}
958   if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
959   ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr);
960   PetscFunctionReturn(0);
961 }
962 
963 /*@C
964    PetscContainerSetUserDestroy - Sets name of the user destroy function.
965 
966    Logically Collective on PetscContainer
967 
968    Input Parameter:
969 +  obj - an object that was created with PetscContainerCreate()
970 -  des - name of the user destroy function
971 
972    Notes:
973    Use PetscContainerUserDestroyDefault() if the memory was obtained by calling PetscMalloc or one of its variants for single memory allocation.
974 
975    Level: advanced
976 
977 .seealso: PetscContainerDestroy(), PetscContainerUserDestroyDefault(), PetscMalloc(), PetscMalloc1(), PetscCalloc(), PetscCalloc1()
978 @*/
979 PetscErrorCode  PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
980 {
981   PetscFunctionBegin;
982   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
983   obj->userdestroy = des;
984   PetscFunctionReturn(0);
985 }
986 
987 PetscClassId PETSC_CONTAINER_CLASSID;
988 
989 /*@C
990    PetscContainerCreate - Creates a PETSc object that has room to hold
991    a single pointer. This allows one to attach any type of data (accessible
992    through a pointer) with the PetscObjectCompose() function to a PetscObject.
993    The data item itself is attached by a call to PetscContainerSetPointer().
994 
995    Collective on MPI_Comm
996 
997    Input Parameters:
998 .  comm - MPI communicator that shares the object
999 
1000    Output Parameters:
1001 .  container - the container created
1002 
1003    Level: advanced
1004 
1005 .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
1006 @*/
1007 PetscErrorCode  PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
1008 {
1009   PetscErrorCode ierr;
1010   PetscContainer contain;
1011 
1012   PetscFunctionBegin;
1013   PetscValidPointer(container,2);
1014   ierr = PetscSysInitializePackage();CHKERRQ(ierr);
1015   ierr = PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);CHKERRQ(ierr);
1016   *container = contain;
1017   PetscFunctionReturn(0);
1018 }
1019 
1020 /*@
1021    PetscObjectSetFromOptions - Sets generic parameters from user options.
1022 
1023    Collective on obj
1024 
1025    Input Parameter:
1026 .  obj - the PetscObjcet
1027 
1028    Options Database Keys:
1029 
1030    Notes:
1031    We have no generic options at present, so this does nothing
1032 
1033    Level: beginner
1034 
1035 .keywords: set, options, database
1036 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
1037 @*/
1038 PetscErrorCode  PetscObjectSetFromOptions(PetscObject obj)
1039 {
1040   PetscFunctionBegin;
1041   PetscValidHeader(obj,1);
1042   PetscFunctionReturn(0);
1043 }
1044 
1045 /*@
1046    PetscObjectSetUp - Sets up the internal data structures for the later use.
1047 
1048    Collective on PetscObject
1049 
1050    Input Parameters:
1051 .  obj - the PetscObject
1052 
1053    Notes:
1054    This does nothing at present.
1055 
1056    Level: advanced
1057 
1058 .keywords: setup
1059 .seealso: PetscObjectDestroy()
1060 @*/
1061 PetscErrorCode  PetscObjectSetUp(PetscObject obj)
1062 {
1063   PetscFunctionBegin;
1064   PetscValidHeader(obj,1);
1065   PetscFunctionReturn(0);
1066 }
1067