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: PetscObjectsView - Prints the currently existing objects.
139: Logically Collective on PetscViewer
141: Input Parameter:
142: . viewer - must be an PETSCVIEWERASCII viewer
144: Level: advanced
146: Concepts: options database^printing
148: @*/
149: PetscErrorCode PetscObjectsView(PetscViewer viewer)
150: {
152: PetscInt i;
153: PetscBool isascii;
154: PetscObject h;
157: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
158: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
159: if (!isascii) SETERRQ(((PetscObject)viewer)->comm,PETSC_ERR_SUP,"Only supports ASCII viewer");
161: for (i=0; i<PetscObjectsMaxCounts; i++) {
162: if ((h = PetscObjects[i])) {
163: PetscObjectName(h);
164: PetscViewerASCIIPrintf(viewer,"%s %s %s\n",h->class_name,h->type_name,h->name);
165: }
166: }
167: return(0);
168: }
172: /*@C
173: PetscObjectsGetObject - Get a pointer to a named object
175: Not collective
177: Input Parameter:
178: . name - the name of an object
180: Output Parameter:
181: . obj - the object or null if there is no object
183: Level: advanced
185: Concepts: options database^printing
187: @*/
188: PetscErrorCode PetscObjectsGetObject(const char* name,PetscObject *obj,char **classname)
189: {
191: PetscInt i;
192: PetscObject h;
193: PetscBool flg;
196: *obj = PETSC_NULL;
197: for (i=0; i<PetscObjectsMaxCounts; i++) {
198: if ((h = PetscObjects[i])) {
199: PetscObjectName(h);
200: PetscStrcmp(h->name,name,&flg);
201: if (flg) {
202: *obj = h;
203: if (classname) *classname = h->class_name;
204: return(0);
205: }
206: }
207: }
208: return(0);
209: }
213: char* PetscObjectsGetObjectMatlab(const char* name,PetscObject *obj)
214: {
216: PetscInt i;
217: PetscObject h;
218: PetscBool flg;
221: *obj = PETSC_NULL;
222: for (i=0; i<PetscObjectsMaxCounts; i++) {
223: if ((h = PetscObjects[i])) {
224: PetscObjectName(h);if (ierr) return(0);
225: PetscStrcmp(h->name,name,&flg);if (ierr) return(0);
226: if (flg) {
227: *obj = h;
228: PetscFunctionReturn(h->class_name);
229: }
230: }
231: }
232: return(0);
233: }
237: /*@C
238: PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
240: Not Collective
242: Input Parameter:
243: + obj - the PETSc object
244: . handle - function that checks for options
245: . destroy - function to destroy context if provided
246: - ctx - optional context for check function
248: Level: developer
251: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()
253: @*/
254: PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
255: {
257: if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
258: obj->optionhandler[obj->noptionhandler] = handle;
259: obj->optiondestroy[obj->noptionhandler] = destroy;
260: obj->optionctx[obj->noptionhandler++] = ctx;
261: return(0);
262: }
266: /*@C
267: PetscObjectProcessOptionsHandlers - Calls all the options handler attached to an object
269: Not Collective
271: Input Parameter:
272: . obj - the PETSc object
274: Level: developer
277: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()
279: @*/
280: PetscErrorCode PetscObjectProcessOptionsHandlers(PetscObject obj)
281: {
282: PetscInt i;
286: for (i=0; i<obj->noptionhandler; i++) {
287: (*obj->optionhandler[i])(obj,obj->optionctx[i]);
288: }
289: return(0);
290: }
294: /*@C
295: PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an objeft
297: Not Collective
299: Input Parameter:
300: . obj - the PETSc object
302: Level: developer
305: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
307: @*/
308: PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj)
309: {
310: PetscInt i;
314: for (i=0; i<obj->noptionhandler; i++) {
315: (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
316: }
317: obj->noptionhandler = 0;
318: return(0);
319: }
324: /*@
325: PetscObjectReference - Indicates to any PetscObject that it is being
326: referenced by another PetscObject. This increases the reference
327: count for that object by one.
329: Logically Collective on PetscObject
331: Input Parameter:
332: . obj - the PETSc object. This must be cast with (PetscObject), for example,
333: PetscObjectReference((PetscObject)mat);
335: Level: advanced
337: .seealso: PetscObjectCompose(), PetscObjectDereference()
338: @*/
339: PetscErrorCode PetscObjectReference(PetscObject obj)
340: {
343: obj->refct++;
344: return(0);
345: }
349: /*@
350: PetscObjectGetReference - Gets the current reference count for
351: any PETSc object.
353: Not Collective
355: Input Parameter:
356: . obj - the PETSc object; this must be cast with (PetscObject), for example,
357: PetscObjectGetReference((PetscObject)mat,&cnt);
359: Output Parameter:
360: . cnt - the reference count
362: Level: advanced
364: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
365: @*/
366: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
367: {
371: *cnt = obj->refct;
372: return(0);
373: }
377: /*@
378: PetscObjectDereference - Indicates to any PetscObject that it is being
379: referenced by one less PetscObject. This decreases the reference
380: count for that object by one.
382: Collective on PetscObject if reference reaches 0 otherwise Logically Collective
384: Input Parameter:
385: . obj - the PETSc object; this must be cast with (PetscObject), for example,
386: PetscObjectDereference((PetscObject)mat);
388: Notes: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not.
390: Level: advanced
392: .seealso: PetscObjectCompose(), PetscObjectReference()
393: @*/
394: PetscErrorCode PetscObjectDereference(PetscObject obj)
395: {
400: if (obj->bops->destroy) {
401: (*obj->bops->destroy)(&obj);
402: } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
403: return(0);
404: }
406: /* ----------------------------------------------------------------------- */
407: /*
408: The following routines are the versions private to the PETSc object
409: data structures.
410: */
413: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
414: {
416: *comm = obj->comm;
417: return(0);
418: }
422: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
423: {
427: PetscOListRemoveReference(&obj->olist,name);
428: return(0);
429: }
433: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
434: {
436: char *tname;
437: PetscBool skipreference;
440: if (ptr) {
441: PetscOListReverseFind(ptr->olist,obj,&tname,&skipreference);
442: if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was compose with it");
443: }
444: PetscOListAdd(&obj->olist,name,ptr);
445: return(0);
446: }
450: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
451: {
455: PetscOListFind(obj->olist,name,ptr);
456: return(0);
457: }
461: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
462: {
466: PetscFListAdd(&obj->qlist,name,fname,ptr);
467: return(0);
468: }
472: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
473: {
477: PetscFListFind(obj->qlist,obj->comm,name,PETSC_FALSE,ptr);
478: return(0);
479: }
483: /*@C
484: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
485:
486: Not Collective
488: Input Parameters:
489: + obj - the PETSc object; this must be cast with (PetscObject), for example,
490: PetscObjectCompose((PetscObject)mat,...);
491: . name - name associated with the child object
492: - ptr - the other PETSc object to associate with the PETSc object; this must also be
493: cast with (PetscObject)
495: Level: advanced
497: Notes:
498: The second objects reference count is automatically increased by one when it is
499: composed.
501: Replaces any previous object that had the same name.
503: If ptr is null and name has previously been composed using an object, then that
504: entry is removed from the obj.
506: PetscObjectCompose() can be used with any PETSc object (such as
507: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
508: PetscContainerCreate() for info on how to create an object from a
509: user-provided pointer that may then be composed with PETSc objects.
510:
511: Concepts: objects^composing
512: Concepts: composing objects
514: .seealso: PetscObjectQuery(), PetscContainerCreate()
515: @*/
516: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
517: {
524: (*obj->bops->compose)(obj,name,ptr);
525: return(0);
526: }
530: /*@C
531: PetscObjectSetPrecision - sets the precision used within a given object.
532:
533: Collective on the PetscObject
535: Input Parameters:
536: + obj - the PETSc object; this must be cast with (PetscObject), for example,
537: PetscObjectCompose((PetscObject)mat,...);
538: - precision - the precision
540: Level: advanced
542: .seealso: PetscObjectQuery(), PetscContainerCreate()
543: @*/
544: PetscErrorCode PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
545: {
548: obj->precision = precision;
549: return(0);
550: }
554: /*@C
555: PetscObjectQuery - Gets a PETSc object associated with a given object.
556:
557: Not Collective
559: Input Parameters:
560: + obj - the PETSc object
561: Thus must be cast with a (PetscObject), for example,
562: PetscObjectCompose((PetscObject)mat,...);
563: . name - name associated with child object
564: - ptr - the other PETSc object associated with the PETSc object, this must be
565: cast with (PetscObject *)
567: Level: advanced
569: The reference count of neither object is increased in this call
571: Concepts: objects^composing
572: Concepts: composing objects
573: Concepts: objects^querying
574: Concepts: querying objects
576: .seealso: PetscObjectCompose()
577: @*/
578: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
579: {
586: (*obj->bops->query)(obj,name,ptr);
587: return(0);
588: }
592: PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
593: {
600: (*obj->bops->composefunction)(obj,name,fname,ptr);
601: return(0);
602: }
606: /*@C
607: PetscObjectQueryFunction - Gets a function associated with a given object.
608:
609: Logically Collective on PetscObject
611: Input Parameters:
612: + obj - the PETSc object; this must be cast with (PetscObject), for example,
613: PetscObjectQueryFunction((PetscObject)ksp,...);
614: - name - name associated with the child function
616: Output Parameter:
617: . ptr - function pointer
619: Level: advanced
621: Concepts: objects^composing functions
622: Concepts: composing functions
623: Concepts: functions^querying
624: Concepts: objects^querying
625: Concepts: querying objects
627: .seealso: PetscObjectComposeFunctionDynamic()
628: @*/
629: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void))
630: {
636: (*obj->bops->queryfunction)(obj,name,ptr);
637: return(0);
638: }
640: struct _p_PetscContainer {
641: PETSCHEADER(int);
642: void *ptr;
643: PetscErrorCode (*userdestroy)(void*);
644: };
648: /*@C
649: PetscContainerGetPointer - Gets the pointer value contained in the container.
651: Not Collective
653: Input Parameter:
654: . obj - the object created with PetscContainerCreate()
656: Output Parameter:
657: . ptr - the pointer value
659: Level: advanced
661: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
662: PetscContainerSetPointer()
663: @*/
664: PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr)
665: {
669: *ptr = obj->ptr;
670: return(0);
671: }
676: /*@C
677: PetscContainerSetPointer - Sets the pointer value contained in the container.
679: Logically Collective on PetscContainer
681: Input Parameters:
682: + obj - the object created with PetscContainerCreate()
683: - ptr - the pointer value
685: Level: advanced
687: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
688: PetscContainerGetPointer()
689: @*/
690: PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr)
691: {
695: obj->ptr = ptr;
696: return(0);
697: }
701: /*@C
702: PetscContainerDestroy - Destroys a PETSc container object.
704: Collective on PetscContainer
706: Input Parameter:
707: . obj - an object that was created with PetscContainerCreate()
709: Level: advanced
711: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
712: @*/
713: PetscErrorCode PetscContainerDestroy(PetscContainer *obj)
714: {
717: if (!*obj) return(0);
719: if (--((PetscObject)(*obj))->refct > 0) return(0);
720: if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
721: PetscHeaderDestroy(obj);
722: return(0);
723: }
727: /*@C
728: PetscContainerSetUserDestroy - Sets name of the user destroy function.
730: Logically Collective on PetscContainer
732: Input Parameter:
733: + obj - an object that was created with PetscContainerCreate()
734: - des - name of the user destroy function
736: Level: advanced
738: .seealso: PetscContainerDestroy()
739: @*/
740: PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
741: {
744: obj->userdestroy = des;
745: return(0);
746: }
748: PetscClassId PETSC_CONTAINER_CLASSID;
752: /*@C
753: PetscContainerCreate - Creates a PETSc object that has room to hold
754: a single pointer. This allows one to attach any type of data (accessible
755: through a pointer) with the PetscObjectCompose() function to a PetscObject.
756: The data item itself is attached by a call to PetscContainerSetPointer().
758: Collective on MPI_Comm
760: Input Parameters:
761: . comm - MPI communicator that shares the object
763: Output Parameters:
764: . container - the container created
766: Level: advanced
768: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
769: @*/
770: PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
771: {
773: PetscContainer contain;
777: PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,0,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);
778: *container = contain;
779: return(0);
780: }
784: /*@
785: PetscObjectSetFromOptions - Sets generic parameters from user options.
787: Collective on obj
789: Input Parameter:
790: . obj - the PetscObjcet
792: Options Database Keys:
794: Notes:
795: We have no generic options at present, so this does nothing
797: Level: beginner
799: .keywords: set, options, database
800: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
801: @*/
802: PetscErrorCode PetscObjectSetFromOptions(PetscObject obj)
803: {
806: return(0);
807: }
811: /*@
812: PetscObjectSetUp - Sets up the internal data structures for the later use.
814: Collective on PetscObject
816: Input Parameters:
817: . obj - the PetscObject
819: Notes:
820: This does nothing at present.
822: Level: advanced
824: .keywords: setup
825: .seealso: PetscObjectDestroy()
826: @*/
827: PetscErrorCode PetscObjectSetUp(PetscObject obj)
828: {
831: return(0);
832: }