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