Actual source code: inherit.c
1: /*
2: Provides utility routines for manipulating any type of PETSc object.
3: */
4: #include petsc.h
5: #include petscsys.h
7: EXTERN PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm *);
8: EXTERN PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject);
9: EXTERN PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject *);
10: EXTERN PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],const char[],void (*)(void));
11: EXTERN PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void));
12: EXTERN PetscErrorCode PetscObjectComposeLanguage_Petsc(PetscObject,PetscLanguage,void *);
13: EXTERN PetscErrorCode PetscObjectQueryLanguage_Petsc(PetscObject,PetscLanguage,void **);
17: /*
18: PetscHeaderCreate_Private - Creates a base PETSc object header and fills
19: in the default values. Called by the macro PetscHeaderCreate().
20: */
21: PetscErrorCode PetscHeaderCreate_Private(PetscObject h,PetscCookie cookie,PetscInt type,const char class_name[],MPI_Comm comm,
22: PetscErrorCode (*des)(PetscObject),PetscErrorCode (*vie)(PetscObject,PetscViewer))
23: {
24: static PetscInt idcnt = 1;
25: PetscErrorCode ierr;
28: h->cookie = cookie;
29: h->type = type;
30: h->class_name = (char*)class_name;
31: h->prefix = 0;
32: h->refct = 1;
33: h->amem = -1;
34: h->id = idcnt++;
35: h->parentid = 0;
36: h->qlist = 0;
37: h->olist = 0;
38: h->bops->destroy = des;
39: h->bops->view = vie;
40: h->bops->getcomm = PetscObjectGetComm_Petsc;
41: h->bops->compose = PetscObjectCompose_Petsc;
42: h->bops->query = PetscObjectQuery_Petsc;
43: h->bops->composefunction = PetscObjectComposeFunction_Petsc;
44: h->bops->queryfunction = PetscObjectQueryFunction_Petsc;
45: h->bops->querylanguage = PetscObjectQueryLanguage_Petsc;
46: h->bops->composelanguage = PetscObjectComposeLanguage_Petsc;
47: PetscCommDuplicate(comm,&h->comm,&h->tag);
48: return(0);
49: }
53: /*
54: PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
55: the macro PetscHeaderDestroy().
56: */
57: PetscErrorCode PetscHeaderDestroy_Private(PetscObject h)
58: {
62: PetscCommDestroy(&h->comm);
63: PetscFree(h->bops);
64: PetscFree(h->ops);
65: PetscOListDestroy(&h->olist);
66: PetscFListDestroy(&h->qlist);
67: PetscStrfree(h->type_name);
68: PetscStrfree(h->name);
69: h->cookie = PETSCFREEDHEADER;
70: PetscStrfree(h->prefix);
71: if (h->fortran_func_pointers) {
72: PetscFree(h->fortran_func_pointers);
73: }
74: if (h->intcomposeddata) {
75: PetscFree(h->intcomposeddata);
76: }
77: if (h->intcomposedstate) {
78: PetscFree(h->intcomposedstate);
79: }
80: if (h->realcomposeddata) {
81: PetscFree(h->realcomposeddata);
82: }
83: if (h->realcomposedstate) {
84: PetscFree(h->realcomposedstate);
85: }
86: if (h->scalarcomposeddata) {
87: PetscFree(h->scalarcomposeddata);
88: }
89: if (h->scalarcomposedstate) {
90: PetscFree(h->scalarcomposedstate);
91: }
92: PetscFree(h);
93: return(0);
94: }
98: /*@C
99: PetscObjectReference - Indicates to any PetscObject that it is being
100: referenced by another PetscObject. This increases the reference
101: count for that object by one.
103: Collective on PetscObject
105: Input Parameter:
106: . obj - the PETSc object. This must be cast with (PetscObject), for example,
107: PetscObjectReference((PetscObject)mat);
109: Level: advanced
111: .seealso: PetscObjectCompose(), PetscObjectDereference()
112: @*/
113: PetscErrorCode PetscObjectReference(PetscObject obj)
114: {
117: obj->refct++;
118: return(0);
119: }
123: /*@C
124: PetscObjectGetReference - Gets the current reference count for
125: any PETSc object.
127: Not Collective
129: Input Parameter:
130: . obj - the PETSc object; this must be cast with (PetscObject), for example,
131: PetscObjectGetReference((PetscObject)mat,&cnt);
133: Output Parameter:
134: . cnt - the reference count
136: Level: advanced
138: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
139: @*/
140: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
141: {
145: *cnt = obj->refct;
146: return(0);
147: }
151: /*@
152: PetscObjectDereference - Indicates to any PetscObject that it is being
153: referenced by one less PetscObject. This decreases the reference
154: count for that object by one.
156: Collective on PetscObject
158: Input Parameter:
159: . obj - the PETSc object; this must be cast with (PetscObject), for example,
160: PetscObjectDereference((PetscObject)mat);
162: Level: advanced
164: .seealso: PetscObjectCompose(), PetscObjectReference()
165: @*/
166: PetscErrorCode PetscObjectDereference(PetscObject obj)
167: {
172: if (obj->bops->destroy) {
173: (*obj->bops->destroy)(obj);
174: } else if (!--obj->refct) {
175: SETERRQ(PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
176: }
177: return(0);
178: }
180: /* ----------------------------------------------------------------------- */
181: /*
182: The following routines are the versions private to the PETSc object
183: data structures.
184: */
187: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
188: {
190: *comm = obj->comm;
191: return(0);
192: }
196: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
197: {
199: char *tname;
202: if (ptr) {
203: PetscOListReverseFind(ptr->olist,obj,&tname);
204: if (tname){
205: SETERRQ(PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was compose with it");
206: }
207: }
208: PetscOListAdd(&obj->olist,name,ptr);
209: return(0);
210: }
214: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
215: {
219: PetscOListFind(obj->olist,name,ptr);
220: return(0);
221: }
225: PetscErrorCode PetscObjectComposeLanguage_Petsc(PetscObject obj,PetscLanguage lang,void *vob)
226: {
228: if (lang == PETSC_LANGUAGE_CPP) {
229: obj->cpp = vob;
230: } else {
231: SETERRQ(PETSC_ERR_SUP,"No support for this language yet");
232: }
233: return(0);
234: }
238: PetscErrorCode PetscObjectQueryLanguage_Petsc(PetscObject obj,PetscLanguage lang,void **vob)
239: {
241: if (lang == PETSC_LANGUAGE_C) {
242: *vob = (void*)obj;
243: } else if (lang == PETSC_LANGUAGE_CPP) {
244: if (obj->cpp) {
245: *vob = obj->cpp;
246: } else {
247: SETERRQ(PETSC_ERR_SUP,"No C++ wrapper generated");
248: }
249: } else {
250: SETERRQ(PETSC_ERR_SUP,"No support for this language yet");
251: }
252: return(0);
253: }
257: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
258: {
262: PetscFListAdd(&obj->qlist,name,fname,ptr);
263: return(0);
264: }
268: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
269: {
273: PetscFListFind(obj->comm,obj->qlist,name,ptr);
274: return(0);
275: }
277: /*
278: These are the versions that are usable to any CCA compliant objects
279: */
282: /*@C
283: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
284:
285: Not Collective
287: Input Parameters:
288: + obj - the PETSc object; this must be cast with (PetscObject), for example,
289: PetscObjectCompose((PetscObject)mat,...);
290: . name - name associated with the child object
291: - ptr - the other PETSc object to associate with the PETSc object; this must also be
292: cast with (PetscObject)
294: Level: advanced
296: Notes:
297: The second objects reference count is automatically increased by one when it is
298: composed.
300: Replaces any previous object that had the same name.
302: If ptr is null and name has previously been composed using an object, then that
303: entry is removed from the obj.
305: PetscObjectCompose() can be used with any PETSc object (such as
306: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
307: PetscObjectContainerCreate() for info on how to create an object from a
308: user-provided pointer that may then be composed with PETSc objects.
309:
310: Concepts: objects^composing
311: Concepts: composing objects
313: .seealso: PetscObjectQuery(), PetscObjectContainerCreate()
314: @*/
315: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
316: {
320: (*obj->bops->compose)(obj,name,ptr);
321: return(0);
322: }
326: /*@C
327: PetscObjectQuery - Gets a PETSc object associated with a given object.
328:
329: Not Collective
331: Input Parameters:
332: + obj - the PETSc object
333: Thus must be cast with a (PetscObject), for example,
334: PetscObjectCompose((PetscObject)mat,...);
335: . name - name associated with child object
336: - ptr - the other PETSc object associated with the PETSc object, this must also be
337: cast with (PetscObject)
339: Level: advanced
341: Concepts: objects^composing
342: Concepts: composing objects
343: Concepts: objects^querying
344: Concepts: querying objects
346: .seealso: PetscObjectQuery()
347: @*/
348: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
349: {
353: (*obj->bops->query)(obj,name,ptr);
354: return(0);
355: }
359: /*@C
360: PetscObjectQueryLanguage - Returns a language specific interface to the given object
361:
362: Not Collective
364: Input Parameters:
365: + obj - the PETSc object
366: Thus must be cast with a (PetscObject), for example,
367: PetscObjectCompose((PetscObject)mat,...);
368: - lang - one of PETSC_LANGUAGE_C, PETSC_LANGUAGE_F77, PETSC_LANGUAGE_CPP
370: Output Parameter:
371: . ptr - the language specific interface
373: Level: developer
375: .seealso: PetscObjectQuery()
376: @*/
377: PetscErrorCode PetscObjectQueryLanguage(PetscObject obj,PetscLanguage lang,void **ptr)
378: {
382: (*obj->bops->querylanguage)(obj,lang,ptr);
383: return(0);
384: }
388: /*@C
389: PetscObjectComposeLanguage - Sets a language specific interface to the given object
390:
391: Not Collective
393: Input Parameters:
394: + obj - the PETSc object
395: Thus must be cast with a (PetscObject), for example,
396: PetscObjectCompose((PetscObject)mat,...);
397: . lang - one of PETSC_LANGUAGE_C, PETSC_LANGUAGE_F77, PETSC_LANGUAGE_CPP
398: - ptr - the language specific interface
400: Level: developer
402: .seealso: PetscObjectQuery()
403: @*/
404: PetscErrorCode PetscObjectComposeLanguage(PetscObject obj,PetscLanguage lang,void *ptr)
405: {
409: (*obj->bops->composelanguage)(obj,lang,ptr);
410: return(0);
411: }
416: PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
417: {
421: (*obj->bops->composefunction)(obj,name,fname,ptr);
422: return(0);
423: }
427: /*@C
428: PetscObjectQueryFunction - Gets a function associated with a given object.
429:
430: Collective on PetscObject
432: Input Parameters:
433: + obj - the PETSc object; this must be cast with (PetscObject), for example,
434: PetscObjectQueryFunction((PetscObject)ksp,...);
435: - name - name associated with the child function
437: Output Parameter:
438: . ptr - function pointer
440: Level: advanced
442: Concepts: objects^composing functions
443: Concepts: composing functions
444: Concepts: functions^querying
445: Concepts: objects^querying
446: Concepts: querying objects
448: .seealso: PetscObjectComposeFunctionDynamic()
449: @*/
450: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void))
451: {
455: (*obj->bops->queryfunction)(obj,name,ptr);
456: return(0);
457: }
459: struct _p_PetscObjectContainer {
460: PETSCHEADER(int)
461: void *ptr;
462: };
466: /*@C
467: PetscObjectContainerGetPointer - Gets the pointer value contained in the container.
469: Collective on PetscObjectContainer
471: Input Parameter:
472: . obj - the object created with PetscObjectContainerCreate()
474: Output Parameter:
475: . ptr - the pointer value
477: Level: advanced
479: .seealso: PetscObjectContainerCreate(), PetscObjectContainerDestroy(),
480: PetscObjectContainerSetPointer()
481: @*/
482: PetscErrorCode PetscObjectContainerGetPointer(PetscObjectContainer obj,void **ptr)
483: {
485: *ptr = obj->ptr;
486: return(0);
487: }
492: /*@C
493: PetscObjectContainerSetPointer - Sets the pointer value contained in the container.
495: Collective on PetscObjectContainer
497: Input Parameters:
498: + obj - the object created with PetscObjectContainerCreate()
499: - ptr - the pointer value
501: Level: advanced
503: .seealso: PetscObjectContainerCreate(), PetscObjectContainerDestroy(),
504: PetscObjectContainerGetPointer()
505: @*/
506: PetscErrorCode PetscObjectContainerSetPointer(PetscObjectContainer obj,void *ptr)
507: {
509: obj->ptr = ptr;
510: return(0);
511: }
515: /*@C
516: PetscObjectContainerDestroy - Destroys a PETSc container object.
518: Collective on PetscObjectContainer
520: Input Parameter:
521: . obj - an object that was created with PetscObjectContainerCreate()
523: Level: advanced
525: .seealso: PetscObjectContainerCreate()
526: @*/
527: PetscErrorCode PetscObjectContainerDestroy(PetscObjectContainer obj)
528: {
530: if (--obj->refct > 0) return(0);
531: PetscHeaderDestroy(obj);
532: return(0);
533: }
537: /*@C
538: PetscObjectContainerCreate - Creates a PETSc object that has room to hold
539: a single pointer. This allows one to attach any type of data (accessible
540: through a pointer) with the PetscObjectCompose() function to a PetscObject.
541: The data item itself is attached by a call to PetscObjectContainerSetPointer.
543: Collective on MPI_Comm
545: Input Parameters:
546: . comm - MPI communicator that shares the object
548: Output Parameters:
549: . container - the container created
551: Level: advanced
553: .seealso: PetscObjectContainerDestroy(), PetscObjectContainerSetPointer(), PetscObjectContainerSetPointer()
554: @*/
555: PetscErrorCode PetscObjectContainerCreate(MPI_Comm comm,PetscObjectContainer *container)
556: {
557: PetscObjectContainer contain;
560: PetscHeaderCreate(contain,_p_PetscObjectContainer,PetscInt,PETSC_COOKIE,0,"container",comm,PetscObjectContainerDestroy,0);
561: *container = contain;
562: return(0);
563: }