xref: /petsc/src/sys/objects/inherit.c (revision 2e82e6d194918c13e0a87f760d0874fddacf4af4)
1 #define PETSC_DLL
2 /*
3      Provides utility routines for manipulating any type of PETSc object.
4 */
5 #include "petscsys.h"  /*I   "petscsys.h"    I*/
6 
7 static PetscObject *PetscObjects = 0;
8 static 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[],MPI_Comm comm,
23                                          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->prefix                 = 0;
35   h->refct                  = 1;
36   h->amem                   = -1;
37   h->id                     = idcnt++;
38   h->parentid               = 0;
39   h->qlist                  = 0;
40   h->olist                  = 0;
41   h->precision              = (PetscPrecision) sizeof(PetscScalar);
42   h->bops->destroy          = des;
43   h->bops->view             = vie;
44   h->bops->getcomm          = PetscObjectGetComm_Petsc;
45   h->bops->compose          = PetscObjectCompose_Petsc;
46   h->bops->query            = PetscObjectQuery_Petsc;
47   h->bops->composefunction  = PetscObjectComposeFunction_Petsc;
48   h->bops->queryfunction    = PetscObjectQueryFunction_Petsc;
49   ierr = PetscCommDuplicate(comm,&h->comm,&h->tag);CHKERRQ(ierr);
50 
51   /* Keep a record of object created */
52   PetscObjectsCounts++;
53   for (i=0; i<PetscObjectsMaxCounts; i++) {
54     if (!PetscObjects[i]) {
55       PetscObjects[i] = h;
56       PetscFunctionReturn(0);
57     }
58   }
59   /* Need to increase the space for storing PETSc objects */
60   if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100;
61   else                        newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts;
62   ierr = PetscMalloc(newPetscObjectsMaxCounts*sizeof(PetscObject),&newPetscObjects);CHKERRQ(ierr);
63   ierr = PetscMemcpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts);CHKERRQ(ierr);
64   ierr = PetscMemzero(newPetscObjects+PetscObjectsMaxCounts,(newPetscObjectsMaxCounts - PetscObjectsMaxCounts)*sizeof(PetscObject));CHKERRQ(ierr);
65   ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
66   PetscObjects                        = newPetscObjects;
67   PetscObjects[PetscObjectsMaxCounts] = h;
68   PetscObjectsMaxCounts               = newPetscObjectsMaxCounts;
69 
70   PetscFunctionReturn(0);
71 }
72 
73 extern PetscBool      PetscMemoryCollectMaximumUsage;
74 extern PetscLogDouble PetscMemoryMaximumUsage;
75 
76 #undef __FUNCT__
77 #define __FUNCT__ "PetscHeaderDestroy_Private"
78 /*
79     PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
80     the macro PetscHeaderDestroy().
81 */
82 PetscErrorCode  PetscHeaderDestroy_Private(PetscObject h)
83 {
84   PetscErrorCode ierr;
85   PetscInt       i;
86 
87   PetscFunctionBegin;
88 #if defined(PETSC_HAVE_AMS)
89   if (PetscAMSPublishAll) {
90     ierr = PetscObjectUnPublish((PetscObject)h);CHKERRQ(ierr);
91   }
92 #endif
93   if (PetscMemoryCollectMaximumUsage) {
94     PetscLogDouble usage;
95     ierr = PetscMemoryGetCurrentUsage(&usage);CHKERRQ(ierr);
96     if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
97   }
98   /* first destroy things that could execute arbitrary code */
99   if (h->python_destroy) {
100     void           *python_context          = h->python_context;
101     PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
102     h->python_context = 0;
103     h->python_destroy = 0;
104     ierr = (*python_destroy)(python_context);CHKERRQ(ierr);
105   }
106   ierr = PetscOListDestroy(h->olist);CHKERRQ(ierr);
107   ierr = PetscCommDestroy(&h->comm);CHKERRQ(ierr);
108   /* next destroy other things */
109   h->classid = PETSCFREEDHEADER;
110   ierr = PetscFree(h->bops);CHKERRQ(ierr);
111   ierr = PetscFListDestroy(&h->qlist);CHKERRQ(ierr);
112   ierr = PetscFree(h->type_name);CHKERRQ(ierr);
113   ierr = PetscFree(h->name);CHKERRQ(ierr);
114   ierr = PetscFree(h->prefix);CHKERRQ(ierr);
115   ierr = PetscFree(h->fortran_func_pointers);CHKERRQ(ierr);
116   ierr = PetscFree(h->intcomposeddata);CHKERRQ(ierr);
117   ierr = PetscFree(h->intcomposedstate);CHKERRQ(ierr);
118   ierr = PetscFree(h->realcomposeddata);CHKERRQ(ierr);
119   ierr = PetscFree(h->realcomposedstate);CHKERRQ(ierr);
120   ierr = PetscFree(h->scalarcomposeddata);CHKERRQ(ierr);
121   ierr = PetscFree(h->scalarcomposedstate);CHKERRQ(ierr);
122 
123   /* Record object removal from list of all objects */
124   for (i=0; i<PetscObjectsMaxCounts; i++) {
125     if (PetscObjects[i] == h) {
126       PetscObjects[i] = 0;
127       PetscObjectsCounts--;
128       break;
129     }
130   }
131   if (!PetscObjectsCounts) {
132     ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
133     PetscObjectsMaxCounts = 0;
134   }
135   PetscFunctionReturn(0);
136 }
137 
138 #undef __FUNCT__
139 #define __FUNCT__ "PetscObjectAddOptionsHandler"
140 /*@C
141     PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
142 
143     Not Collective
144 
145     Input Parameter:
146 +   obj - the PETSc object
147 .   handle - function that checks for options
148 .   destroy - function to destroy context if provided
149 -   ctx - optional context for check function
150 
151     Level: developer
152 
153 
154 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()
155 
156 @*/
157 PetscErrorCode  PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
158 {
159   PetscFunctionBegin;
160   if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
161   obj->optionhandler[obj->noptionhandler]   = handle;
162   obj->optiondestroy[obj->noptionhandler]   = destroy;
163   obj->optionctx[obj->noptionhandler++]     = ctx;
164   PetscFunctionReturn(0);
165 }
166 
167 #undef __FUNCT__
168 #define __FUNCT__ "PetscObjectProcessOptionsHandlers"
169 /*@C
170     PetscObjectProcessOptionsHandlers - Calls all the options handler attached to an object
171 
172     Not Collective
173 
174     Input Parameter:
175 .   obj - the PETSc object
176 
177     Level: developer
178 
179 
180 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()
181 
182 @*/
183 PetscErrorCode  PetscObjectProcessOptionsHandlers(PetscObject obj)
184 {
185   PetscInt       i;
186   PetscErrorCode ierr;
187 
188   PetscFunctionBegin;
189   for (i=0; i<obj->noptionhandler; i++) {
190     ierr = (*obj->optionhandler[i])(obj,obj->optionctx[i]);CHKERRQ(ierr);
191   }
192   PetscFunctionReturn(0);
193 }
194 
195 #undef __FUNCT__
196 #define __FUNCT__ "PetscObjectDestroyOptionsHandlers"
197 /*@C
198     PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an objeft
199 
200     Not Collective
201 
202     Input Parameter:
203 .   obj - the PETSc object
204 
205     Level: developer
206 
207 
208 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
209 
210 @*/
211 PetscErrorCode  PetscObjectDestroyOptionsHandlers(PetscObject obj)
212 {
213   PetscInt       i;
214   PetscErrorCode ierr;
215 
216   PetscFunctionBegin;
217   for (i=0; i<obj->noptionhandler; i++) {
218     ierr = (*obj->optiondestroy[i])(obj,obj->optionctx[i]);CHKERRQ(ierr);
219   }
220   obj->noptionhandler = 0;
221   PetscFunctionReturn(0);
222 }
223 
224 
225 #undef __FUNCT__
226 #define __FUNCT__ "PetscObjectReference"
227 /*@
228    PetscObjectReference - Indicates to any PetscObject that it is being
229    referenced by another PetscObject. This increases the reference
230    count for that object by one.
231 
232    Logically Collective on PetscObject
233 
234    Input Parameter:
235 .  obj - the PETSc object. This must be cast with (PetscObject), for example,
236          PetscObjectReference((PetscObject)mat);
237 
238    Level: advanced
239 
240 .seealso: PetscObjectCompose(), PetscObjectDereference()
241 @*/
242 PetscErrorCode  PetscObjectReference(PetscObject obj)
243 {
244   PetscFunctionBegin;
245   PetscValidHeader(obj,1);
246   obj->refct++;
247   PetscFunctionReturn(0);
248 }
249 
250 #undef __FUNCT__
251 #define __FUNCT__ "PetscObjectGetReference"
252 /*@
253    PetscObjectGetReference - Gets the current reference count for
254    any PETSc object.
255 
256    Not Collective
257 
258    Input Parameter:
259 .  obj - the PETSc object; this must be cast with (PetscObject), for example,
260          PetscObjectGetReference((PetscObject)mat,&cnt);
261 
262    Output Parameter:
263 .  cnt - the reference count
264 
265    Level: advanced
266 
267 .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
268 @*/
269 PetscErrorCode  PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
270 {
271   PetscFunctionBegin;
272   PetscValidHeader(obj,1);
273   PetscValidIntPointer(cnt,2);
274   *cnt = obj->refct;
275   PetscFunctionReturn(0);
276 }
277 
278 #undef __FUNCT__
279 #define __FUNCT__ "PetscObjectDereference"
280 /*@
281    PetscObjectDereference - Indicates to any PetscObject that it is being
282    referenced by one less PetscObject. This decreases the reference
283    count for that object by one.
284 
285    Collective on PetscObject if reference reaches 0 otherwise Logically Collective
286 
287    Input Parameter:
288 .  obj - the PETSc object; this must be cast with (PetscObject), for example,
289          PetscObjectDereference((PetscObject)mat);
290 
291    Level: advanced
292 
293 .seealso: PetscObjectCompose(), PetscObjectReference()
294 @*/
295 PetscErrorCode  PetscObjectDereference(PetscObject obj)
296 {
297   PetscErrorCode ierr;
298 
299   PetscFunctionBegin;
300   PetscValidHeader(obj,1);
301   if (obj->bops->destroy) {
302     ierr = (*obj->bops->destroy)(obj);CHKERRQ(ierr);
303   } else if (!--obj->refct) {
304     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
305   }
306   PetscFunctionReturn(0);
307 }
308 
309 /* ----------------------------------------------------------------------- */
310 /*
311      The following routines are the versions private to the PETSc object
312      data structures.
313 */
314 #undef __FUNCT__
315 #define __FUNCT__ "PetscObjectGetComm_Petsc"
316 PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
317 {
318   PetscFunctionBegin;
319   *comm = obj->comm;
320   PetscFunctionReturn(0);
321 }
322 
323 #undef __FUNCT__
324 #define __FUNCT__ "PetscObjectCompose_Petsc"
325 PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
326 {
327   PetscErrorCode ierr;
328   char           *tname;
329 
330   PetscFunctionBegin;
331   if (ptr) {
332     ierr = PetscOListReverseFind(ptr->olist,obj,&tname);CHKERRQ(ierr);
333     if (tname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was compose with it");
334   }
335   ierr = PetscOListAdd(&obj->olist,name,ptr);CHKERRQ(ierr);
336   PetscFunctionReturn(0);
337 }
338 
339 #undef __FUNCT__
340 #define __FUNCT__ "PetscObjectQuery_Petsc"
341 PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
342 {
343   PetscErrorCode ierr;
344 
345   PetscFunctionBegin;
346   ierr = PetscOListFind(obj->olist,name,ptr);CHKERRQ(ierr);
347   PetscFunctionReturn(0);
348 }
349 
350 #undef __FUNCT__
351 #define __FUNCT__ "PetscObjectComposeFunction_Petsc"
352 PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
353 {
354   PetscErrorCode ierr;
355 
356   PetscFunctionBegin;
357   ierr = PetscFListAdd(&obj->qlist,name,fname,ptr);CHKERRQ(ierr);
358   PetscFunctionReturn(0);
359 }
360 
361 #undef __FUNCT__
362 #define __FUNCT__ "PetscObjectQueryFunction_Petsc"
363 PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
364 {
365   PetscErrorCode ierr;
366 
367   PetscFunctionBegin;
368   ierr = PetscFListFind(obj->qlist,obj->comm,name,ptr);CHKERRQ(ierr);
369   PetscFunctionReturn(0);
370 }
371 
372 #undef __FUNCT__
373 #define __FUNCT__ "PetscObjectCompose"
374 /*@C
375    PetscObjectCompose - Associates another PETSc object with a given PETSc object.
376 
377    Not Collective
378 
379    Input Parameters:
380 +  obj - the PETSc object; this must be cast with (PetscObject), for example,
381          PetscObjectCompose((PetscObject)mat,...);
382 .  name - name associated with the child object
383 -  ptr - the other PETSc object to associate with the PETSc object; this must also be
384          cast with (PetscObject)
385 
386    Level: advanced
387 
388    Notes:
389    The second objects reference count is automatically increased by one when it is
390    composed.
391 
392    Replaces any previous object that had the same name.
393 
394    If ptr is null and name has previously been composed using an object, then that
395    entry is removed from the obj.
396 
397    PetscObjectCompose() can be used with any PETSc object (such as
398    Mat, Vec, KSP, SNES, etc.) or any user-provided object.  See
399    PetscContainerCreate() for info on how to create an object from a
400    user-provided pointer that may then be composed with PETSc objects.
401 
402    Concepts: objects^composing
403    Concepts: composing objects
404 
405 .seealso: PetscObjectQuery(), PetscContainerCreate()
406 @*/
407 PetscErrorCode  PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
408 {
409   PetscErrorCode ierr;
410 
411   PetscFunctionBegin;
412   PetscValidHeader(obj,1);
413   PetscValidCharPointer(name,2);
414   if (ptr) PetscValidHeader(ptr,3);
415   ierr = (*obj->bops->compose)(obj,name,ptr);CHKERRQ(ierr);
416   PetscFunctionReturn(0);
417 }
418 
419 #undef __FUNCT__
420 #define __FUNCT__ "PetscObjectSetPrecision"
421 /*@C
422    PetscObjectSetPrecision - sets the precision used within a given object.
423 
424    Collective on the PetscObject
425 
426    Input Parameters:
427 +  obj - the PETSc object; this must be cast with (PetscObject), for example,
428          PetscObjectCompose((PetscObject)mat,...);
429 -  precision - the precision
430 
431    Level: advanced
432 
433 .seealso: PetscObjectQuery(), PetscContainerCreate()
434 @*/
435 PetscErrorCode  PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
436 {
437   PetscFunctionBegin;
438   PetscValidHeader(obj,1);
439   obj->precision = precision;
440   PetscFunctionReturn(0);
441 }
442 
443 #undef __FUNCT__
444 #define __FUNCT__ "PetscObjectQuery"
445 /*@C
446    PetscObjectQuery  - Gets a PETSc object associated with a given object.
447 
448    Not Collective
449 
450    Input Parameters:
451 +  obj - the PETSc object
452          Thus must be cast with a (PetscObject), for example,
453          PetscObjectCompose((PetscObject)mat,...);
454 .  name - name associated with child object
455 -  ptr - the other PETSc object associated with the PETSc object, this must also be
456          cast with (PetscObject)
457 
458    Level: advanced
459 
460    Concepts: objects^composing
461    Concepts: composing objects
462    Concepts: objects^querying
463    Concepts: querying objects
464 
465 .seealso: PetscObjectQuery()
466 @*/
467 PetscErrorCode  PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
468 {
469   PetscErrorCode ierr;
470 
471   PetscFunctionBegin;
472   PetscValidHeader(obj,1);
473   PetscValidCharPointer(name,2);
474   PetscValidPointer(ptr,3);
475   ierr = (*obj->bops->query)(obj,name,ptr);CHKERRQ(ierr);
476   PetscFunctionReturn(0);
477 }
478 
479 #undef __FUNCT__
480 #define __FUNCT__ "PetscObjectComposeFunction"
481 PetscErrorCode  PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
482 {
483   PetscErrorCode ierr;
484 
485   PetscFunctionBegin;
486   PetscValidHeader(obj,1);
487   PetscValidCharPointer(name,2);
488   PetscValidCharPointer(fname,3);
489   ierr = (*obj->bops->composefunction)(obj,name,fname,ptr);CHKERRQ(ierr);
490   PetscFunctionReturn(0);
491 }
492 
493 #undef __FUNCT__
494 #define __FUNCT__ "PetscObjectQueryFunction"
495 /*@C
496    PetscObjectQueryFunction - Gets a function associated with a given object.
497 
498    Logically Collective on PetscObject
499 
500    Input Parameters:
501 +  obj - the PETSc object; this must be cast with (PetscObject), for example,
502          PetscObjectQueryFunction((PetscObject)ksp,...);
503 -  name - name associated with the child function
504 
505    Output Parameter:
506 .  ptr - function pointer
507 
508    Level: advanced
509 
510    Concepts: objects^composing functions
511    Concepts: composing functions
512    Concepts: functions^querying
513    Concepts: objects^querying
514    Concepts: querying objects
515 
516 .seealso: PetscObjectComposeFunctionDynamic()
517 @*/
518 PetscErrorCode  PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void))
519 {
520   PetscErrorCode ierr;
521 
522   PetscFunctionBegin;
523   PetscValidHeader(obj,1);
524   PetscValidCharPointer(name,2);
525   ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr);
526   PetscFunctionReturn(0);
527 }
528 
529 struct _p_PetscContainer {
530   PETSCHEADER(int);
531   void   *ptr;
532   PetscErrorCode (*userdestroy)(void*);
533 };
534 
535 #undef __FUNCT__
536 #define __FUNCT__ "PetscContainerGetPointer"
537 /*@C
538    PetscContainerGetPointer - Gets the pointer value contained in the container.
539 
540    Not Collective
541 
542    Input Parameter:
543 .  obj - the object created with PetscContainerCreate()
544 
545    Output Parameter:
546 .  ptr - the pointer value
547 
548    Level: advanced
549 
550 .seealso: PetscContainerCreate(), PetscContainerDestroy(),
551           PetscContainerSetPointer()
552 @*/
553 PetscErrorCode  PetscContainerGetPointer(PetscContainer obj,void **ptr)
554 {
555   PetscFunctionBegin;
556   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
557   PetscValidPointer(ptr,2);
558   *ptr = obj->ptr;
559   PetscFunctionReturn(0);
560 }
561 
562 
563 #undef __FUNCT__
564 #define __FUNCT__ "PetscContainerSetPointer"
565 /*@C
566    PetscContainerSetPointer - Sets the pointer value contained in the container.
567 
568    Logically Collective on PetscContainer
569 
570    Input Parameters:
571 +  obj - the object created with PetscContainerCreate()
572 -  ptr - the pointer value
573 
574    Level: advanced
575 
576 .seealso: PetscContainerCreate(), PetscContainerDestroy(),
577           PetscContainerGetPointer()
578 @*/
579 PetscErrorCode  PetscContainerSetPointer(PetscContainer obj,void *ptr)
580 {
581   PetscFunctionBegin;
582   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
583   if (ptr) PetscValidPointer(ptr,2);
584   obj->ptr = ptr;
585   PetscFunctionReturn(0);
586 }
587 
588 #undef __FUNCT__
589 #define __FUNCT__ "PetscContainerDestroy"
590 /*@C
591    PetscContainerDestroy - Destroys a PETSc container object.
592 
593    Collective on PetscContainer
594 
595    Input Parameter:
596 .  obj - an object that was created with PetscContainerCreate()
597 
598    Level: advanced
599 
600 .seealso: PetscContainerCreate()
601 @*/
602 PetscErrorCode  PetscContainerDestroy(PetscContainer obj)
603 {
604   PetscErrorCode ierr;
605   PetscFunctionBegin;
606   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
607   if (--((PetscObject)obj)->refct > 0) PetscFunctionReturn(0);
608   if (obj->userdestroy) (*obj->userdestroy)(obj->ptr);
609   ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr);
610   PetscFunctionReturn(0);
611 }
612 
613 #undef __FUNCT__
614 #define __FUNCT__ "PetscContainerSetUserDestroy"
615 /*@C
616    PetscContainerSetUserDestroy - Sets name of the user destroy function.
617 
618    Logically Collective on PetscContainer
619 
620    Input Parameter:
621 +  obj - an object that was created with PetscContainerCreate()
622 -  des - name of the user destroy function
623 
624    Level: advanced
625 
626 .seealso: PetscContainerDestroy()
627 @*/
628 PetscErrorCode  PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
629 {
630   PetscFunctionBegin;
631   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1);
632   obj->userdestroy = des;
633   PetscFunctionReturn(0);
634 }
635 
636 PetscClassId  PETSC_CONTAINER_CLASSID;
637 
638 #undef __FUNCT__
639 #define __FUNCT__ "PetscContainerCreate"
640 /*@C
641    PetscContainerCreate - Creates a PETSc object that has room to hold
642    a single pointer. This allows one to attach any type of data (accessible
643    through a pointer) with the PetscObjectCompose() function to a PetscObject.
644    The data item itself is attached by a call to PetscContainerSetPointer.
645 
646    Collective on MPI_Comm
647 
648    Input Parameters:
649 .  comm - MPI communicator that shares the object
650 
651    Output Parameters:
652 .  container - the container created
653 
654    Level: advanced
655 
656 .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
657 @*/
658 PetscErrorCode  PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
659 {
660   PetscErrorCode ierr;
661   PetscContainer contain;
662 
663   PetscFunctionBegin;
664   PetscValidPointer(container,2);
665   ierr = PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,0,"PetscContainer",comm,PetscContainerDestroy,0);CHKERRQ(ierr);
666   *container = contain;
667   PetscFunctionReturn(0);
668 }
669 
670 #undef __FUNCT__
671 #define __FUNCT__ "PetscObjectSetFromOptions"
672 /*@
673    PetscObjectSetFromOptions - Sets generic parameters from user options.
674 
675    Collective on obj
676 
677    Input Parameter:
678 .  obj - the PetscObjcet
679 
680    Options Database Keys:
681 
682    Notes:
683    We have no generic options at present, so this does nothing
684 
685    Level: beginner
686 
687 .keywords: set, options, database
688 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
689 @*/
690 PetscErrorCode  PetscObjectSetFromOptions(PetscObject obj)
691 {
692   PetscFunctionBegin;
693   PetscValidHeader(obj,1);
694   PetscFunctionReturn(0);
695 }
696 
697 #undef __FUNCT__
698 #define __FUNCT__ "PetscObjectSetUp"
699 /*@
700    PetscObjectSetUp - Sets up the internal data structures for the later use.
701 
702    Collective on PetscObject
703 
704    Input Parameters:
705 .  obj - the PetscObject
706 
707    Notes:
708    This does nothing at present.
709 
710    Level: advanced
711 
712 .keywords: setup
713 .seealso: PetscObjectDestroy()
714 @*/
715 PetscErrorCode  PetscObjectSetUp(PetscObject obj)
716 {
717   PetscFunctionBegin;
718   PetscValidHeader(obj,1);
719   PetscFunctionReturn(0);
720 }
721