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