Actual source code: inherit.c
petsc-3.3-p7 2013-05-11
2: /*
3: Provides utility routines for manipulating any type of PETSc object.
4: */
5: #include <petscsys.h> /*I "petscsys.h" I*/
7: PetscObject *PetscObjects = 0;
8: PetscInt PetscObjectsCounts = 0, PetscObjectsMaxCounts = 0;
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));
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;
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(PetscScalar);
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: PetscCommDuplicate(comm,&h->comm,&h->tag);
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: return(0);
59: }
60: }
61: /* Need to increase the space for storing PETSc objects */
62: if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100;
63: else newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts;
64: PetscMalloc(newPetscObjectsMaxCounts*sizeof(PetscObject),&newPetscObjects);
65: PetscMemcpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts*sizeof(PetscObject));
66: PetscMemzero(newPetscObjects+PetscObjectsMaxCounts,(newPetscObjectsMaxCounts - PetscObjectsMaxCounts)*sizeof(PetscObject));
67: PetscFree(PetscObjects);
68: PetscObjects = newPetscObjects;
69: PetscObjects[PetscObjectsMaxCounts] = h;
70: PetscObjectsMaxCounts = newPetscObjectsMaxCounts;
72: return(0);
73: }
75: extern PetscBool PetscMemoryCollectMaximumUsage;
76: extern PetscLogDouble PetscMemoryMaximumUsage;
80: /*
81: PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
82: the macro PetscHeaderDestroy().
83: */
84: PetscErrorCode PetscHeaderDestroy_Private(PetscObject h)
85: {
87: PetscInt i;
91: #if defined(PETSC_HAVE_AMS)
92: if (PetscAMSPublishAll) {
93: PetscObjectUnPublish((PetscObject)h);
94: }
95: #endif
96: if (PetscMemoryCollectMaximumUsage) {
97: PetscLogDouble usage;
98: PetscMemoryGetCurrentUsage(&usage);
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: (*python_destroy)(python_context);
108: }
109: PetscOListDestroy(&h->olist);
110: PetscCommDestroy(&h->comm);
111: /* next destroy other things */
112: h->classid = PETSCFREEDHEADER;
113: PetscFree(h->bops);
114: PetscFListDestroy(&h->qlist);
115: PetscFree(h->type_name);
116: PetscFree(h->name);
117: PetscFree(h->prefix);
118: PetscFree(h->fortran_func_pointers);
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: PetscFree(PetscObjects);
130: PetscObjectsMaxCounts = 0;
131: }
132: return(0);
133: }
137: /*@C
138: PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object
140: Logically Collective on PetscObject
142: Input Parameter:
143: + src - source object
144: - dest - destination object
146: Level: developer
148: Note:
149: Both objects must have the same class.
150: @*/
151: PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest)
152: {
158: if (src->classid != dest->classid) SETERRQ(src->comm,PETSC_ERR_ARG_INCOMP,"Objects must be of the same class");
160: PetscFree(dest->fortran_func_pointers);
161: PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);
162: PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));
163: dest->num_fortran_func_pointers = src->num_fortran_func_pointers;
164: return(0);
165: }
169: /*@C
170: PetscObjectsView - Prints the currently existing objects.
172: Logically Collective on PetscViewer
174: Input Parameter:
175: . viewer - must be an PETSCVIEWERASCII viewer
177: Level: advanced
179: Concepts: options database^printing
181: @*/
182: PetscErrorCode PetscObjectsView(PetscViewer viewer)
183: {
185: PetscInt i;
186: PetscBool isascii;
187: PetscObject h;
190: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
191: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
192: if (!isascii) SETERRQ(((PetscObject)viewer)->comm,PETSC_ERR_SUP,"Only supports ASCII viewer");
194: for (i=0; i<PetscObjectsMaxCounts; i++) {
195: if ((h = PetscObjects[i])) {
196: PetscObjectName(h);
197: PetscViewerASCIIPrintf(viewer,"%s %s %s\n",h->class_name,h->type_name,h->name);
198: }
199: }
200: return(0);
201: }
205: /*@C
206: PetscObjectsGetObject - Get a pointer to a named object
208: Not collective
210: Input Parameter:
211: . name - the name of an object
213: Output Parameter:
214: . obj - the object or null if there is no object
216: Level: advanced
218: Concepts: options database^printing
220: @*/
221: PetscErrorCode PetscObjectsGetObject(const char* name,PetscObject *obj,char **classname)
222: {
224: PetscInt i;
225: PetscObject h;
226: PetscBool flg;
229: *obj = PETSC_NULL;
230: for (i=0; i<PetscObjectsMaxCounts; i++) {
231: if ((h = PetscObjects[i])) {
232: PetscObjectName(h);
233: PetscStrcmp(h->name,name,&flg);
234: if (flg) {
235: *obj = h;
236: if (classname) *classname = h->class_name;
237: return(0);
238: }
239: }
240: }
241: return(0);
242: }
246: char* PetscObjectsGetObjectMatlab(const char* name,PetscObject *obj)
247: {
249: PetscInt i;
250: PetscObject h;
251: PetscBool flg;
254: *obj = PETSC_NULL;
255: for (i=0; i<PetscObjectsMaxCounts; i++) {
256: if ((h = PetscObjects[i])) {
257: PetscObjectName(h);if (ierr) return(0);
258: PetscStrcmp(h->name,name,&flg);if (ierr) return(0);
259: if (flg) {
260: *obj = h;
261: PetscFunctionReturn(h->class_name);
262: }
263: }
264: }
265: return(0);
266: }
270: /*@C
271: PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
273: Not Collective
275: Input Parameter:
276: + obj - the PETSc object
277: . handle - function that checks for options
278: . destroy - function to destroy context if provided
279: - ctx - optional context for check function
281: Level: developer
284: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()
286: @*/
287: PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
288: {
291: if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
292: obj->optionhandler[obj->noptionhandler] = handle;
293: obj->optiondestroy[obj->noptionhandler] = destroy;
294: obj->optionctx[obj->noptionhandler++] = ctx;
295: return(0);
296: }
300: /*@C
301: PetscObjectProcessOptionsHandlers - Calls all the options handler attached to an object
303: Not Collective
305: Input Parameter:
306: . obj - the PETSc object
308: Level: developer
311: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()
313: @*/
314: PetscErrorCode PetscObjectProcessOptionsHandlers(PetscObject obj)
315: {
316: PetscInt i;
321: for (i=0; i<obj->noptionhandler; i++) {
322: (*obj->optionhandler[i])(obj,obj->optionctx[i]);
323: }
324: return(0);
325: }
329: /*@C
330: PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an objeft
332: Not Collective
334: Input Parameter:
335: . obj - the PETSc object
337: Level: developer
340: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
342: @*/
343: PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj)
344: {
345: PetscInt i;
350: for (i=0; i<obj->noptionhandler; i++) {
351: (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
352: }
353: obj->noptionhandler = 0;
354: return(0);
355: }
360: /*@
361: PetscObjectReference - Indicates to any PetscObject that it is being
362: referenced by another PetscObject. This increases the reference
363: count for that object by one.
365: Logically Collective on PetscObject
367: Input Parameter:
368: . obj - the PETSc object. This must be cast with (PetscObject), for example,
369: PetscObjectReference((PetscObject)mat);
371: Level: advanced
373: .seealso: PetscObjectCompose(), PetscObjectDereference()
374: @*/
375: PetscErrorCode PetscObjectReference(PetscObject obj)
376: {
379: obj->refct++;
380: return(0);
381: }
385: /*@
386: PetscObjectGetReference - Gets the current reference count for
387: any PETSc object.
389: Not Collective
391: Input Parameter:
392: . obj - the PETSc object; this must be cast with (PetscObject), for example,
393: PetscObjectGetReference((PetscObject)mat,&cnt);
395: Output Parameter:
396: . cnt - the reference count
398: Level: advanced
400: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
401: @*/
402: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
403: {
407: *cnt = obj->refct;
408: return(0);
409: }
413: /*@
414: PetscObjectDereference - Indicates to any PetscObject that it is being
415: referenced by one less PetscObject. This decreases the reference
416: count for that object by one.
418: Collective on PetscObject if reference reaches 0 otherwise Logically Collective
420: Input Parameter:
421: . obj - the PETSc object; this must be cast with (PetscObject), for example,
422: PetscObjectDereference((PetscObject)mat);
424: Notes: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not.
426: Level: advanced
428: .seealso: PetscObjectCompose(), PetscObjectReference()
429: @*/
430: PetscErrorCode PetscObjectDereference(PetscObject obj)
431: {
436: if (obj->bops->destroy) {
437: (*obj->bops->destroy)(&obj);
438: } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
439: return(0);
440: }
442: /* ----------------------------------------------------------------------- */
443: /*
444: The following routines are the versions private to the PETSc object
445: data structures.
446: */
449: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
450: {
453: *comm = obj->comm;
454: return(0);
455: }
459: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
460: {
465: PetscOListRemoveReference(&obj->olist,name);
466: return(0);
467: }
471: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
472: {
474: char *tname;
475: PetscBool skipreference;
478: if (ptr) {
479: PetscOListReverseFind(ptr->olist,obj,&tname,&skipreference);
480: if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
481: }
482: PetscOListAdd(&obj->olist,name,ptr);
483: return(0);
484: }
488: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
489: {
494: PetscOListFind(obj->olist,name,ptr);
495: return(0);
496: }
500: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
501: {
506: PetscFListAdd(&obj->qlist,name,fname,ptr);
507: return(0);
508: }
512: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
513: {
518: PetscFListFind(obj->qlist,obj->comm,name,PETSC_FALSE,ptr);
519: return(0);
520: }
524: /*@C
525: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
526:
527: Not Collective
529: Input Parameters:
530: + obj - the PETSc object; this must be cast with (PetscObject), for example,
531: PetscObjectCompose((PetscObject)mat,...);
532: . name - name associated with the child object
533: - ptr - the other PETSc object to associate with the PETSc object; this must also be
534: cast with (PetscObject)
536: Level: advanced
538: Notes:
539: The second objects reference count is automatically increased by one when it is
540: composed.
542: Replaces any previous object that had the same name.
544: If ptr is null and name has previously been composed using an object, then that
545: entry is removed from the obj.
547: PetscObjectCompose() can be used with any PETSc object (such as
548: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
549: PetscContainerCreate() for info on how to create an object from a
550: user-provided pointer that may then be composed with PETSc objects.
551:
552: Concepts: objects^composing
553: Concepts: composing objects
555: .seealso: PetscObjectQuery(), PetscContainerCreate()
556: @*/
557: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
558: {
565: (*obj->bops->compose)(obj,name,ptr);
566: return(0);
567: }
571: /*@C
572: PetscObjectSetPrecision - sets the precision used within a given object.
573:
574: Collective on the PetscObject
576: Input Parameters:
577: + obj - the PETSc object; this must be cast with (PetscObject), for example,
578: PetscObjectCompose((PetscObject)mat,...);
579: - precision - the precision
581: Level: advanced
583: .seealso: PetscObjectQuery(), PetscContainerCreate()
584: @*/
585: PetscErrorCode PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
586: {
589: obj->precision = precision;
590: return(0);
591: }
595: /*@C
596: PetscObjectQuery - Gets a PETSc object associated with a given object.
597:
598: Not Collective
600: Input Parameters:
601: + obj - the PETSc object
602: Thus must be cast with a (PetscObject), for example,
603: PetscObjectCompose((PetscObject)mat,...);
604: . name - name associated with child object
605: - ptr - the other PETSc object associated with the PETSc object, this must be
606: cast with (PetscObject *)
608: Level: advanced
610: The reference count of neither object is increased in this call
612: Concepts: objects^composing
613: Concepts: composing objects
614: Concepts: objects^querying
615: Concepts: querying objects
617: .seealso: PetscObjectCompose()
618: @*/
619: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
620: {
627: (*obj->bops->query)(obj,name,ptr);
628: return(0);
629: }
633: PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
634: {
640: (*obj->bops->composefunction)(obj,name,fname,ptr);
641: return(0);
642: }
646: /*@C
647: PetscObjectQueryFunction - Gets a function associated with a given object.
648:
649: Logically Collective on PetscObject
651: Input Parameters:
652: + obj - the PETSc object; this must be cast with (PetscObject), for example,
653: PetscObjectQueryFunction((PetscObject)ksp,...);
654: - name - name associated with the child function
656: Output Parameter:
657: . ptr - function pointer
659: Level: advanced
661: Concepts: objects^composing functions
662: Concepts: composing functions
663: Concepts: functions^querying
664: Concepts: objects^querying
665: Concepts: querying objects
667: .seealso: PetscObjectComposeFunctionDynamic()
668: @*/
669: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void))
670: {
676: (*obj->bops->queryfunction)(obj,name,ptr);
677: return(0);
678: }
680: struct _p_PetscContainer {
681: PETSCHEADER(int);
682: void *ptr;
683: PetscErrorCode (*userdestroy)(void*);
684: };
688: /*@C
689: PetscContainerGetPointer - Gets the pointer value contained in the container.
691: Not Collective
693: Input Parameter:
694: . obj - the object created with PetscContainerCreate()
696: Output Parameter:
697: . ptr - the pointer value
699: Level: advanced
701: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
702: PetscContainerSetPointer()
703: @*/
704: PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr)
705: {
709: *ptr = obj->ptr;
710: return(0);
711: }
716: /*@C
717: PetscContainerSetPointer - Sets the pointer value contained in the container.
719: Logically Collective on PetscContainer
721: Input Parameters:
722: + obj - the object created with PetscContainerCreate()
723: - ptr - the pointer value
725: Level: advanced
727: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
728: PetscContainerGetPointer()
729: @*/
730: PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr)
731: {
735: obj->ptr = ptr;
736: return(0);
737: }
741: /*@C
742: PetscContainerDestroy - Destroys a PETSc container object.
744: Collective on PetscContainer
746: Input Parameter:
747: . obj - an object that was created with PetscContainerCreate()
749: Level: advanced
751: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
752: @*/
753: PetscErrorCode PetscContainerDestroy(PetscContainer *obj)
754: {
757: if (!*obj) return(0);
759: if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; return(0);}
760: if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
761: PetscHeaderDestroy(obj);
762: return(0);
763: }
767: /*@C
768: PetscContainerSetUserDestroy - Sets name of the user destroy function.
770: Logically Collective on PetscContainer
772: Input Parameter:
773: + obj - an object that was created with PetscContainerCreate()
774: - des - name of the user destroy function
776: Level: advanced
778: .seealso: PetscContainerDestroy()
779: @*/
780: PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
781: {
784: obj->userdestroy = des;
785: return(0);
786: }
788: PetscClassId PETSC_CONTAINER_CLASSID;
792: /*@C
793: PetscContainerCreate - Creates a PETSc object that has room to hold
794: a single pointer. This allows one to attach any type of data (accessible
795: through a pointer) with the PetscObjectCompose() function to a PetscObject.
796: The data item itself is attached by a call to PetscContainerSetPointer().
798: Collective on MPI_Comm
800: Input Parameters:
801: . comm - MPI communicator that shares the object
803: Output Parameters:
804: . container - the container created
806: Level: advanced
808: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
809: @*/
810: PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
811: {
813: PetscContainer contain;
817: PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,0,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);
818: *container = contain;
819: return(0);
820: }
824: /*@
825: PetscObjectSetFromOptions - Sets generic parameters from user options.
827: Collective on obj
829: Input Parameter:
830: . obj - the PetscObjcet
832: Options Database Keys:
834: Notes:
835: We have no generic options at present, so this does nothing
837: Level: beginner
839: .keywords: set, options, database
840: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
841: @*/
842: PetscErrorCode PetscObjectSetFromOptions(PetscObject obj)
843: {
846: return(0);
847: }
851: /*@
852: PetscObjectSetUp - Sets up the internal data structures for the later use.
854: Collective on PetscObject
856: Input Parameters:
857: . obj - the PetscObject
859: Notes:
860: This does nothing at present.
862: Level: advanced
864: .keywords: setup
865: .seealso: PetscObjectDestroy()
866: @*/
867: PetscErrorCode PetscObjectSetUp(PetscObject obj)
868: {
871: return(0);
872: }