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