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