Actual source code: inherit.c
petsc-3.4.5 2014-06-29
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 = 0;
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: if (stack) {
300: k = stack->currentsize-2;
301: if (!all) {
302: k = 0;
303: while (!stack->petscroutine[k]) k++;
304: PetscStrstr(stack->function[k],"Create",&create);
305: if (!create) {
306: PetscStrstr(stack->function[k],"Get",&create);
307: }
308: PetscStrstr(stack->function[k],h->class_name,&rclass);
309: if (!create) continue;
310: if (!rclass) continue;
311: }
312: }
313: #endif
315: PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);
317: #if defined(PETSC_USE_DEBUG)
318: PetscMallocGetStack(h,&stack);
319: if (stack) {
320: for (j=k; j>=0; j--) {
321: fprintf(fd," [%d] %s() in %s%s\n",PetscGlobalRank,stack->function[j],stack->directory[j],stack->file[j]);
322: }
323: }
324: #endif
325: }
326: }
327: }
328: }
329: return(0);
330: }
335: /*@C
336: PetscObjectsView - Prints the currently existing objects.
338: Logically Collective on PetscViewer
340: Input Parameter:
341: . viewer - must be an PETSCVIEWERASCII viewer
343: Level: advanced
345: Concepts: options database^printing
347: @*/
348: PetscErrorCode PetscObjectsView(PetscViewer viewer)
349: {
351: PetscBool isascii;
352: FILE *fd;
355: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
356: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
357: if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
358: PetscViewerASCIIGetPointer(viewer,&fd);
359: PetscObjectsDump(fd,PETSC_TRUE);
360: return(0);
361: }
365: /*@C
366: PetscObjectsGetObject - Get a pointer to a named object
368: Not collective
370: Input Parameter:
371: . name - the name of an object
373: Output Parameter:
374: . obj - the object or null if there is no object
376: Level: advanced
378: Concepts: options database^printing
380: @*/
381: PetscErrorCode PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
382: {
384: PetscInt i;
385: PetscObject h;
386: PetscBool flg;
389: *obj = NULL;
390: for (i=0; i<PetscObjectsMaxCounts; i++) {
391: if ((h = PetscObjects[i])) {
392: PetscObjectName(h);
393: PetscStrcmp(h->name,name,&flg);
394: if (flg) {
395: *obj = h;
396: if (classname) *classname = h->class_name;
397: return(0);
398: }
399: }
400: }
401: return(0);
402: }
406: char *PetscObjectsGetObjectMatlab(const char* name,PetscObject *obj)
407: {
409: PetscInt i;
410: PetscObject h;
411: PetscBool flg;
414: *obj = NULL;
415: for (i=0; i<PetscObjectsMaxCounts; i++) {
416: if ((h = PetscObjects[i])) {
417: PetscObjectName(h);if (ierr) return(0);
418: PetscStrcmp(h->name,name,&flg);if (ierr) return(0);
419: if (flg) {
420: *obj = h;
421: PetscFunctionReturn(h->class_name);
422: }
423: }
424: }
425: return(0);
426: }
430: /*@C
431: PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
433: Not Collective
435: Input Parameter:
436: + obj - the PETSc object
437: . handle - function that checks for options
438: . destroy - function to destroy context if provided
439: - ctx - optional context for check function
441: Level: developer
444: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()
446: @*/
447: PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
448: {
451: if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
452: obj->optionhandler[obj->noptionhandler] = handle;
453: obj->optiondestroy[obj->noptionhandler] = destroy;
454: obj->optionctx[obj->noptionhandler++] = ctx;
455: return(0);
456: }
460: /*@C
461: PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object
463: Not Collective
465: Input Parameter:
466: . obj - the PETSc object
468: Level: developer
471: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()
473: @*/
474: PetscErrorCode PetscObjectProcessOptionsHandlers(PetscObject obj)
475: {
476: PetscInt i;
481: for (i=0; i<obj->noptionhandler; i++) {
482: (*obj->optionhandler[i])(obj,obj->optionctx[i]);
483: }
484: return(0);
485: }
489: /*@C
490: PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object
492: Not Collective
494: Input Parameter:
495: . obj - the PETSc object
497: Level: developer
500: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
502: @*/
503: PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj)
504: {
505: PetscInt i;
510: for (i=0; i<obj->noptionhandler; i++) {
511: if (obj->optiondestroy[i]) {
512: (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
513: }
514: }
515: obj->noptionhandler = 0;
516: return(0);
517: }
522: /*@
523: PetscObjectReference - Indicates to any PetscObject that it is being
524: referenced by another PetscObject. This increases the reference
525: count for that object by one.
527: Logically Collective on PetscObject
529: Input Parameter:
530: . obj - the PETSc object. This must be cast with (PetscObject), for example,
531: PetscObjectReference((PetscObject)mat);
533: Level: advanced
535: .seealso: PetscObjectCompose(), PetscObjectDereference()
536: @*/
537: PetscErrorCode PetscObjectReference(PetscObject obj)
538: {
540: if (!obj) return(0);
542: obj->refct++;
543: return(0);
544: }
548: /*@
549: PetscObjectGetReference - Gets the current reference count for
550: any PETSc object.
552: Not Collective
554: Input Parameter:
555: . obj - the PETSc object; this must be cast with (PetscObject), for example,
556: PetscObjectGetReference((PetscObject)mat,&cnt);
558: Output Parameter:
559: . cnt - the reference count
561: Level: advanced
563: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
564: @*/
565: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
566: {
570: *cnt = obj->refct;
571: return(0);
572: }
576: /*@
577: PetscObjectDereference - Indicates to any PetscObject that it is being
578: referenced by one less PetscObject. This decreases the reference
579: count for that object by one.
581: Collective on PetscObject if reference reaches 0 otherwise Logically Collective
583: Input Parameter:
584: . obj - the PETSc object; this must be cast with (PetscObject), for example,
585: PetscObjectDereference((PetscObject)mat);
587: Notes: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not.
589: Level: advanced
591: .seealso: PetscObjectCompose(), PetscObjectReference()
592: @*/
593: PetscErrorCode PetscObjectDereference(PetscObject obj)
594: {
599: if (obj->bops->destroy) {
600: (*obj->bops->destroy)(&obj);
601: } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
602: return(0);
603: }
605: /* ----------------------------------------------------------------------- */
606: /*
607: The following routines are the versions private to the PETSc object
608: data structures.
609: */
612: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
613: {
616: *comm = obj->comm;
617: return(0);
618: }
622: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
623: {
628: PetscObjectListRemoveReference(&obj->olist,name);
629: return(0);
630: }
634: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
635: {
637: char *tname;
638: PetscBool skipreference;
641: if (ptr) {
642: PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
643: if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
644: }
645: PetscObjectListAdd(&obj->olist,name,ptr);
646: return(0);
647: }
651: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
652: {
657: PetscObjectListFind(obj->olist,name,ptr);
658: return(0);
659: }
663: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
664: {
669: PetscFunctionListAdd(&obj->qlist,name,ptr);
670: return(0);
671: }
675: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
676: {
681: PetscFunctionListFind(obj->qlist,name,ptr);
682: return(0);
683: }
687: /*@C
688: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
690: Not Collective
692: Input Parameters:
693: + obj - the PETSc object; this must be cast with (PetscObject), for example,
694: PetscObjectCompose((PetscObject)mat,...);
695: . name - name associated with the child object
696: - ptr - the other PETSc object to associate with the PETSc object; this must also be
697: cast with (PetscObject)
699: Level: advanced
701: Notes:
702: The second objects reference count is automatically increased by one when it is
703: composed.
705: Replaces any previous object that had the same name.
707: If ptr is null and name has previously been composed using an object, then that
708: entry is removed from the obj.
710: PetscObjectCompose() can be used with any PETSc object (such as
711: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
712: PetscContainerCreate() for info on how to create an object from a
713: user-provided pointer that may then be composed with PETSc objects.
715: Concepts: objects^composing
716: Concepts: composing objects
718: .seealso: PetscObjectQuery(), PetscContainerCreate()
719: @*/
720: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
721: {
728: (*obj->bops->compose)(obj,name,ptr);
729: return(0);
730: }
734: /*@C
735: PetscObjectSetPrecision - sets the precision used within a given object.
737: Collective on the PetscObject
739: Input Parameters:
740: + obj - the PETSc object; this must be cast with (PetscObject), for example,
741: PetscObjectCompose((PetscObject)mat,...);
742: - precision - the precision
744: Level: advanced
746: .seealso: PetscObjectQuery(), PetscContainerCreate()
747: @*/
748: PetscErrorCode PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
749: {
752: obj->precision = precision;
753: return(0);
754: }
758: /*@C
759: PetscObjectQuery - Gets a PETSc object associated with a given object.
761: Not Collective
763: Input Parameters:
764: + obj - the PETSc object
765: Thus must be cast with a (PetscObject), for example,
766: PetscObjectCompose((PetscObject)mat,...);
767: . name - name associated with child object
768: - ptr - the other PETSc object associated with the PETSc object, this must be
769: cast with (PetscObject*)
771: Level: advanced
773: The reference count of neither object is increased in this call
775: Concepts: objects^composing
776: Concepts: composing objects
777: Concepts: objects^querying
778: Concepts: querying objects
780: .seealso: PetscObjectCompose()
781: @*/
782: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
783: {
790: (*obj->bops->query)(obj,name,ptr);
791: return(0);
792: }
794: /*MC
795: PetscObjectComposeFunction - Associates a function with a given PETSc object.
797: Synopsis:
798: #include "petscsys.h"
799: PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))
801: Logically Collective on PetscObject
803: Input Parameters:
804: + obj - the PETSc object; this must be cast with a (PetscObject), for example,
805: PetscObjectCompose((PetscObject)mat,...);
806: . name - name associated with the child function
807: . fname - name of the function
808: - fptr - function pointer
810: Level: advanced
812: Notes:
813: To remove a registered routine, pass in NULL for fptr().
815: PetscObjectComposeFunction() can be used with any PETSc object (such as
816: Mat, Vec, KSP, SNES, etc.) or any user-provided object.
818: Concepts: objects^composing functions
819: Concepts: composing functions
820: Concepts: functions^querying
821: Concepts: objects^querying
822: Concepts: querying objects
824: .seealso: PetscObjectQueryFunction(), PetscContainerCreate()
825: M*/
829: PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
830: {
836: (*obj->bops->composefunction)(obj,name,fptr);
837: return(0);
838: }
840: /*MC
841: PetscObjectQueryFunction - Gets a function associated with a given object.
843: Synopsis:
844: #include "petscsys.h"
845: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))
847: Logically Collective on PetscObject
849: Input Parameters:
850: + obj - the PETSc object; this must be cast with (PetscObject), for example,
851: PetscObjectQueryFunction((PetscObject)ksp,...);
852: - name - name associated with the child function
854: Output Parameter:
855: . fptr - function pointer
857: Level: advanced
859: Concepts: objects^composing functions
860: Concepts: composing functions
861: Concepts: functions^querying
862: Concepts: objects^querying
863: Concepts: querying objects
865: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind()
866: M*/
869: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
870: {
876: (*obj->bops->queryfunction)(obj,name,ptr);
877: return(0);
878: }
880: struct _p_PetscContainer {
881: PETSCHEADER(int);
882: void *ptr;
883: PetscErrorCode (*userdestroy)(void*);
884: };
888: /*@C
889: PetscContainerGetPointer - Gets the pointer value contained in the container.
891: Not Collective
893: Input Parameter:
894: . obj - the object created with PetscContainerCreate()
896: Output Parameter:
897: . ptr - the pointer value
899: Level: advanced
901: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
902: PetscContainerSetPointer()
903: @*/
904: PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr)
905: {
909: *ptr = obj->ptr;
910: return(0);
911: }
916: /*@C
917: PetscContainerSetPointer - Sets the pointer value contained in the container.
919: Logically Collective on PetscContainer
921: Input Parameters:
922: + obj - the object created with PetscContainerCreate()
923: - ptr - the pointer value
925: Level: advanced
927: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
928: PetscContainerGetPointer()
929: @*/
930: PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr)
931: {
935: obj->ptr = ptr;
936: return(0);
937: }
941: /*@C
942: PetscContainerDestroy - Destroys a PETSc container object.
944: Collective on PetscContainer
946: Input Parameter:
947: . obj - an object that was created with PetscContainerCreate()
949: Level: advanced
951: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
952: @*/
953: PetscErrorCode PetscContainerDestroy(PetscContainer *obj)
954: {
958: if (!*obj) return(0);
960: if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; return(0);}
961: if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
962: PetscHeaderDestroy(obj);
963: return(0);
964: }
968: /*@C
969: PetscContainerSetUserDestroy - Sets name of the user destroy function.
971: Logically Collective on PetscContainer
973: Input Parameter:
974: + obj - an object that was created with PetscContainerCreate()
975: - des - name of the user destroy function
977: Level: advanced
979: .seealso: PetscContainerDestroy()
980: @*/
981: PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
982: {
985: obj->userdestroy = des;
986: return(0);
987: }
989: PetscClassId PETSC_CONTAINER_CLASSID;
993: /*@C
994: PetscContainerCreate - Creates a PETSc object that has room to hold
995: a single pointer. This allows one to attach any type of data (accessible
996: through a pointer) with the PetscObjectCompose() function to a PetscObject.
997: The data item itself is attached by a call to PetscContainerSetPointer().
999: Collective on MPI_Comm
1001: Input Parameters:
1002: . comm - MPI communicator that shares the object
1004: Output Parameters:
1005: . container - the container created
1007: Level: advanced
1009: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
1010: @*/
1011: PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
1012: {
1014: PetscContainer contain;
1018: PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);
1019: *container = contain;
1020: return(0);
1021: }
1025: /*@
1026: PetscObjectSetFromOptions - Sets generic parameters from user options.
1028: Collective on obj
1030: Input Parameter:
1031: . obj - the PetscObjcet
1033: Options Database Keys:
1035: Notes:
1036: We have no generic options at present, so this does nothing
1038: Level: beginner
1040: .keywords: set, options, database
1041: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
1042: @*/
1043: PetscErrorCode PetscObjectSetFromOptions(PetscObject obj)
1044: {
1047: return(0);
1048: }
1052: /*@
1053: PetscObjectSetUp - Sets up the internal data structures for the later use.
1055: Collective on PetscObject
1057: Input Parameters:
1058: . obj - the PetscObject
1060: Notes:
1061: This does nothing at present.
1063: Level: advanced
1065: .keywords: setup
1066: .seealso: PetscObjectDestroy()
1067: @*/
1068: PetscErrorCode PetscObjectSetUp(PetscObject obj)
1069: {
1072: return(0);
1073: }