xref: /petsc/src/sys/objects/inherit.c (revision eb4227cfdd169cc03749ba3ef12d3932f2f322bf)
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[],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 = 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 objeft
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     ierr = (*obj->optiondestroy[i])(obj,obj->optionctx[i]);CHKERRQ(ierr);
508   }
509   obj->noptionhandler = 0;
510   PetscFunctionReturn(0);
511 }
512 
513 
514 #undef __FUNCT__
515 #define __FUNCT__ "PetscObjectReference"
516 /*@
517    PetscObjectReference - Indicates to any PetscObject that it is being
518    referenced by another PetscObject. This increases the reference
519    count for that object by one.
520 
521    Logically Collective on PetscObject
522 
523    Input Parameter:
524 .  obj - the PETSc object. This must be cast with (PetscObject), for example,
525          PetscObjectReference((PetscObject)mat);
526 
527    Level: advanced
528 
529 .seealso: PetscObjectCompose(), PetscObjectDereference()
530 @*/
531 PetscErrorCode  PetscObjectReference(PetscObject obj)
532 {
533   PetscFunctionBegin;
534   if (!obj) PetscFunctionReturn(0);
535   PetscValidHeader(obj,1);
536   obj->refct++;
537   PetscFunctionReturn(0);
538 }
539 
540 #undef __FUNCT__
541 #define __FUNCT__ "PetscObjectGetReference"
542 /*@
543    PetscObjectGetReference - Gets the current reference count for
544    any PETSc object.
545 
546    Not Collective
547 
548    Input Parameter:
549 .  obj - the PETSc object; this must be cast with (PetscObject), for example,
550          PetscObjectGetReference((PetscObject)mat,&cnt);
551 
552    Output Parameter:
553 .  cnt - the reference count
554 
555    Level: advanced
556 
557 .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
558 @*/
559 PetscErrorCode  PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
560 {
561   PetscFunctionBegin;
562   PetscValidHeader(obj,1);
563   PetscValidIntPointer(cnt,2);
564   *cnt = obj->refct;
565   PetscFunctionReturn(0);
566 }
567 
568 #undef __FUNCT__
569 #define __FUNCT__ "PetscObjectDereference"
570 /*@
571    PetscObjectDereference - Indicates to any PetscObject that it is being
572    referenced by one less PetscObject. This decreases the reference
573    count for that object by one.
574 
575    Collective on PetscObject if reference reaches 0 otherwise Logically Collective
576 
577    Input Parameter:
578 .  obj - the PETSc object; this must be cast with (PetscObject), for example,
579          PetscObjectDereference((PetscObject)mat);
580 
581    Notes: PetscObjectDestroy(PetscObject *obj)  sets the obj pointer to null after the call, this routine does not.
582 
583    Level: advanced
584 
585 .seealso: PetscObjectCompose(), PetscObjectReference()
586 @*/
587 PetscErrorCode  PetscObjectDereference(PetscObject obj)
588 {
589   PetscErrorCode ierr;
590 
591   PetscFunctionBegin;
592   PetscValidHeader(obj,1);
593   if (obj->bops->destroy) {
594     ierr = (*obj->bops->destroy)(&obj);CHKERRQ(ierr);
595   } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
596   PetscFunctionReturn(0);
597 }
598 
599 /* ----------------------------------------------------------------------- */
600 /*
601      The following routines are the versions private to the PETSc object
602      data structures.
603 */
604 #undef __FUNCT__
605 #define __FUNCT__ "PetscObjectGetComm_Petsc"
606 PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
607 {
608   PetscFunctionBegin;
609   PetscValidHeader(obj,1);
610   *comm = obj->comm;
611   PetscFunctionReturn(0);
612 }
613 
614 #undef __FUNCT__
615 #define __FUNCT__ "PetscObjectRemoveReference"
616 PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
617 {
618   PetscErrorCode ierr;
619 
620   PetscFunctionBegin;
621   PetscValidHeader(obj,1);
622   ierr = PetscObjectListRemoveReference(&obj->olist,name);CHKERRQ(ierr);
623   PetscFunctionReturn(0);
624 }
625 
626 #undef __FUNCT__
627 #define __FUNCT__ "PetscObjectCompose_Petsc"
628 PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
629 {
630   PetscErrorCode ierr;
631   char           *tname;
632   PetscBool      skipreference;
633 
634   PetscFunctionBegin;
635   if (ptr) {
636     ierr = PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);CHKERRQ(ierr);
637     if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
638   }
639   ierr = PetscObjectListAdd(&obj->olist,name,ptr);CHKERRQ(ierr);
640   PetscFunctionReturn(0);
641 }
642 
643 #undef __FUNCT__
644 #define __FUNCT__ "PetscObjectQuery_Petsc"
645 PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
646 {
647   PetscErrorCode ierr;
648 
649   PetscFunctionBegin;
650   PetscValidHeader(obj,1);
651   ierr = PetscObjectListFind(obj->olist,name,ptr);CHKERRQ(ierr);
652   PetscFunctionReturn(0);
653 }
654 
655 #undef __FUNCT__
656 #define __FUNCT__ "PetscObjectComposeFunction_Petsc"
657 PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
658 {
659   PetscErrorCode ierr;
660 
661   PetscFunctionBegin;
662   PetscValidHeader(obj,1);
663   ierr = PetscFunctionListAdd(obj->comm,&obj->qlist,name,fname,ptr);CHKERRQ(ierr);
664   PetscFunctionReturn(0);
665 }
666 
667 #undef __FUNCT__
668 #define __FUNCT__ "PetscObjectQueryFunction_Petsc"
669 PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
670 {
671   PetscErrorCode ierr;
672 
673   PetscFunctionBegin;
674   PetscValidHeader(obj,1);
675   ierr = PetscFunctionListFind(obj->comm,obj->qlist,name,PETSC_FALSE,ptr);CHKERRQ(ierr);
676   PetscFunctionReturn(0);
677 }
678 
679 #undef __FUNCT__
680 #define __FUNCT__ "PetscObjectCompose"
681 /*@C
682    PetscObjectCompose - Associates another PETSc object with a given PETSc object.
683 
684    Not Collective
685 
686    Input Parameters:
687 +  obj - the PETSc object; this must be cast with (PetscObject), for example,
688          PetscObjectCompose((PetscObject)mat,...);
689 .  name - name associated with the child object
690 -  ptr - the other PETSc object to associate with the PETSc object; this must also be
691          cast with (PetscObject)
692 
693    Level: advanced
694 
695    Notes:
696    The second objects reference count is automatically increased by one when it is
697    composed.
698 
699    Replaces any previous object that had the same name.
700 
701    If ptr is null and name has previously been composed using an object, then that
702    entry is removed from the obj.
703 
704    PetscObjectCompose() can be used with any PETSc object (such as
705    Mat, Vec, KSP, SNES, etc.) or any user-provided object.  See
706    PetscContainerCreate() for info on how to create an object from a
707    user-provided pointer that may then be composed with PETSc objects.
708 
709    Concepts: objects^composing
710    Concepts: composing objects
711 
712 .seealso: PetscObjectQuery(), PetscContainerCreate()
713 @*/
714 PetscErrorCode  PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
715 {
716   PetscErrorCode ierr;
717 
718   PetscFunctionBegin;
719   PetscValidHeader(obj,1);
720   PetscValidCharPointer(name,2);
721   if (ptr) PetscValidHeader(ptr,3);
722   ierr = (*obj->bops->compose)(obj,name,ptr);CHKERRQ(ierr);
723   PetscFunctionReturn(0);
724 }
725 
726 #undef __FUNCT__
727 #define __FUNCT__ "PetscObjectSetPrecision"
728 /*@C
729    PetscObjectSetPrecision - sets the precision used within a given object.
730 
731    Collective on the PetscObject
732 
733    Input Parameters:
734 +  obj - the PETSc object; this must be cast with (PetscObject), for example,
735          PetscObjectCompose((PetscObject)mat,...);
736 -  precision - the precision
737 
738    Level: advanced
739 
740 .seealso: PetscObjectQuery(), PetscContainerCreate()
741 @*/
742 PetscErrorCode  PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
743 {
744   PetscFunctionBegin;
745   PetscValidHeader(obj,1);
746   obj->precision = precision;
747   PetscFunctionReturn(0);
748 }
749 
750 #undef __FUNCT__
751 #define __FUNCT__ "PetscObjectQuery"
752 /*@C
753    PetscObjectQuery  - Gets a PETSc object associated with a given object.
754 
755    Not Collective
756 
757    Input Parameters:
758 +  obj - the PETSc object
759          Thus must be cast with a (PetscObject), for example,
760          PetscObjectCompose((PetscObject)mat,...);
761 .  name - name associated with child object
762 -  ptr - the other PETSc object associated with the PETSc object, this must be
763          cast with (PetscObject*)
764 
765    Level: advanced
766 
767    The reference count of neither object is increased in this call
768 
769    Concepts: objects^composing
770    Concepts: composing objects
771    Concepts: objects^querying
772    Concepts: querying objects
773 
774 .seealso: PetscObjectCompose()
775 @*/
776 PetscErrorCode  PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
777 {
778   PetscErrorCode ierr;
779 
780   PetscFunctionBegin;
781   PetscValidHeader(obj,1);
782   PetscValidCharPointer(name,2);
783   PetscValidPointer(ptr,3);
784   ierr = (*obj->bops->query)(obj,name,ptr);CHKERRQ(ierr);
785   PetscFunctionReturn(0);
786 }
787 
788 #undef __FUNCT__
789 #define __FUNCT__ "PetscObjectComposeFunction_Private"
790 PetscErrorCode  PetscObjectComposeFunction_Private(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
791 {
792   PetscErrorCode ierr;
793 
794   PetscFunctionBegin;
795   PetscValidHeader(obj,1);
796   PetscValidCharPointer(name,2);
797   ierr = (*obj->bops->composefunction)(obj,name,fname,ptr);CHKERRQ(ierr);
798   PetscFunctionReturn(0);
799 }
800 
801 #undef __FUNCT__
802 #define __FUNCT__ "PetscObjectQueryFunction"
803 /*@C
804    PetscObjectQueryFunction - Gets a function associated with a given object.
805 
806    Logically Collective on PetscObject
807 
808    Input Parameters:
809 +  obj - the PETSc object; this must be cast with (PetscObject), for example,
810          PetscObjectQueryFunction((PetscObject)ksp,...);
811 -  name - name associated with the child function
812 
813    Output Parameter:
814 .  ptr - function pointer
815 
816    Level: advanced
817 
818    Concepts: objects^composing functions
819    Concepts: composing functions
820    Concepts: functions^querying
821    Concepts: objects^querying
822    Concepts: querying objects
823 
824 .seealso: PetscObjectComposeFunctionDynamic()
825 @*/
826 PetscErrorCode  PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void))
827 {
828   PetscErrorCode ierr;
829 
830   PetscFunctionBegin;
831   PetscValidHeader(obj,1);
832   PetscValidCharPointer(name,2);
833   ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr);
834   PetscFunctionReturn(0);
835 }
836 
837 struct _p_PetscContainer {
838   PETSCHEADER(int);
839   void           *ptr;
840   PetscErrorCode (*userdestroy)(void*);
841 };
842 
843 #undef __FUNCT__
844 #define __FUNCT__ "PetscContainerGetPointer"
845 /*@C
846    PetscContainerGetPointer - Gets the pointer value contained in the container.
847 
848    Not Collective
849 
850    Input Parameter:
851 .  obj - the object created with PetscContainerCreate()
852 
853    Output Parameter:
854 .  ptr - the pointer value
855 
856    Level: advanced
857 
858 .seealso: PetscContainerCreate(), PetscContainerDestroy(),
859           PetscContainerSetPointer()
860 @*/
861 PetscErrorCode  PetscContainerGetPointer(PetscContainer obj,void **ptr)
862 {
863   PetscFunctionBegin;
864   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
865   PetscValidPointer(ptr,2);
866   *ptr = obj->ptr;
867   PetscFunctionReturn(0);
868 }
869 
870 
871 #undef __FUNCT__
872 #define __FUNCT__ "PetscContainerSetPointer"
873 /*@C
874    PetscContainerSetPointer - Sets the pointer value contained in the container.
875 
876    Logically Collective on PetscContainer
877 
878    Input Parameters:
879 +  obj - the object created with PetscContainerCreate()
880 -  ptr - the pointer value
881 
882    Level: advanced
883 
884 .seealso: PetscContainerCreate(), PetscContainerDestroy(),
885           PetscContainerGetPointer()
886 @*/
887 PetscErrorCode  PetscContainerSetPointer(PetscContainer obj,void *ptr)
888 {
889   PetscFunctionBegin;
890   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
891   if (ptr) PetscValidPointer(ptr,2);
892   obj->ptr = ptr;
893   PetscFunctionReturn(0);
894 }
895 
896 #undef __FUNCT__
897 #define __FUNCT__ "PetscContainerDestroy"
898 /*@C
899    PetscContainerDestroy - Destroys a PETSc container object.
900 
901    Collective on PetscContainer
902 
903    Input Parameter:
904 .  obj - an object that was created with PetscContainerCreate()
905 
906    Level: advanced
907 
908 .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
909 @*/
910 PetscErrorCode  PetscContainerDestroy(PetscContainer *obj)
911 {
912   PetscErrorCode ierr;
913 
914   PetscFunctionBegin;
915   if (!*obj) PetscFunctionReturn(0);
916   PetscValidHeaderSpecific(*obj,PETSC_CONTAINER_CLASSID,1);
917   if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; PetscFunctionReturn(0);}
918   if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
919   ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr);
920   PetscFunctionReturn(0);
921 }
922 
923 #undef __FUNCT__
924 #define __FUNCT__ "PetscContainerSetUserDestroy"
925 /*@C
926    PetscContainerSetUserDestroy - Sets name of the user destroy function.
927 
928    Logically Collective on PetscContainer
929 
930    Input Parameter:
931 +  obj - an object that was created with PetscContainerCreate()
932 -  des - name of the user destroy function
933 
934    Level: advanced
935 
936 .seealso: PetscContainerDestroy()
937 @*/
938 PetscErrorCode  PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
939 {
940   PetscFunctionBegin;
941   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
942   obj->userdestroy = des;
943   PetscFunctionReturn(0);
944 }
945 
946 PetscClassId PETSC_CONTAINER_CLASSID;
947 
948 #undef __FUNCT__
949 #define __FUNCT__ "PetscContainerCreate"
950 /*@C
951    PetscContainerCreate - Creates a PETSc object that has room to hold
952    a single pointer. This allows one to attach any type of data (accessible
953    through a pointer) with the PetscObjectCompose() function to a PetscObject.
954    The data item itself is attached by a call to PetscContainerSetPointer().
955 
956    Collective on MPI_Comm
957 
958    Input Parameters:
959 .  comm - MPI communicator that shares the object
960 
961    Output Parameters:
962 .  container - the container created
963 
964    Level: advanced
965 
966 .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
967 @*/
968 PetscErrorCode  PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
969 {
970   PetscErrorCode ierr;
971   PetscContainer contain;
972 
973   PetscFunctionBegin;
974   PetscValidPointer(container,2);
975   ierr = PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);CHKERRQ(ierr);
976   *container = contain;
977   PetscFunctionReturn(0);
978 }
979 
980 #undef __FUNCT__
981 #define __FUNCT__ "PetscObjectSetFromOptions"
982 /*@
983    PetscObjectSetFromOptions - Sets generic parameters from user options.
984 
985    Collective on obj
986 
987    Input Parameter:
988 .  obj - the PetscObjcet
989 
990    Options Database Keys:
991 
992    Notes:
993    We have no generic options at present, so this does nothing
994 
995    Level: beginner
996 
997 .keywords: set, options, database
998 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
999 @*/
1000 PetscErrorCode  PetscObjectSetFromOptions(PetscObject obj)
1001 {
1002   PetscFunctionBegin;
1003   PetscValidHeader(obj,1);
1004   PetscFunctionReturn(0);
1005 }
1006 
1007 #undef __FUNCT__
1008 #define __FUNCT__ "PetscObjectSetUp"
1009 /*@
1010    PetscObjectSetUp - Sets up the internal data structures for the later use.
1011 
1012    Collective on PetscObject
1013 
1014    Input Parameters:
1015 .  obj - the PetscObject
1016 
1017    Notes:
1018    This does nothing at present.
1019 
1020    Level: advanced
1021 
1022 .keywords: setup
1023 .seealso: PetscObjectDestroy()
1024 @*/
1025 PetscErrorCode  PetscObjectSetUp(PetscObject obj)
1026 {
1027   PetscFunctionBegin;
1028   PetscValidHeader(obj,1);
1029   PetscFunctionReturn(0);
1030 }
1031