Actual source code: inherit.c
petsc-3.4.2 2013-07-02
2: /*
3: Provides utility routines for manipulating any type of PETSc object.
4: */
5: #include <petsc-private/petscimpl.h> /*I "petscsys.h" I*/
6: #include <petscviewer.h>
8: PetscObject *PetscObjects = 0;
9: PetscInt PetscObjectsCounts = 0, PetscObjectsMaxCounts = 0;
11: extern PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm*);
12: extern PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject);
13: extern PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject*);
14: extern PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],void (*)(void));
15: extern PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void));
19: /*
20: PetscHeaderCreate_Private - Creates a base PETSc object header and fills
21: in the default values. Called by the macro PetscHeaderCreate().
22: */
23: PetscErrorCode PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,const char class_name[],const char descr[],const char mansec[],
24: MPI_Comm comm,PetscErrorCode (*des)(PetscObject*),PetscErrorCode (*vie)(PetscObject,PetscViewer))
25: {
26: static PetscInt idcnt = 1;
27: PetscErrorCode ierr;
28: PetscObject *newPetscObjects;
29: PetscInt newPetscObjectsMaxCounts,i;
32: h->classid = classid;
33: h->type = 0;
34: h->class_name = (char*)class_name;
35: h->description = (char*)descr;
36: h->mansec = (char*)mansec;
37: h->prefix = 0;
38: h->refct = 1;
39: #if defined(PETSC_HAVE_AMS)
40: h->amsmem = -1;
41: #endif
42: h->id = idcnt++;
43: h->parentid = 0;
44: h->qlist = 0;
45: h->olist = 0;
46: h->precision = (PetscPrecision) sizeof(PetscReal);
47: h->bops->destroy = des;
48: h->bops->view = vie;
49: h->bops->getcomm = PetscObjectGetComm_Petsc;
50: h->bops->compose = PetscObjectCompose_Petsc;
51: h->bops->query = PetscObjectQuery_Petsc;
52: h->bops->composefunction = PetscObjectComposeFunction_Petsc;
53: h->bops->queryfunction = PetscObjectQueryFunction_Petsc;
55: PetscCommDuplicate(comm,&h->comm,&h->tag);
57: /* Keep a record of object created */
58: PetscObjectsCounts++;
59: for (i=0; i<PetscObjectsMaxCounts; i++) {
60: if (!PetscObjects[i]) {
61: PetscObjects[i] = h;
62: return(0);
63: }
64: }
65: /* Need to increase the space for storing PETSc objects */
66: if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100;
67: else newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts;
68: PetscMalloc(newPetscObjectsMaxCounts*sizeof(PetscObject),&newPetscObjects);
69: PetscMemcpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts*sizeof(PetscObject));
70: PetscMemzero(newPetscObjects+PetscObjectsMaxCounts,(newPetscObjectsMaxCounts - PetscObjectsMaxCounts)*sizeof(PetscObject));
71: PetscFree(PetscObjects);
73: PetscObjects = newPetscObjects;
74: PetscObjects[PetscObjectsMaxCounts] = h;
75: PetscObjectsMaxCounts = newPetscObjectsMaxCounts;
76: return(0);
77: }
79: extern PetscBool PetscMemoryCollectMaximumUsage;
80: extern PetscLogDouble PetscMemoryMaximumUsage;
84: /*
85: PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
86: the macro PetscHeaderDestroy().
87: */
88: PetscErrorCode PetscHeaderDestroy_Private(PetscObject h)
89: {
91: PetscInt i;
95: PetscObjectAMSViewOff(h);
96: PetscLogObjectDestroy(h);
97: PetscComposedQuantitiesDestroy(h);
98: if (PetscMemoryCollectMaximumUsage) {
99: PetscLogDouble usage;
100: PetscMemoryGetCurrentUsage(&usage);
101: if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
102: }
103: /* first destroy things that could execute arbitrary code */
104: if (h->python_destroy) {
105: void *python_context = h->python_context;
106: PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
107: h->python_context = 0;
108: h->python_destroy = 0;
110: (*python_destroy)(python_context);
111: }
112: PetscObjectDestroyOptionsHandlers(h);
113: PetscObjectListDestroy(&h->olist);
114: PetscCommDestroy(&h->comm);
115: /* next destroy other things */
116: h->classid = PETSCFREEDHEADER;
118: PetscFree(h->bops);
119: PetscFunctionListDestroy(&h->qlist);
120: PetscFree(h->type_name);
121: PetscFree(h->name);
122: PetscFree(h->prefix);
123: PetscFree(h->fortran_func_pointers);
124: PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_CLASS]);
125: PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
127: /* Record object removal from list of all objects */
128: for (i=0; i<PetscObjectsMaxCounts; i++) {
129: if (PetscObjects[i] == h) {
130: PetscObjects[i] = 0;
131: PetscObjectsCounts--;
132: break;
133: }
134: }
135: if (!PetscObjectsCounts) {
136: PetscFree(PetscObjects);
137: PetscObjectsMaxCounts = 0;
138: }
139: return(0);
140: }
144: /*@C
145: PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object
147: Logically Collective on PetscObject
149: Input Parameter:
150: + src - source object
151: - dest - destination object
153: Level: developer
155: Note:
156: Both objects must have the same class.
157: @*/
158: PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest)
159: {
161: PetscInt cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE];
166: if (src->classid != dest->classid) SETERRQ(src->comm,PETSC_ERR_ARG_INCOMP,"Objects must be of the same class");
168: PetscFree(dest->fortran_func_pointers);
169: PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);
170: PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));
172: dest->num_fortran_func_pointers = src->num_fortran_func_pointers;
174: PetscFortranCallbackGetSizes(src->classid,&numcb[PETSC_FORTRAN_CALLBACK_CLASS],&numcb[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
175: for (cbtype=PETSC_FORTRAN_CALLBACK_CLASS; cbtype<PETSC_FORTRAN_CALLBACK_MAXTYPE; cbtype++) {
176: PetscFree(dest->fortrancallback[cbtype]);
177: PetscMalloc(numcb[cbtype]*sizeof(PetscFortranCallback),&dest->fortrancallback[cbtype]);
178: PetscMemzero(dest->fortrancallback[cbtype],numcb[cbtype]*sizeof(PetscFortranCallback));
179: PetscMemcpy(dest->fortrancallback[cbtype],src->fortrancallback[cbtype],src->num_fortrancallback[cbtype]*sizeof(PetscFortranCallback));
180: }
181: return(0);
182: }
186: /*@C
187: PetscObjectSetFortranCallback - set fortran callback function pointer and context
189: Logically Collective
191: Input Arguments:
192: + obj - object on which to set callback
193: . cbtype - callback type (class or subtype)
194: . cid - address of callback Id, updated if not yet initialized (zero)
195: . func - Fortran function
196: - ctx - Fortran context
198: Level: developer
200: .seealso: PetscObjectGetFortranCallback()
201: @*/
202: PetscErrorCode PetscObjectSetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId *cid,void (*func)(void),void *ctx)
203: {
205: const char *subtype = NULL;
209: if (cbtype == PETSC_FORTRAN_CALLBACK_SUBTYPE) subtype = obj->type_name;
210: if (!*cid) {PetscFortranCallbackRegister(obj->classid,subtype,cid);}
211: if (*cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype]) {
212: PetscInt oldnum = obj->num_fortrancallback[cbtype],newnum = PetscMax(1,2*oldnum);
213: PetscFortranCallback *callback;
214: PetscMalloc(newnum*sizeof(callback[0]),&callback);
215: PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));
216: PetscFree(obj->fortrancallback[cbtype]);
218: obj->fortrancallback[cbtype] = callback;
219: obj->num_fortrancallback[cbtype] = newnum;
220: }
221: obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func;
222: obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx;
223: return(0);
224: }
228: /*@C
229: PetscObjectGetFortranCallback - get fortran callback function pointer and context
231: Logically Collective
233: Input Arguments:
234: + obj - object on which to get callback
235: . cbtype - callback type
236: - cid - address of callback Id
238: Output Arguments:
239: + func - Fortran function (or NULL if not needed)
240: - ctx - Fortran context (or NULL if not needed)
242: Level: developer
244: .seealso: PetscObjectSetFortranCallback()
245: @*/
246: PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx)
247: {
248: PetscFortranCallback *cb;
252: if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid");
253: if (PetscUnlikely(cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype])) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback not set on this object");
254: cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK];
255: if (func) *func = cb->func;
256: if (ctx) *ctx = cb->ctx;
257: return(0);
258: }
262: /*@C
263: PetscObjectsDump - Prints the currently existing objects.
265: Logically Collective on PetscViewer
267: Input Parameter:
268: + viewer - must be an PETSCVIEWERASCII viewer
269: - all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects
271: Level: advanced
273: Concepts: options database^printing
275: @*/
276: PetscErrorCode PetscObjectsDump(FILE *fd,PetscBool all)
277: {
279: PetscInt i;
280: #if defined(PETSC_USE_DEBUG)
281: PetscInt j,k;
282: #endif
283: PetscObject h;
286: if (PetscObjectsCounts) {
287: PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");
288: PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");
289: for (i=0; i<PetscObjectsMaxCounts; i++) {
290: if ((h = PetscObjects[i])) {
291: PetscObjectName(h);
292: {
293: #if defined(PETSC_USE_DEBUG)
294: PetscStack *stack;
295: char *create,*rclass;
297: /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */
298: PetscMallocGetStack(h,&stack);
299: k = stack->currentsize-2;
300: if (!all) {
301: k = 0;
302: while (!stack->petscroutine[k]) k++;
303: PetscStrstr(stack->function[k],"Create",&create);
304: if (!create) {
305: PetscStrstr(stack->function[k],"Get",&create);
306: }
307: PetscStrstr(stack->function[k],h->class_name,&rclass);
309: if (!create) continue;
310: if (!rclass) continue;
311: }
312: #endif
314: PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);
316: #if defined(PETSC_USE_DEBUG)
317: PetscMallocGetStack(h,&stack);
318: for (j=k; j>=0; j--) {
319: fprintf(fd," [%d] %s() in %s%s\n",PetscGlobalRank,stack->function[j],stack->directory[j],stack->file[j]);
320: }
321: #endif
322: }
323: }
324: }
325: }
326: return(0);
327: }
332: /*@C
333: PetscObjectsView - Prints the currently existing objects.
335: Logically Collective on PetscViewer
337: Input Parameter:
338: . viewer - must be an PETSCVIEWERASCII viewer
340: Level: advanced
342: Concepts: options database^printing
344: @*/
345: PetscErrorCode PetscObjectsView(PetscViewer viewer)
346: {
348: PetscBool isascii;
349: FILE *fd;
352: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
353: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
354: if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
355: PetscViewerASCIIGetPointer(viewer,&fd);
356: PetscObjectsDump(fd,PETSC_TRUE);
357: return(0);
358: }
362: /*@C
363: PetscObjectsGetObject - Get a pointer to a named object
365: Not collective
367: Input Parameter:
368: . name - the name of an object
370: Output Parameter:
371: . obj - the object or null if there is no object
373: Level: advanced
375: Concepts: options database^printing
377: @*/
378: PetscErrorCode PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
379: {
381: PetscInt i;
382: PetscObject h;
383: PetscBool flg;
386: *obj = NULL;
387: for (i=0; i<PetscObjectsMaxCounts; i++) {
388: if ((h = PetscObjects[i])) {
389: PetscObjectName(h);
390: PetscStrcmp(h->name,name,&flg);
391: if (flg) {
392: *obj = h;
393: if (classname) *classname = h->class_name;
394: return(0);
395: }
396: }
397: }
398: return(0);
399: }
403: char *PetscObjectsGetObjectMatlab(const char* name,PetscObject *obj)
404: {
406: PetscInt i;
407: PetscObject h;
408: PetscBool flg;
411: *obj = NULL;
412: for (i=0; i<PetscObjectsMaxCounts; i++) {
413: if ((h = PetscObjects[i])) {
414: PetscObjectName(h);if (ierr) return(0);
415: PetscStrcmp(h->name,name,&flg);if (ierr) return(0);
416: if (flg) {
417: *obj = h;
418: PetscFunctionReturn(h->class_name);
419: }
420: }
421: }
422: return(0);
423: }
427: /*@C
428: PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
430: Not Collective
432: Input Parameter:
433: + obj - the PETSc object
434: . handle - function that checks for options
435: . destroy - function to destroy context if provided
436: - ctx - optional context for check function
438: Level: developer
441: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()
443: @*/
444: PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
445: {
448: if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
449: obj->optionhandler[obj->noptionhandler] = handle;
450: obj->optiondestroy[obj->noptionhandler] = destroy;
451: obj->optionctx[obj->noptionhandler++] = ctx;
452: return(0);
453: }
457: /*@C
458: PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object
460: Not Collective
462: Input Parameter:
463: . obj - the PETSc object
465: Level: developer
468: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()
470: @*/
471: PetscErrorCode PetscObjectProcessOptionsHandlers(PetscObject obj)
472: {
473: PetscInt i;
478: for (i=0; i<obj->noptionhandler; i++) {
479: (*obj->optionhandler[i])(obj,obj->optionctx[i]);
480: }
481: return(0);
482: }
486: /*@C
487: PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object
489: Not Collective
491: Input Parameter:
492: . obj - the PETSc object
494: Level: developer
497: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
499: @*/
500: PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj)
501: {
502: PetscInt i;
507: for (i=0; i<obj->noptionhandler; i++) {
508: if (obj->optiondestroy[i]) {
509: (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
510: }
511: }
512: obj->noptionhandler = 0;
513: return(0);
514: }
519: /*@
520: PetscObjectReference - Indicates to any PetscObject that it is being
521: referenced by another PetscObject. This increases the reference
522: count for that object by one.
524: Logically Collective on PetscObject
526: Input Parameter:
527: . obj - the PETSc object. This must be cast with (PetscObject), for example,
528: PetscObjectReference((PetscObject)mat);
530: Level: advanced
532: .seealso: PetscObjectCompose(), PetscObjectDereference()
533: @*/
534: PetscErrorCode PetscObjectReference(PetscObject obj)
535: {
537: if (!obj) return(0);
539: obj->refct++;
540: return(0);
541: }
545: /*@
546: PetscObjectGetReference - Gets the current reference count for
547: any PETSc object.
549: Not Collective
551: Input Parameter:
552: . obj - the PETSc object; this must be cast with (PetscObject), for example,
553: PetscObjectGetReference((PetscObject)mat,&cnt);
555: Output Parameter:
556: . cnt - the reference count
558: Level: advanced
560: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
561: @*/
562: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
563: {
567: *cnt = obj->refct;
568: return(0);
569: }
573: /*@
574: PetscObjectDereference - Indicates to any PetscObject that it is being
575: referenced by one less PetscObject. This decreases the reference
576: count for that object by one.
578: Collective on PetscObject if reference reaches 0 otherwise Logically Collective
580: Input Parameter:
581: . obj - the PETSc object; this must be cast with (PetscObject), for example,
582: PetscObjectDereference((PetscObject)mat);
584: Notes: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not.
586: Level: advanced
588: .seealso: PetscObjectCompose(), PetscObjectReference()
589: @*/
590: PetscErrorCode PetscObjectDereference(PetscObject obj)
591: {
596: if (obj->bops->destroy) {
597: (*obj->bops->destroy)(&obj);
598: } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
599: return(0);
600: }
602: /* ----------------------------------------------------------------------- */
603: /*
604: The following routines are the versions private to the PETSc object
605: data structures.
606: */
609: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
610: {
613: *comm = obj->comm;
614: return(0);
615: }
619: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
620: {
625: PetscObjectListRemoveReference(&obj->olist,name);
626: return(0);
627: }
631: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
632: {
634: char *tname;
635: PetscBool skipreference;
638: if (ptr) {
639: PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
640: if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
641: }
642: PetscObjectListAdd(&obj->olist,name,ptr);
643: return(0);
644: }
648: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
649: {
654: PetscObjectListFind(obj->olist,name,ptr);
655: return(0);
656: }
660: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
661: {
666: PetscFunctionListAdd(&obj->qlist,name,ptr);
667: return(0);
668: }
672: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
673: {
678: PetscFunctionListFind(obj->qlist,name,ptr);
679: return(0);
680: }
684: /*@C
685: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
687: Not Collective
689: Input Parameters:
690: + obj - the PETSc object; this must be cast with (PetscObject), for example,
691: PetscObjectCompose((PetscObject)mat,...);
692: . name - name associated with the child object
693: - ptr - the other PETSc object to associate with the PETSc object; this must also be
694: cast with (PetscObject)
696: Level: advanced
698: Notes:
699: The second objects reference count is automatically increased by one when it is
700: composed.
702: Replaces any previous object that had the same name.
704: If ptr is null and name has previously been composed using an object, then that
705: entry is removed from the obj.
707: PetscObjectCompose() can be used with any PETSc object (such as
708: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
709: PetscContainerCreate() for info on how to create an object from a
710: user-provided pointer that may then be composed with PETSc objects.
712: Concepts: objects^composing
713: Concepts: composing objects
715: .seealso: PetscObjectQuery(), PetscContainerCreate()
716: @*/
717: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
718: {
725: (*obj->bops->compose)(obj,name,ptr);
726: return(0);
727: }
731: /*@C
732: PetscObjectSetPrecision - sets the precision used within a given object.
734: Collective on the PetscObject
736: Input Parameters:
737: + obj - the PETSc object; this must be cast with (PetscObject), for example,
738: PetscObjectCompose((PetscObject)mat,...);
739: - precision - the precision
741: Level: advanced
743: .seealso: PetscObjectQuery(), PetscContainerCreate()
744: @*/
745: PetscErrorCode PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
746: {
749: obj->precision = precision;
750: return(0);
751: }
755: /*@C
756: PetscObjectQuery - Gets a PETSc object associated with a given object.
758: Not Collective
760: Input Parameters:
761: + obj - the PETSc object
762: Thus must be cast with a (PetscObject), for example,
763: PetscObjectCompose((PetscObject)mat,...);
764: . name - name associated with child object
765: - ptr - the other PETSc object associated with the PETSc object, this must be
766: cast with (PetscObject*)
768: Level: advanced
770: The reference count of neither object is increased in this call
772: Concepts: objects^composing
773: Concepts: composing objects
774: Concepts: objects^querying
775: Concepts: querying objects
777: .seealso: PetscObjectCompose()
778: @*/
779: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
780: {
787: (*obj->bops->query)(obj,name,ptr);
788: return(0);
789: }
791: /*MC
792: PetscObjectComposeFunction - Associates a function with a given PETSc object.
794: Synopsis:
795: #include "petscsys.h"
796: PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))
798: Logically Collective on PetscObject
800: Input Parameters:
801: + obj - the PETSc object; this must be cast with a (PetscObject), for example,
802: PetscObjectCompose((PetscObject)mat,...);
803: . name - name associated with the child function
804: . fname - name of the function
805: - fptr - function pointer
807: Level: advanced
809: Notes:
810: To remove a registered routine, pass in NULL for fptr().
812: PetscObjectComposeFunction() can be used with any PETSc object (such as
813: Mat, Vec, KSP, SNES, etc.) or any user-provided object.
815: Concepts: objects^composing functions
816: Concepts: composing functions
817: Concepts: functions^querying
818: Concepts: objects^querying
819: Concepts: querying objects
821: .seealso: PetscObjectQueryFunction(), PetscContainerCreate()
822: M*/
826: PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
827: {
833: (*obj->bops->composefunction)(obj,name,fptr);
834: return(0);
835: }
837: /*MC
838: PetscObjectQueryFunction - Gets a function associated with a given object.
840: Synopsis:
841: #include "petscsys.h"
842: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))
844: Logically Collective on PetscObject
846: Input Parameters:
847: + obj - the PETSc object; this must be cast with (PetscObject), for example,
848: PetscObjectQueryFunction((PetscObject)ksp,...);
849: - name - name associated with the child function
851: Output Parameter:
852: . fptr - function pointer
854: Level: advanced
856: Concepts: objects^composing functions
857: Concepts: composing functions
858: Concepts: functions^querying
859: Concepts: objects^querying
860: Concepts: querying objects
862: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind()
863: M*/
866: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
867: {
873: (*obj->bops->queryfunction)(obj,name,ptr);
874: return(0);
875: }
877: struct _p_PetscContainer {
878: PETSCHEADER(int);
879: void *ptr;
880: PetscErrorCode (*userdestroy)(void*);
881: };
885: /*@C
886: PetscContainerGetPointer - Gets the pointer value contained in the container.
888: Not Collective
890: Input Parameter:
891: . obj - the object created with PetscContainerCreate()
893: Output Parameter:
894: . ptr - the pointer value
896: Level: advanced
898: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
899: PetscContainerSetPointer()
900: @*/
901: PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr)
902: {
906: *ptr = obj->ptr;
907: return(0);
908: }
913: /*@C
914: PetscContainerSetPointer - Sets the pointer value contained in the container.
916: Logically Collective on PetscContainer
918: Input Parameters:
919: + obj - the object created with PetscContainerCreate()
920: - ptr - the pointer value
922: Level: advanced
924: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
925: PetscContainerGetPointer()
926: @*/
927: PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr)
928: {
932: obj->ptr = ptr;
933: return(0);
934: }
938: /*@C
939: PetscContainerDestroy - Destroys a PETSc container object.
941: Collective on PetscContainer
943: Input Parameter:
944: . obj - an object that was created with PetscContainerCreate()
946: Level: advanced
948: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
949: @*/
950: PetscErrorCode PetscContainerDestroy(PetscContainer *obj)
951: {
955: if (!*obj) return(0);
957: if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; return(0);}
958: if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
959: PetscHeaderDestroy(obj);
960: return(0);
961: }
965: /*@C
966: PetscContainerSetUserDestroy - Sets name of the user destroy function.
968: Logically Collective on PetscContainer
970: Input Parameter:
971: + obj - an object that was created with PetscContainerCreate()
972: - des - name of the user destroy function
974: Level: advanced
976: .seealso: PetscContainerDestroy()
977: @*/
978: PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
979: {
982: obj->userdestroy = des;
983: return(0);
984: }
986: PetscClassId PETSC_CONTAINER_CLASSID;
990: /*@C
991: PetscContainerCreate - Creates a PETSc object that has room to hold
992: a single pointer. This allows one to attach any type of data (accessible
993: through a pointer) with the PetscObjectCompose() function to a PetscObject.
994: The data item itself is attached by a call to PetscContainerSetPointer().
996: Collective on MPI_Comm
998: Input Parameters:
999: . comm - MPI communicator that shares the object
1001: Output Parameters:
1002: . container - the container created
1004: Level: advanced
1006: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
1007: @*/
1008: PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
1009: {
1011: PetscContainer contain;
1015: PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);
1016: *container = contain;
1017: return(0);
1018: }
1022: /*@
1023: PetscObjectSetFromOptions - Sets generic parameters from user options.
1025: Collective on obj
1027: Input Parameter:
1028: . obj - the PetscObjcet
1030: Options Database Keys:
1032: Notes:
1033: We have no generic options at present, so this does nothing
1035: Level: beginner
1037: .keywords: set, options, database
1038: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
1039: @*/
1040: PetscErrorCode PetscObjectSetFromOptions(PetscObject obj)
1041: {
1044: return(0);
1045: }
1049: /*@
1050: PetscObjectSetUp - Sets up the internal data structures for the later use.
1052: Collective on PetscObject
1054: Input Parameters:
1055: . obj - the PetscObject
1057: Notes:
1058: This does nothing at present.
1060: Level: advanced
1062: .keywords: setup
1063: .seealso: PetscObjectDestroy()
1064: @*/
1065: PetscErrorCode PetscObjectSetUp(PetscObject obj)
1066: {
1069: return(0);
1070: }