Actual source code: inherit.c
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;
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: }
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;
90: #if defined(PETSC_HAVE_AMS)
91: if (PetscAMSPublishAll) {
92: PetscObjectUnPublish((PetscObject)h);
93: }
94: #endif
95: if (PetscMemoryCollectMaximumUsage) {
96: PetscLogDouble usage;
97: PetscMemoryGetCurrentUsage(&usage);
98: if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
99: }
100: /* first destroy things that could execute arbitrary code */
101: if (h->python_destroy) {
102: void *python_context = h->python_context;
103: PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
104: h->python_context = 0;
105: h->python_destroy = 0;
106: (*python_destroy)(python_context);
107: }
108: PetscOListDestroy(&h->olist);
109: PetscCommDestroy(&h->comm);
110: /* next destroy other things */
111: h->classid = PETSCFREEDHEADER;
112: PetscFree(h->bops);
113: PetscFListDestroy(&h->qlist);
114: PetscFree(h->type_name);
115: PetscFree(h->name);
116: PetscFree(h->prefix);
117: PetscFree(h->fortran_func_pointers);
119: /* Record object removal from list of all objects */
120: for (i=0; i<PetscObjectsMaxCounts; i++) {
121: if (PetscObjects[i] == h) {
122: PetscObjects[i] = 0;
123: PetscObjectsCounts--;
124: break;
125: }
126: }
127: if (!PetscObjectsCounts) {
128: PetscFree(PetscObjects);
129: PetscObjectsMaxCounts = 0;
130: }
131: return(0);
132: }
136: /*@C
137: PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object
139: Logically Collective on PetscObject
141: Input Parameter:
142: + src - source object
143: - dest - destination object
145: Level: developer
147: Note:
148: Both objects must have the same class.
149: @*/
150: PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest)
151: {
157: if (src->classid != dest->classid) SETERRQ(src->comm,PETSC_ERR_ARG_INCOMP,"Objects must be of the same class");
159: PetscFree(dest->fortran_func_pointers);
160: PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);
161: PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));
162: dest->num_fortran_func_pointers = src->num_fortran_func_pointers;
163: return(0);
164: }
168: /*@C
169: PetscObjectsView - Prints the currently existing objects.
171: Logically Collective on PetscViewer
173: Input Parameter:
174: . viewer - must be an PETSCVIEWERASCII viewer
176: Level: advanced
178: Concepts: options database^printing
180: @*/
181: PetscErrorCode PetscObjectsView(PetscViewer viewer)
182: {
184: PetscInt i;
185: PetscBool isascii;
186: PetscObject h;
189: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
190: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
191: if (!isascii) SETERRQ(((PetscObject)viewer)->comm,PETSC_ERR_SUP,"Only supports ASCII viewer");
193: for (i=0; i<PetscObjectsMaxCounts; i++) {
194: if ((h = PetscObjects[i])) {
195: PetscObjectName(h);
196: PetscViewerASCIIPrintf(viewer,"%s %s %s\n",h->class_name,h->type_name,h->name);
197: }
198: }
199: return(0);
200: }
204: /*@C
205: PetscObjectsGetObject - Get a pointer to a named object
207: Not collective
209: Input Parameter:
210: . name - the name of an object
212: Output Parameter:
213: . obj - the object or null if there is no object
215: Level: advanced
217: Concepts: options database^printing
219: @*/
220: PetscErrorCode PetscObjectsGetObject(const char* name,PetscObject *obj,char **classname)
221: {
223: PetscInt i;
224: PetscObject h;
225: PetscBool flg;
228: *obj = PETSC_NULL;
229: for (i=0; i<PetscObjectsMaxCounts; i++) {
230: if ((h = PetscObjects[i])) {
231: PetscObjectName(h);
232: PetscStrcmp(h->name,name,&flg);
233: if (flg) {
234: *obj = h;
235: if (classname) *classname = h->class_name;
236: return(0);
237: }
238: }
239: }
240: return(0);
241: }
245: char* PetscObjectsGetObjectMatlab(const char* name,PetscObject *obj)
246: {
248: PetscInt i;
249: PetscObject h;
250: PetscBool flg;
253: *obj = PETSC_NULL;
254: for (i=0; i<PetscObjectsMaxCounts; i++) {
255: if ((h = PetscObjects[i])) {
256: PetscObjectName(h);if (ierr) return(0);
257: PetscStrcmp(h->name,name,&flg);if (ierr) return(0);
258: if (flg) {
259: *obj = h;
260: PetscFunctionReturn(h->class_name);
261: }
262: }
263: }
264: return(0);
265: }
269: /*@C
270: PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
272: Not Collective
274: Input Parameter:
275: + obj - the PETSc object
276: . handle - function that checks for options
277: . destroy - function to destroy context if provided
278: - ctx - optional context for check function
280: Level: developer
283: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()
285: @*/
286: PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
287: {
289: if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
290: obj->optionhandler[obj->noptionhandler] = handle;
291: obj->optiondestroy[obj->noptionhandler] = destroy;
292: obj->optionctx[obj->noptionhandler++] = ctx;
293: return(0);
294: }
298: /*@C
299: PetscObjectProcessOptionsHandlers - Calls all the options handler attached to an object
301: Not Collective
303: Input Parameter:
304: . obj - the PETSc object
306: Level: developer
309: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()
311: @*/
312: PetscErrorCode PetscObjectProcessOptionsHandlers(PetscObject obj)
313: {
314: PetscInt i;
318: for (i=0; i<obj->noptionhandler; i++) {
319: (*obj->optionhandler[i])(obj,obj->optionctx[i]);
320: }
321: return(0);
322: }
326: /*@C
327: PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an objeft
329: Not Collective
331: Input Parameter:
332: . obj - the PETSc object
334: Level: developer
337: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
339: @*/
340: PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj)
341: {
342: PetscInt i;
346: for (i=0; i<obj->noptionhandler; i++) {
347: (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
348: }
349: obj->noptionhandler = 0;
350: return(0);
351: }
356: /*@
357: PetscObjectReference - Indicates to any PetscObject that it is being
358: referenced by another PetscObject. This increases the reference
359: count for that object by one.
361: Logically Collective on PetscObject
363: Input Parameter:
364: . obj - the PETSc object. This must be cast with (PetscObject), for example,
365: PetscObjectReference((PetscObject)mat);
367: Level: advanced
369: .seealso: PetscObjectCompose(), PetscObjectDereference()
370: @*/
371: PetscErrorCode PetscObjectReference(PetscObject obj)
372: {
375: obj->refct++;
376: return(0);
377: }
381: /*@
382: PetscObjectGetReference - Gets the current reference count for
383: any PETSc object.
385: Not Collective
387: Input Parameter:
388: . obj - the PETSc object; this must be cast with (PetscObject), for example,
389: PetscObjectGetReference((PetscObject)mat,&cnt);
391: Output Parameter:
392: . cnt - the reference count
394: Level: advanced
396: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
397: @*/
398: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
399: {
403: *cnt = obj->refct;
404: return(0);
405: }
409: /*@
410: PetscObjectDereference - Indicates to any PetscObject that it is being
411: referenced by one less PetscObject. This decreases the reference
412: count for that object by one.
414: Collective on PetscObject if reference reaches 0 otherwise Logically Collective
416: Input Parameter:
417: . obj - the PETSc object; this must be cast with (PetscObject), for example,
418: PetscObjectDereference((PetscObject)mat);
420: Notes: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not.
422: Level: advanced
424: .seealso: PetscObjectCompose(), PetscObjectReference()
425: @*/
426: PetscErrorCode PetscObjectDereference(PetscObject obj)
427: {
432: if (obj->bops->destroy) {
433: (*obj->bops->destroy)(&obj);
434: } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
435: return(0);
436: }
438: /* ----------------------------------------------------------------------- */
439: /*
440: The following routines are the versions private to the PETSc object
441: data structures.
442: */
445: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
446: {
448: *comm = obj->comm;
449: return(0);
450: }
454: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
455: {
459: PetscOListRemoveReference(&obj->olist,name);
460: return(0);
461: }
465: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
466: {
468: char *tname;
469: PetscBool skipreference;
472: if (ptr) {
473: PetscOListReverseFind(ptr->olist,obj,&tname,&skipreference);
474: if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was compose with it");
475: }
476: PetscOListAdd(&obj->olist,name,ptr);
477: return(0);
478: }
482: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
483: {
487: PetscOListFind(obj->olist,name,ptr);
488: return(0);
489: }
493: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
494: {
498: PetscFListAdd(&obj->qlist,name,fname,ptr);
499: return(0);
500: }
504: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
505: {
509: PetscFListFind(obj->qlist,obj->comm,name,PETSC_FALSE,ptr);
510: return(0);
511: }
515: /*@C
516: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
517:
518: Not Collective
520: Input Parameters:
521: + obj - the PETSc object; this must be cast with (PetscObject), for example,
522: PetscObjectCompose((PetscObject)mat,...);
523: . name - name associated with the child object
524: - ptr - the other PETSc object to associate with the PETSc object; this must also be
525: cast with (PetscObject)
527: Level: advanced
529: Notes:
530: The second objects reference count is automatically increased by one when it is
531: composed.
533: Replaces any previous object that had the same name.
535: If ptr is null and name has previously been composed using an object, then that
536: entry is removed from the obj.
538: PetscObjectCompose() can be used with any PETSc object (such as
539: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
540: PetscContainerCreate() for info on how to create an object from a
541: user-provided pointer that may then be composed with PETSc objects.
542:
543: Concepts: objects^composing
544: Concepts: composing objects
546: .seealso: PetscObjectQuery(), PetscContainerCreate()
547: @*/
548: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
549: {
556: (*obj->bops->compose)(obj,name,ptr);
557: return(0);
558: }
562: /*@C
563: PetscObjectSetPrecision - sets the precision used within a given object.
564:
565: Collective on the PetscObject
567: Input Parameters:
568: + obj - the PETSc object; this must be cast with (PetscObject), for example,
569: PetscObjectCompose((PetscObject)mat,...);
570: - precision - the precision
572: Level: advanced
574: .seealso: PetscObjectQuery(), PetscContainerCreate()
575: @*/
576: PetscErrorCode PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
577: {
580: obj->precision = precision;
581: return(0);
582: }
586: /*@C
587: PetscObjectQuery - Gets a PETSc object associated with a given object.
588:
589: Not Collective
591: Input Parameters:
592: + obj - the PETSc object
593: Thus must be cast with a (PetscObject), for example,
594: PetscObjectCompose((PetscObject)mat,...);
595: . name - name associated with child object
596: - ptr - the other PETSc object associated with the PETSc object, this must be
597: cast with (PetscObject *)
599: Level: advanced
601: The reference count of neither object is increased in this call
603: Concepts: objects^composing
604: Concepts: composing objects
605: Concepts: objects^querying
606: Concepts: querying objects
608: .seealso: PetscObjectCompose()
609: @*/
610: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
611: {
618: (*obj->bops->query)(obj,name,ptr);
619: return(0);
620: }
624: PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
625: {
632: (*obj->bops->composefunction)(obj,name,fname,ptr);
633: return(0);
634: }
638: /*@C
639: PetscObjectQueryFunction - Gets a function associated with a given object.
640:
641: Logically Collective on PetscObject
643: Input Parameters:
644: + obj - the PETSc object; this must be cast with (PetscObject), for example,
645: PetscObjectQueryFunction((PetscObject)ksp,...);
646: - name - name associated with the child function
648: Output Parameter:
649: . ptr - function pointer
651: Level: advanced
653: Concepts: objects^composing functions
654: Concepts: composing functions
655: Concepts: functions^querying
656: Concepts: objects^querying
657: Concepts: querying objects
659: .seealso: PetscObjectComposeFunctionDynamic()
660: @*/
661: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void))
662: {
668: (*obj->bops->queryfunction)(obj,name,ptr);
669: return(0);
670: }
672: struct _p_PetscContainer {
673: PETSCHEADER(int);
674: void *ptr;
675: PetscErrorCode (*userdestroy)(void*);
676: };
680: /*@C
681: PetscContainerGetPointer - Gets the pointer value contained in the container.
683: Not Collective
685: Input Parameter:
686: . obj - the object created with PetscContainerCreate()
688: Output Parameter:
689: . ptr - the pointer value
691: Level: advanced
693: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
694: PetscContainerSetPointer()
695: @*/
696: PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr)
697: {
701: *ptr = obj->ptr;
702: return(0);
703: }
708: /*@C
709: PetscContainerSetPointer - Sets the pointer value contained in the container.
711: Logically Collective on PetscContainer
713: Input Parameters:
714: + obj - the object created with PetscContainerCreate()
715: - ptr - the pointer value
717: Level: advanced
719: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
720: PetscContainerGetPointer()
721: @*/
722: PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr)
723: {
727: obj->ptr = ptr;
728: return(0);
729: }
733: /*@C
734: PetscContainerDestroy - Destroys a PETSc container object.
736: Collective on PetscContainer
738: Input Parameter:
739: . obj - an object that was created with PetscContainerCreate()
741: Level: advanced
743: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
744: @*/
745: PetscErrorCode PetscContainerDestroy(PetscContainer *obj)
746: {
749: if (!*obj) return(0);
751: if (--((PetscObject)(*obj))->refct > 0) return(0);
752: if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
753: PetscHeaderDestroy(obj);
754: return(0);
755: }
759: /*@C
760: PetscContainerSetUserDestroy - Sets name of the user destroy function.
762: Logically Collective on PetscContainer
764: Input Parameter:
765: + obj - an object that was created with PetscContainerCreate()
766: - des - name of the user destroy function
768: Level: advanced
770: .seealso: PetscContainerDestroy()
771: @*/
772: PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
773: {
776: obj->userdestroy = des;
777: return(0);
778: }
780: PetscClassId PETSC_CONTAINER_CLASSID;
784: /*@C
785: PetscContainerCreate - Creates a PETSc object that has room to hold
786: a single pointer. This allows one to attach any type of data (accessible
787: through a pointer) with the PetscObjectCompose() function to a PetscObject.
788: The data item itself is attached by a call to PetscContainerSetPointer().
790: Collective on MPI_Comm
792: Input Parameters:
793: . comm - MPI communicator that shares the object
795: Output Parameters:
796: . container - the container created
798: Level: advanced
800: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
801: @*/
802: PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
803: {
805: PetscContainer contain;
809: PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,0,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);
810: *container = contain;
811: return(0);
812: }
816: /*@
817: PetscObjectSetFromOptions - Sets generic parameters from user options.
819: Collective on obj
821: Input Parameter:
822: . obj - the PetscObjcet
824: Options Database Keys:
826: Notes:
827: We have no generic options at present, so this does nothing
829: Level: beginner
831: .keywords: set, options, database
832: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
833: @*/
834: PetscErrorCode PetscObjectSetFromOptions(PetscObject obj)
835: {
838: return(0);
839: }
843: /*@
844: PetscObjectSetUp - Sets up the internal data structures for the later use.
846: Collective on PetscObject
848: Input Parameters:
849: . obj - the PetscObject
851: Notes:
852: This does nothing at present.
854: Level: advanced
856: .keywords: setup
857: .seealso: PetscObjectDestroy()
858: @*/
859: PetscErrorCode PetscObjectSetUp(PetscObject obj)
860: {
863: return(0);
864: }