Actual source code: inherit.c
1: /*$Id: inherit.c,v 1.70 2001/06/21 21:15:31 bsmith Exp $*/
2: /*
3: Provides utility routines for manipulating any type of PETSc object.
4: */
5: #include petsc.h
6: #include petscsys.h
8: EXTERN int PetscObjectGetComm_Petsc(PetscObject,MPI_Comm *);
9: EXTERN int PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject);
10: EXTERN int PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject *);
11: EXTERN int PetscObjectComposeFunction_Petsc(PetscObject,const char[],const char[],void (*)(void));
12: EXTERN int PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void));
13: EXTERN int PetscObjectComposeLanguage_Petsc(PetscObject,PetscLanguage,void *);
14: EXTERN int PetscObjectQueryLanguage_Petsc(PetscObject,PetscLanguage,void **);
16: #undef __FUNCT__
18: /*
19: PetscHeaderCreate_Private - Creates a base PETSc object header and fills
20: in the default values. Called by the macro PetscHeaderCreate().
21: */
22: int PetscHeaderCreate_Private(PetscObject h,int cookie,int type,char *class_name,MPI_Comm comm,
23: int (*des)(PetscObject),int (*vie)(PetscObject,PetscViewer))
24: {
25: static int idcnt = 1;
26: int ierr;
29: h->cookie = cookie;
30: h->type = type;
31: h->class_name = 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_Private(comm,&h->comm,&h->tag);
49: return(0);
50: }
52: #undef __FUNCT__
54: /*
55: PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
56: the macro PetscHeaderDestroy().
57: */
58: int PetscHeaderDestroy_Private(PetscObject h)
59: {
63: if (h->amem != -1) {
64: SETERRQ(1,"PETSc object destroyed before its AMS publication was destroyed");
65: }
67: PetscCommDestroy_Private(&h->comm);
68: PetscFree(h->bops);
69: PetscFree(h->ops);
70: PetscOListDestroy(&h->olist);
71: PetscFListDestroy(&h->qlist);
72: PetscStrfree(h->type_name);
73: PetscStrfree(h->serialize_name);
74: PetscStrfree(h->name);
75: h->cookie = PETSCFREEDHEADER;
76: PetscStrfree(h->prefix);
77: if (h->dict) {
78: ParameterDictDestroy(h->dict);
79: }
80: if (h->fortran_func_pointers) {
81: PetscFree(h->fortran_func_pointers);
82: }
83: PetscFree(h);
84: return(0);
85: }
87: #undef __FUNCT__
89: /*@C
90: PetscObjectReference - Indicates to any PetscObject that it is being
91: referenced by another PetscObject. This increases the reference
92: count for that object by one.
94: Collective on PetscObject
96: Input Parameter:
97: . obj - the PETSc object. This must be cast with (PetscObject), for example,
98: PetscObjectReference((PetscObject)mat);
100: Level: advanced
102: .seealso: PetscObjectCompose(), PetscObjectDereference()
103: @*/
104: int PetscObjectReference(PetscObject obj)
105: {
108: obj->refct++;
109: return(0);
110: }
112: #undef __FUNCT__
114: /*@C
115: PetscObjectGetReference - Gets the current reference count for
116: any PETSc object.
118: Not Collective
120: Input Parameter:
121: . obj - the PETSc object; this must be cast with (PetscObject), for example,
122: PetscObjectGetReference((PetscObject)mat,&cnt);
124: Output Parameter:
125: . cnt - the reference count
127: Level: advanced
129: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
130: @*/
131: int PetscObjectGetReference(PetscObject obj,int *cnt)
132: {
135: *cnt = obj->refct;
136: return(0);
137: }
139: #undef __FUNCT__
141: /*@
142: PetscObjectDereference - Indicates to any PetscObject that it is being
143: referenced by one less PetscObject. This decreases the reference
144: count for that object by one.
146: Collective on PetscObject
148: Input Parameter:
149: . obj - the PETSc object; this must be cast with (PetscObject), for example,
150: PetscObjectDereference((PetscObject)mat);
152: Level: advanced
154: .seealso: PetscObjectCompose(), PetscObjectReference()
155: @*/
156: int PetscObjectDereference(PetscObject obj)
157: {
162: if (obj->bops->destroy) {
163: (*obj->bops->destroy)(obj);
164: } else if (!--obj->refct) {
165: SETERRQ(PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
166: }
167: return(0);
168: }
170: /* ----------------------------------------------------------------------- */
171: /*
172: The following routines are the versions private to the PETSc object
173: data structures.
174: */
175: #undef __FUNCT__
177: int PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
178: {
180: *comm = obj->comm;
181: return(0);
182: }
184: #undef __FUNCT__
186: int PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
187: {
188: int ierr;
189: char *tname;
192: if (ptr) {
193: PetscOListReverseFind(ptr->olist,obj,&tname);
194: if (tname){
195: SETERRQ(1,"An object cannot be composed with an object that was compose with it");
196: }
197: }
198: PetscOListAdd(&obj->olist,name,ptr);
199: return(0);
200: }
202: #undef __FUNCT__
204: int PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
205: {
209: PetscOListFind(obj->olist,name,ptr);
210: return(0);
211: }
213: #undef __FUNCT__
215: int PetscObjectComposeLanguage_Petsc(PetscObject obj,PetscLanguage lang,void *vob)
216: {
218: if (lang == PETSC_LANGUAGE_CPP) {
219: obj->cpp = vob;
220: } else {
221: SETERRQ(1,"No support for this language yet");
222: }
223: return(0);
224: }
226: #undef __FUNCT__
228: int PetscObjectQueryLanguage_Petsc(PetscObject obj,PetscLanguage lang,void **vob)
229: {
231: if (lang == PETSC_LANGUAGE_C) {
232: *vob = (void*)obj;
233: } else if (lang == PETSC_LANGUAGE_CPP) {
234: if (obj->cpp) {
235: *vob = obj->cpp;
236: } else {
237: SETERRQ(1,"No C++ wrapper generated");
238: }
239: } else {
240: SETERRQ(1,"No support for this language yet");
241: }
242: return(0);
243: }
245: #undef __FUNCT__
247: int PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
248: {
252: PetscFListAddDynamic(&obj->qlist,name,fname,ptr);
253: return(0);
254: }
256: #undef __FUNCT__
258: int PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
259: {
263: PetscFListFind(obj->comm,obj->qlist,name,ptr);
264: return(0);
265: }
267: /*
268: These are the versions that are usable to any CCA compliant objects
269: */
270: #undef __FUNCT__
272: /*@C
273: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
274:
275: Not Collective
277: Input Parameters:
278: + obj - the PETSc object; this must be cast with (PetscObject), for example,
279: PetscObjectCompose((PetscObject)mat,...);
280: . name - name associated with the child object
281: - ptr - the other PETSc object to associate with the PETSc object; this must also be
282: cast with (PetscObject)
284: Level: advanced
286: Notes:
287: The second objects reference count is automatically increased by one when it is
288: composed.
290: Replaces any previous object that had the same name.
292: If ptr is null and name has previously been composed using an object, then that
293: entry is removed from the obj.
295: PetscObjectCompose() can be used with any PETSc object (such as
296: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
297: PetscObjectContainerCreate() for info on how to create an object from a
298: user-provided pointer that may then be composed with PETSc objects.
299:
300: Concepts: objects^composing
301: Concepts: composing objects
303: .seealso: PetscObjectQuery(), PetscObjectContainerCreate()
304: @*/
305: int PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
306: {
310: (*obj->bops->compose)(obj,name,ptr);
311: return(0);
312: }
314: #undef __FUNCT__
316: /*@C
317: PetscObjectQuery - Gets a PETSc object associated with a given object.
318:
319: Not Collective
321: Input Parameters:
322: + obj - the PETSc object
323: Thus must be cast with a (PetscObject), for example,
324: PetscObjectCompose((PetscObject)mat,...);
325: . name - name associated with child object
326: - ptr - the other PETSc object associated with the PETSc object, this must also be
327: cast with (PetscObject)
329: Level: advanced
331: Concepts: objects^composing
332: Concepts: composing objects
333: Concepts: objects^querying
334: Concepts: querying objects
336: .seealso: PetscObjectQuery()
337: @*/
338: int PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
339: {
343: (*obj->bops->query)(obj,name,ptr);
344: return(0);
345: }
347: #undef __FUNCT__
349: /*@C
350: PetscObjectQueryLanguage - Returns a language specific interface to the given object
351:
352: Not Collective
354: Input Parameters:
355: + obj - the PETSc object
356: Thus must be cast with a (PetscObject), for example,
357: PetscObjectCompose((PetscObject)mat,...);
358: - lang - one of PETSC_LANGUAGE_C, PETSC_LANGUAGE_F77, PETSC_LANGUAGE_CPP
360: Output Parameter:
361: . ptr - the language specific interface
363: Level: developer
365: .seealso: PetscObjectQuery()
366: @*/
367: int PetscObjectQueryLanguage(PetscObject obj,PetscLanguage lang,void **ptr)
368: {
372: (*obj->bops->querylanguage)(obj,lang,ptr);
373: return(0);
374: }
376: #undef __FUNCT__
378: /*@C
379: PetscObjectComposeLanguage - Sets a language specific interface to the given object
380:
381: Not Collective
383: Input Parameters:
384: + obj - the PETSc object
385: Thus must be cast with a (PetscObject), for example,
386: PetscObjectCompose((PetscObject)mat,...);
387: . lang - one of PETSC_LANGUAGE_C, PETSC_LANGUAGE_F77, PETSC_LANGUAGE_CPP
388: - ptr - the language specific interface
390: Level: developer
392: .seealso: PetscObjectQuery()
393: @*/
394: int PetscObjectComposeLanguage(PetscObject obj,PetscLanguage lang,void *ptr)
395: {
399: (*obj->bops->composelanguage)(obj,lang,ptr);
400: return(0);
401: }
404: #undef __FUNCT__
406: int PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
407: {
411: (*obj->bops->composefunction)(obj,name,fname,ptr);
412: return(0);
413: }
415: #undef __FUNCT__
417: /*@C
418: PetscObjectQueryFunction - Gets a function associated with a given object.
419:
420: Collective on PetscObject
422: Input Parameters:
423: + obj - the PETSc object; this must be cast with (PetscObject), for example,
424: PetscObjectQueryFunction((PetscObject)ksp,...);
425: - name - name associated with the child function
427: Output Parameter:
428: . ptr - function pointer
430: Level: advanced
432: Concepts: objects^composing functions
433: Concepts: composing functions
434: Concepts: functions^querying
435: Concepts: objects^querying
436: Concepts: querying objects
438: .seealso: PetscObjectComposeFunctionDynamic()
439: @*/
440: int PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void))
441: {
445: (*obj->bops->queryfunction)(obj,name,ptr);
446: return(0);
447: }
449: #undef __FUNCT__
451: /*@C
452: PetscObjectSetParameterDict - Sets a parameter dictionary for an object
454: Input Parameters:
455: + obj - The PetscObject
456: - dict - The ParameterDict
458: Level: intermediate
460: .seealso PetscObjectGetParameterDict()
461: @*/
462: int PetscObjectSetParameterDict(PetscObject obj, ParameterDict dict) {
467: if (obj->dict != PETSC_NULL) {
468: PetscObjectDereference((PetscObject) obj->dict);
469: }
470: if (dict != PETSC_NULL) {
471: PetscObjectReference((PetscObject) dict);
472: }
473: obj->dict = dict;
474: return(0);
475: }
477: #undef __FUNCT__
479: /*@C
480: PetscObjectGetParameterDict - Gets the parameter dictionary for an object
482: Input Parameter:
483: . obj - The PetscObject
485: Output Parameter:
486: . dict - The ParameterDict
488: Level: intermediate
490: .seealso PetscObjectSetParameterDict()
491: @*/
492: int PetscObjectGetParameterDict(PetscObject obj, ParameterDict *dict) {
496: *dict = obj->dict;
497: return(0);
498: }
500: struct _p_PetscObjectContainer {
501: PETSCHEADER(int)
502: void *ptr;
503: };
505: #undef __FUNCT__
507: /*@C
508: PetscObjectContainerGetPointer - Gets the pointer value contained in the container.
510: Collective on PetscObjectContainer
512: Input Parameter:
513: . obj - the object created with PetscObjectContainerCreate()
515: Output Parameter:
516: . ptr - the pointer value
518: Level: advanced
520: .seealso: PetscObjectContainerCreate(), PetscObjectContainerDestroy(),
521: PetscObjectContainerSetPointer()
522: @*/
523: int PetscObjectContainerGetPointer(PetscObjectContainer obj,void **ptr)
524: {
526: *ptr = obj->ptr;
527: return(0);
528: }
531: #undef __FUNCT__
533: /*@C
534: PetscObjectContainerSetPointer - Sets the pointer value contained in the container.
536: Collective on PetscObjectContainer
538: Input Parameters:
539: + obj - the object created with PetscObjectContainerCreate()
540: - ptr - the pointer value
542: Level: advanced
544: .seealso: PetscObjectContainerCreate(), PetscObjectContainerDestroy(),
545: PetscObjectContainerGetPointer()
546: @*/
547: int PetscObjectContainerSetPointer(PetscObjectContainer obj,void *ptr)
548: {
550: obj->ptr = ptr;
551: return(0);
552: }
554: #undef __FUNCT__
556: /*@C
557: PetscObjectContainerDestroy - Destroys a PETSc container object.
559: Collective on PetscObjectContainer
561: Input Parameter:
562: . obj - an object that was created with PetscObjectContainerCreate()
564: Level: advanced
566: .seealso: PetscObjectContainerCreate()
567: @*/
568: int PetscObjectContainerDestroy(PetscObjectContainer obj)
569: {
571: if (--obj->refct > 0) return(0);
572: PetscHeaderDestroy(obj);
573: return(0);
574: }
576: #undef __FUNCT__
578: /*@C
579: PetscObjectContainerCreate - Creates a PETSc object that has room to hold
580: a single pointer. This allows one to attach any type of data (accessible
581: through a pointer) with the PetscObjectCompose() function to a PetscObject.
583: Collective on MPI_Comm
585: Input Parameters:
586: . comm - MPI communicator that shares the object
588: Level: advanced
590: .seealso: PetscObjectContainerDestroy()
591: @*/
592: int PetscObjectContainerCreate(MPI_Comm comm,PetscObjectContainer *container)
593: {
594: PetscObjectContainer contain;
597: PetscHeaderCreate(contain,_p_PetscObjectContainer,int,PETSC_COOKIE,0,"container",comm,PetscObjectContainerDestroy,0);
598: *container = contain;
599: return(0);
600: }
602: /*MC
603: PetscObjectComposeFunctionDynamic - Associates a function with a given PETSc object.
604:
605: Collective on PetscObject
607: Input Parameters:
608: + obj - the PETSc object; this must be cast with a (PetscObject), for example,
609: PetscObjectCompose((PetscObject)mat,...);
610: . name - name associated with the child function
611: . fname - name of the function
612: - ptr - function pointer (or PETSC_NULL if using dynamic libraries)
614: Level: advanced
616: Synopsis:
617: int PetscObjectComposeFunctionDynamic(PetscObject obj,char *name,char *fname,void *ptr)
619: Notes:
620: PetscObjectComposeFunctionDynamic() can be used with any PETSc object (such as
621: Mat, Vec, KSP, SNES, etc.) or any user-provided object.
623: The composed function must be wrapped in a EXTERN_C_BEGIN/END for this to
624: work in C++/complex with dynamic link libraries (PETSC_USE_DYNAMIC_LIBRARIES)
625: enabled.
627: Concepts: objects^composing functions
628: Concepts: composing functions
629: Concepts: functions^querying
630: Concepts: objects^querying
631: Concepts: querying objects
633: .seealso: PetscObjectQueryFunction()
634: M*/