Actual source code: inherit.c
1: #define PETSC_DLL
2: /*
3: Provides utility routines for manipulating any type of PETSc object.
4: */
5: #include petsc.h
6: #include petscsys.h
8: EXTERN PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm *);
9: EXTERN PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject);
10: EXTERN PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject *);
11: EXTERN PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],const char[],void (*)(void));
12: EXTERN PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void));
13: EXTERN PetscErrorCode PetscObjectComposeLanguage_Petsc(PetscObject,PetscLanguage,void *);
14: EXTERN PetscErrorCode PetscObjectQueryLanguage_Petsc(PetscObject,PetscLanguage,void **);
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 PETSC_DLLEXPORT PetscHeaderCreate_Private(PetscObject h,PetscCookie cookie,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;
29: h->cookie = cookie;
30: h->type = type;
31: h->class_name = (char*)class_name;
32: h->prefix = 0;
33: h->refct = 1;
34: h->amem = -1;
35: h->id = idcnt++;
36: h->parentid = 0;
37: h->qlist = 0;
38: h->olist = 0;
39: h->bops->destroy = des;
40: h->bops->view = vie;
41: h->bops->getcomm = PetscObjectGetComm_Petsc;
42: h->bops->compose = PetscObjectCompose_Petsc;
43: h->bops->query = PetscObjectQuery_Petsc;
44: h->bops->composefunction = PetscObjectComposeFunction_Petsc;
45: h->bops->queryfunction = PetscObjectQueryFunction_Petsc;
46: h->bops->querylanguage = PetscObjectQueryLanguage_Petsc;
47: h->bops->composelanguage = PetscObjectComposeLanguage_Petsc;
48: PetscCommDuplicate(comm,&h->comm,&h->tag);
49: return(0);
50: }
57: /*
58: PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
59: the macro PetscHeaderDestroy().
60: */
61: PetscErrorCode PETSC_DLLEXPORT PetscHeaderDestroy_Private(PetscObject h)
62: {
66: if (PetscMemoryCollectMaximumUsage) {
67: PetscLogDouble usage;
68: PetscMemoryGetCurrentUsage(&usage);
69: if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
70: }
71: PetscCommDestroy(&h->comm);
72: PetscFree(h->bops);
73: PetscFree(h->ops);
74: PetscOListDestroy(&h->olist);
75: PetscFListDestroy(&h->qlist);
76: PetscStrfree(h->type_name);
77: PetscStrfree(h->name);
78: h->cookie = PETSCFREEDHEADER;
79: PetscStrfree(h->prefix);
80: if (h->fortran_func_pointers) {
81: PetscFree(h->fortran_func_pointers);
82: }
83: if (h->intcomposeddata) {
84: PetscFree(h->intcomposeddata);
85: }
86: if (h->intcomposedstate) {
87: PetscFree(h->intcomposedstate);
88: }
89: if (h->realcomposeddata) {
90: PetscFree(h->realcomposeddata);
91: }
92: if (h->realcomposedstate) {
93: PetscFree(h->realcomposedstate);
94: }
95: if (h->scalarcomposeddata) {
96: PetscFree(h->scalarcomposeddata);
97: }
98: if (h->scalarcomposedstate) {
99: PetscFree(h->scalarcomposedstate);
100: }
101: return(0);
102: }
106: /*@C
107: PetscObjectReference - Indicates to any PetscObject that it is being
108: referenced by another PetscObject. This increases the reference
109: count for that object by one.
111: Collective on PetscObject
113: Input Parameter:
114: . obj - the PETSc object. This must be cast with (PetscObject), for example,
115: PetscObjectReference((PetscObject)mat);
117: Level: advanced
119: .seealso: PetscObjectCompose(), PetscObjectDereference()
120: @*/
121: PetscErrorCode PETSC_DLLEXPORT PetscObjectReference(PetscObject obj)
122: {
125: obj->refct++;
126: return(0);
127: }
131: /*@C
132: PetscObjectGetReference - Gets the current reference count for
133: any PETSc object.
135: Not Collective
137: Input Parameter:
138: . obj - the PETSc object; this must be cast with (PetscObject), for example,
139: PetscObjectGetReference((PetscObject)mat,&cnt);
141: Output Parameter:
142: . cnt - the reference count
144: Level: advanced
146: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
147: @*/
148: PetscErrorCode PETSC_DLLEXPORT PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
149: {
153: *cnt = obj->refct;
154: return(0);
155: }
159: /*@
160: PetscObjectDereference - Indicates to any PetscObject that it is being
161: referenced by one less PetscObject. This decreases the reference
162: count for that object by one.
164: Collective on PetscObject
166: Input Parameter:
167: . obj - the PETSc object; this must be cast with (PetscObject), for example,
168: PetscObjectDereference((PetscObject)mat);
170: Level: advanced
172: .seealso: PetscObjectCompose(), PetscObjectReference()
173: @*/
174: PetscErrorCode PETSC_DLLEXPORT PetscObjectDereference(PetscObject obj)
175: {
180: if (obj->bops->destroy) {
181: (*obj->bops->destroy)(obj);
182: } else if (!--obj->refct) {
183: SETERRQ(PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
184: }
185: return(0);
186: }
188: /* ----------------------------------------------------------------------- */
189: /*
190: The following routines are the versions private to the PETSc object
191: data structures.
192: */
195: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
196: {
198: *comm = obj->comm;
199: return(0);
200: }
204: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
205: {
207: char *tname;
210: if (ptr) {
211: PetscOListReverseFind(ptr->olist,obj,&tname);
212: if (tname){
213: SETERRQ(PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was compose with it");
214: }
215: }
216: PetscOListAdd(&obj->olist,name,ptr);
217: return(0);
218: }
222: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
223: {
227: PetscOListFind(obj->olist,name,ptr);
228: return(0);
229: }
233: PetscErrorCode PetscObjectComposeLanguage_Petsc(PetscObject obj,PetscLanguage lang,void *vob)
234: {
236: if (lang == PETSC_LANGUAGE_CXX) {
237: obj->cpp = vob;
238: } else {
239: SETERRQ(PETSC_ERR_SUP,"No support for this language yet");
240: }
241: return(0);
242: }
246: PetscErrorCode PetscObjectQueryLanguage_Petsc(PetscObject obj,PetscLanguage lang,void **vob)
247: {
249: if (lang == PETSC_LANGUAGE_C) {
250: *vob = (void*)obj;
251: } else if (lang == PETSC_LANGUAGE_CXX) {
252: if (obj->cpp) {
253: *vob = obj->cpp;
254: } else {
255: SETERRQ(PETSC_ERR_SUP,"No C++ wrapper generated");
256: }
257: } else {
258: SETERRQ(PETSC_ERR_SUP,"No support for this language yet");
259: }
260: return(0);
261: }
265: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
266: {
270: PetscFListAdd(&obj->qlist,name,fname,ptr);
271: return(0);
272: }
276: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
277: {
281: PetscFListFind(obj->comm,obj->qlist,name,ptr);
282: return(0);
283: }
285: /*
286: These are the versions that are usable to any CCA compliant objects
287: */
290: /*@C
291: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
292:
293: Not Collective
295: Input Parameters:
296: + obj - the PETSc object; this must be cast with (PetscObject), for example,
297: PetscObjectCompose((PetscObject)mat,...);
298: . name - name associated with the child object
299: - ptr - the other PETSc object to associate with the PETSc object; this must also be
300: cast with (PetscObject)
302: Level: advanced
304: Notes:
305: The second objects reference count is automatically increased by one when it is
306: composed.
308: Replaces any previous object that had the same name.
310: If ptr is null and name has previously been composed using an object, then that
311: entry is removed from the obj.
313: PetscObjectCompose() can be used with any PETSc object (such as
314: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
315: PetscObjectContainerCreate() for info on how to create an object from a
316: user-provided pointer that may then be composed with PETSc objects.
317:
318: Concepts: objects^composing
319: Concepts: composing objects
321: .seealso: PetscObjectQuery(), PetscObjectContainerCreate()
322: @*/
323: PetscErrorCode PETSC_DLLEXPORT PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
324: {
328: (*obj->bops->compose)(obj,name,ptr);
329: return(0);
330: }
334: /*@C
335: PetscObjectQuery - Gets a PETSc object associated with a given object.
336:
337: Not Collective
339: Input Parameters:
340: + obj - the PETSc object
341: Thus must be cast with a (PetscObject), for example,
342: PetscObjectCompose((PetscObject)mat,...);
343: . name - name associated with child object
344: - ptr - the other PETSc object associated with the PETSc object, this must also be
345: cast with (PetscObject)
347: Level: advanced
349: Concepts: objects^composing
350: Concepts: composing objects
351: Concepts: objects^querying
352: Concepts: querying objects
354: .seealso: PetscObjectQuery()
355: @*/
356: PetscErrorCode PETSC_DLLEXPORT PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
357: {
361: (*obj->bops->query)(obj,name,ptr);
362: return(0);
363: }
367: /*@C
368: PetscObjectQueryLanguage - Returns a language specific interface to the given object
369:
370: Not Collective
372: Input Parameters:
373: + obj - the PETSc object
374: Thus must be cast with a (PetscObject), for example,
375: PetscObjectCompose((PetscObject)mat,...);
376: - lang - one of PETSC_LANGUAGE_C, PETSC_LANGUAGE_F77, PETSC_LANGUAGE_CXX
378: Output Parameter:
379: . ptr - the language specific interface
381: Level: developer
383: .seealso: PetscObjectQuery()
384: @*/
385: PetscErrorCode PETSC_DLLEXPORT PetscObjectQueryLanguage(PetscObject obj,PetscLanguage lang,void **ptr)
386: {
390: (*obj->bops->querylanguage)(obj,lang,ptr);
391: return(0);
392: }
396: /*@C
397: PetscObjectComposeLanguage - Sets a language specific interface to the given object
398:
399: Not Collective
401: Input Parameters:
402: + obj - the PETSc object
403: Thus must be cast with a (PetscObject), for example,
404: PetscObjectCompose((PetscObject)mat,...);
405: . lang - one of PETSC_LANGUAGE_C, PETSC_LANGUAGE_F77, PETSC_LANGUAGE_CXX
406: - ptr - the language specific interface
408: Level: developer
410: .seealso: PetscObjectQuery()
411: @*/
412: PetscErrorCode PETSC_DLLEXPORT PetscObjectComposeLanguage(PetscObject obj,PetscLanguage lang,void *ptr)
413: {
417: (*obj->bops->composelanguage)(obj,lang,ptr);
418: return(0);
419: }
424: PetscErrorCode PETSC_DLLEXPORT PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
425: {
429: (*obj->bops->composefunction)(obj,name,fname,ptr);
430: return(0);
431: }
435: /*@C
436: PetscObjectQueryFunction - Gets a function associated with a given object.
437:
438: Collective on PetscObject
440: Input Parameters:
441: + obj - the PETSc object; this must be cast with (PetscObject), for example,
442: PetscObjectQueryFunction((PetscObject)ksp,...);
443: - name - name associated with the child function
445: Output Parameter:
446: . ptr - function pointer
448: Level: advanced
450: Concepts: objects^composing functions
451: Concepts: composing functions
452: Concepts: functions^querying
453: Concepts: objects^querying
454: Concepts: querying objects
456: .seealso: PetscObjectComposeFunctionDynamic()
457: @*/
458: PetscErrorCode PETSC_DLLEXPORT PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void))
459: {
463: (*obj->bops->queryfunction)(obj,name,ptr);
464: return(0);
465: }
467: struct _p_PetscObjectContainer {
468: PETSCHEADER(int);
469: void *ptr;
470: PetscErrorCode (*userdestroy)(void*);
471: };
475: /*@C
476: PetscObjectContainerGetPointer - Gets the pointer value contained in the container.
478: Collective on PetscObjectContainer
480: Input Parameter:
481: . obj - the object created with PetscObjectContainerCreate()
483: Output Parameter:
484: . ptr - the pointer value
486: Level: advanced
488: .seealso: PetscObjectContainerCreate(), PetscObjectContainerDestroy(),
489: PetscObjectContainerSetPointer()
490: @*/
491: PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerGetPointer(PetscObjectContainer obj,void **ptr)
492: {
494: *ptr = obj->ptr;
495: return(0);
496: }
501: /*@C
502: PetscObjectContainerSetPointer - Sets the pointer value contained in the container.
504: Collective on PetscObjectContainer
506: Input Parameters:
507: + obj - the object created with PetscObjectContainerCreate()
508: - ptr - the pointer value
510: Level: advanced
512: .seealso: PetscObjectContainerCreate(), PetscObjectContainerDestroy(),
513: PetscObjectContainerGetPointer()
514: @*/
515: PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerSetPointer(PetscObjectContainer obj,void *ptr)
516: {
518: obj->ptr = ptr;
519: return(0);
520: }
524: /*@C
525: PetscObjectContainerDestroy - Destroys a PETSc container object.
527: Collective on PetscObjectContainer
529: Input Parameter:
530: . obj - an object that was created with PetscObjectContainerCreate()
532: Level: advanced
534: .seealso: PetscObjectContainerCreate()
535: @*/
536: PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerDestroy(PetscObjectContainer obj)
537: {
540: if (--obj->refct > 0) return(0);
541: if (obj->userdestroy) (*obj->userdestroy)(obj->ptr);
542: PetscHeaderDestroy(obj);
543: return(0);
544: }
548: /*@C
549: PetscObjectContainerSetUserDestroy - Sets name of the user destroy function.
551: Collective on PetscObjectContainer
553: Input Parameter:
554: + obj - an object that was created with PetscObjectContainerCreate()
555: - des - name of the user destroy function
557: Level: advanced
559: .seealso: PetscObjectContainerDestroy()
560: @*/
561: PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerSetUserDestroy(PetscObjectContainer obj, PetscErrorCode (*des)(void*))
562: {
564: obj->userdestroy = des;
565: return(0);
566: }
568: PetscCookie PETSC_DLLEXPORT CONTAINER_COOKIE = 0;
572: /*@C
573: PetscObjectContainerCreate - Creates a PETSc object that has room to hold
574: a single pointer. This allows one to attach any type of data (accessible
575: through a pointer) with the PetscObjectCompose() function to a PetscObject.
576: The data item itself is attached by a call to PetscObjectContainerSetPointer.
578: Collective on MPI_Comm
580: Input Parameters:
581: . comm - MPI communicator that shares the object
583: Output Parameters:
584: . container - the container created
586: Level: advanced
588: .seealso: PetscObjectContainerDestroy(), PetscObjectContainerSetPointer(), PetscObjectContainerSetPointer()
589: @*/
590: PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerCreate(MPI_Comm comm,PetscObjectContainer *container)
591: {
592: PetscErrorCode ierr;
593: PetscObjectContainer contain;
596: if (!CONTAINER_COOKIE) {
597: PetscLogClassRegister(&CONTAINER_COOKIE, "Container");
598: }
599: PetscHeaderCreate(contain,_p_PetscObjectContainer,PetscInt,CONTAINER_COOKIE,0,"container",comm,PetscObjectContainerDestroy,0);
600: *container = contain;
601: return(0);
602: }
606: /*@
607: PetscObjectSetFromOptions - Sets generic parameters from user options.
609: Collective on obj
611: Input Parameter:
612: . obj - the PetscObjcet
614: Options Database Keys:
616: Notes:
617: We have no generic options at present, so this does nothing
619: Level: beginner
621: .keywords: set, options, database
622: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
623: @*/
624: PetscErrorCode PETSC_DLLEXPORT PetscObjectSetFromOptions(PetscObject obj)
625: {
627: if (!obj) SETERRQ(PETSC_ERR_ARG_CORRUPT, "Null object");
628: return(0);
629: }
633: /*@
634: PetscObjectSetUp - Sets up the internal data structures for the later use.
636: Collective on PetscObject
638: Input Parameters:
639: . obj - the PetscObject
641: Notes:
642: This does nothing at present.
644: Level: advanced
646: .keywords: setup
647: .seealso: PetscObjectDestroy()
648: @*/
649: PetscErrorCode PETSC_DLLEXPORT PetscObjectSetUp(PetscObject obj)
650: {
652: if (!obj) SETERRQ(PETSC_ERR_ARG_CORRUPT, "Null object");
653: return(0);
654: }