Actual source code: inherit.c
petsc-3.4.0 2013-05-13
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: (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
509: }
510: obj->noptionhandler = 0;
511: return(0);
512: }
517: /*@
518: PetscObjectReference - Indicates to any PetscObject that it is being
519: referenced by another PetscObject. This increases the reference
520: count for that object by one.
522: Logically Collective on PetscObject
524: Input Parameter:
525: . obj - the PETSc object. This must be cast with (PetscObject), for example,
526: PetscObjectReference((PetscObject)mat);
528: Level: advanced
530: .seealso: PetscObjectCompose(), PetscObjectDereference()
531: @*/
532: PetscErrorCode PetscObjectReference(PetscObject obj)
533: {
535: if (!obj) return(0);
537: obj->refct++;
538: return(0);
539: }
543: /*@
544: PetscObjectGetReference - Gets the current reference count for
545: any PETSc object.
547: Not Collective
549: Input Parameter:
550: . obj - the PETSc object; this must be cast with (PetscObject), for example,
551: PetscObjectGetReference((PetscObject)mat,&cnt);
553: Output Parameter:
554: . cnt - the reference count
556: Level: advanced
558: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
559: @*/
560: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
561: {
565: *cnt = obj->refct;
566: return(0);
567: }
571: /*@
572: PetscObjectDereference - Indicates to any PetscObject that it is being
573: referenced by one less PetscObject. This decreases the reference
574: count for that object by one.
576: Collective on PetscObject if reference reaches 0 otherwise Logically Collective
578: Input Parameter:
579: . obj - the PETSc object; this must be cast with (PetscObject), for example,
580: PetscObjectDereference((PetscObject)mat);
582: Notes: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not.
584: Level: advanced
586: .seealso: PetscObjectCompose(), PetscObjectReference()
587: @*/
588: PetscErrorCode PetscObjectDereference(PetscObject obj)
589: {
594: if (obj->bops->destroy) {
595: (*obj->bops->destroy)(&obj);
596: } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
597: return(0);
598: }
600: /* ----------------------------------------------------------------------- */
601: /*
602: The following routines are the versions private to the PETSc object
603: data structures.
604: */
607: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
608: {
611: *comm = obj->comm;
612: return(0);
613: }
617: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
618: {
623: PetscObjectListRemoveReference(&obj->olist,name);
624: return(0);
625: }
629: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
630: {
632: char *tname;
633: PetscBool skipreference;
636: if (ptr) {
637: PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
638: if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
639: }
640: PetscObjectListAdd(&obj->olist,name,ptr);
641: return(0);
642: }
646: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
647: {
652: PetscObjectListFind(obj->olist,name,ptr);
653: return(0);
654: }
658: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
659: {
664: PetscFunctionListAdd(&obj->qlist,name,ptr);
665: return(0);
666: }
670: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
671: {
676: PetscFunctionListFind(obj->qlist,name,ptr);
677: return(0);
678: }
682: /*@C
683: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
685: Not Collective
687: Input Parameters:
688: + obj - the PETSc object; this must be cast with (PetscObject), for example,
689: PetscObjectCompose((PetscObject)mat,...);
690: . name - name associated with the child object
691: - ptr - the other PETSc object to associate with the PETSc object; this must also be
692: cast with (PetscObject)
694: Level: advanced
696: Notes:
697: The second objects reference count is automatically increased by one when it is
698: composed.
700: Replaces any previous object that had the same name.
702: If ptr is null and name has previously been composed using an object, then that
703: entry is removed from the obj.
705: PetscObjectCompose() can be used with any PETSc object (such as
706: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
707: PetscContainerCreate() for info on how to create an object from a
708: user-provided pointer that may then be composed with PETSc objects.
710: Concepts: objects^composing
711: Concepts: composing objects
713: .seealso: PetscObjectQuery(), PetscContainerCreate()
714: @*/
715: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
716: {
723: (*obj->bops->compose)(obj,name,ptr);
724: return(0);
725: }
729: /*@C
730: PetscObjectSetPrecision - sets the precision used within a given object.
732: Collective on the PetscObject
734: Input Parameters:
735: + obj - the PETSc object; this must be cast with (PetscObject), for example,
736: PetscObjectCompose((PetscObject)mat,...);
737: - precision - the precision
739: Level: advanced
741: .seealso: PetscObjectQuery(), PetscContainerCreate()
742: @*/
743: PetscErrorCode PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
744: {
747: obj->precision = precision;
748: return(0);
749: }
753: /*@C
754: PetscObjectQuery - Gets a PETSc object associated with a given object.
756: Not Collective
758: Input Parameters:
759: + obj - the PETSc object
760: Thus must be cast with a (PetscObject), for example,
761: PetscObjectCompose((PetscObject)mat,...);
762: . name - name associated with child object
763: - ptr - the other PETSc object associated with the PETSc object, this must be
764: cast with (PetscObject*)
766: Level: advanced
768: The reference count of neither object is increased in this call
770: Concepts: objects^composing
771: Concepts: composing objects
772: Concepts: objects^querying
773: Concepts: querying objects
775: .seealso: PetscObjectCompose()
776: @*/
777: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
778: {
785: (*obj->bops->query)(obj,name,ptr);
786: return(0);
787: }
789: /*MC
790: PetscObjectComposeFunction - Associates a function with a given PETSc object.
792: Synopsis:
793: #include "petscsys.h"
794: PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))
796: Logically Collective on PetscObject
798: Input Parameters:
799: + obj - the PETSc object; this must be cast with a (PetscObject), for example,
800: PetscObjectCompose((PetscObject)mat,...);
801: . name - name associated with the child function
802: . fname - name of the function
803: - fptr - function pointer
805: Level: advanced
807: Notes:
808: To remove a registered routine, pass in NULL for fptr().
810: PetscObjectComposeFunction() can be used with any PETSc object (such as
811: Mat, Vec, KSP, SNES, etc.) or any user-provided object.
813: Concepts: objects^composing functions
814: Concepts: composing functions
815: Concepts: functions^querying
816: Concepts: objects^querying
817: Concepts: querying objects
819: .seealso: PetscObjectQueryFunction(), PetscContainerCreate()
820: M*/
824: PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
825: {
831: (*obj->bops->composefunction)(obj,name,fptr);
832: return(0);
833: }
835: /*MC
836: PetscObjectQueryFunction - Gets a function associated with a given object.
838: Synopsis:
839: #include "petscsys.h"
840: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))
842: Logically Collective on PetscObject
844: Input Parameters:
845: + obj - the PETSc object; this must be cast with (PetscObject), for example,
846: PetscObjectQueryFunction((PetscObject)ksp,...);
847: - name - name associated with the child function
849: Output Parameter:
850: . fptr - function pointer
852: Level: advanced
854: Concepts: objects^composing functions
855: Concepts: composing functions
856: Concepts: functions^querying
857: Concepts: objects^querying
858: Concepts: querying objects
860: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind()
861: M*/
864: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
865: {
871: (*obj->bops->queryfunction)(obj,name,ptr);
872: return(0);
873: }
875: struct _p_PetscContainer {
876: PETSCHEADER(int);
877: void *ptr;
878: PetscErrorCode (*userdestroy)(void*);
879: };
883: /*@C
884: PetscContainerGetPointer - Gets the pointer value contained in the container.
886: Not Collective
888: Input Parameter:
889: . obj - the object created with PetscContainerCreate()
891: Output Parameter:
892: . ptr - the pointer value
894: Level: advanced
896: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
897: PetscContainerSetPointer()
898: @*/
899: PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr)
900: {
904: *ptr = obj->ptr;
905: return(0);
906: }
911: /*@C
912: PetscContainerSetPointer - Sets the pointer value contained in the container.
914: Logically Collective on PetscContainer
916: Input Parameters:
917: + obj - the object created with PetscContainerCreate()
918: - ptr - the pointer value
920: Level: advanced
922: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
923: PetscContainerGetPointer()
924: @*/
925: PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr)
926: {
930: obj->ptr = ptr;
931: return(0);
932: }
936: /*@C
937: PetscContainerDestroy - Destroys a PETSc container object.
939: Collective on PetscContainer
941: Input Parameter:
942: . obj - an object that was created with PetscContainerCreate()
944: Level: advanced
946: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
947: @*/
948: PetscErrorCode PetscContainerDestroy(PetscContainer *obj)
949: {
953: if (!*obj) return(0);
955: if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; return(0);}
956: if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
957: PetscHeaderDestroy(obj);
958: return(0);
959: }
963: /*@C
964: PetscContainerSetUserDestroy - Sets name of the user destroy function.
966: Logically Collective on PetscContainer
968: Input Parameter:
969: + obj - an object that was created with PetscContainerCreate()
970: - des - name of the user destroy function
972: Level: advanced
974: .seealso: PetscContainerDestroy()
975: @*/
976: PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
977: {
980: obj->userdestroy = des;
981: return(0);
982: }
984: PetscClassId PETSC_CONTAINER_CLASSID;
988: /*@C
989: PetscContainerCreate - Creates a PETSc object that has room to hold
990: a single pointer. This allows one to attach any type of data (accessible
991: through a pointer) with the PetscObjectCompose() function to a PetscObject.
992: The data item itself is attached by a call to PetscContainerSetPointer().
994: Collective on MPI_Comm
996: Input Parameters:
997: . comm - MPI communicator that shares the object
999: Output Parameters:
1000: . container - the container created
1002: Level: advanced
1004: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
1005: @*/
1006: PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
1007: {
1009: PetscContainer contain;
1013: PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);
1014: *container = contain;
1015: return(0);
1016: }
1020: /*@
1021: PetscObjectSetFromOptions - Sets generic parameters from user options.
1023: Collective on obj
1025: Input Parameter:
1026: . obj - the PetscObjcet
1028: Options Database Keys:
1030: Notes:
1031: We have no generic options at present, so this does nothing
1033: Level: beginner
1035: .keywords: set, options, database
1036: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
1037: @*/
1038: PetscErrorCode PetscObjectSetFromOptions(PetscObject obj)
1039: {
1042: return(0);
1043: }
1047: /*@
1048: PetscObjectSetUp - Sets up the internal data structures for the later use.
1050: Collective on PetscObject
1052: Input Parameters:
1053: . obj - the PetscObject
1055: Notes:
1056: This does nothing at present.
1058: Level: advanced
1060: .keywords: setup
1061: .seealso: PetscObjectDestroy()
1062: @*/
1063: PetscErrorCode PetscObjectSetUp(PetscObject obj)
1064: {
1067: return(0);
1068: }