Actual source code: inherit.c
petsc-3.5.4 2015-05-23
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: #if defined(PETSC_USE_LOG)
9: PetscObject *PetscObjects = 0;
10: PetscInt PetscObjectsCounts = 0, PetscObjectsMaxCounts = 0;
11: PetscBool PetscObjectsLog = PETSC_FALSE;
12: #endif
14: extern PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm*);
15: extern PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject);
16: extern PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject*);
17: extern PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],void (*)(void));
18: extern PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void));
22: /*
23: PetscHeaderCreate_Private - Creates a base PETSc object header and fills
24: in the default values. Called by the macro PetscHeaderCreate().
25: */
26: PetscErrorCode PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,const char class_name[],const char descr[],const char mansec[],
27: MPI_Comm comm,PetscErrorCode (*des)(PetscObject*),PetscErrorCode (*vie)(PetscObject,PetscViewer))
28: {
29: static PetscInt idcnt = 1;
30: PetscErrorCode ierr;
31: #if defined(PETSC_USE_LOG)
32: PetscObject *newPetscObjects;
33: PetscInt newPetscObjectsMaxCounts,i;
34: #endif
37: h->classid = classid;
38: h->type = 0;
39: h->class_name = (char*)class_name;
40: h->description = (char*)descr;
41: h->mansec = (char*)mansec;
42: h->prefix = 0;
43: h->refct = 1;
44: #if defined(PETSC_HAVE_SAWS)
45: h->amsmem = PETSC_FALSE;
46: #endif
47: h->id = idcnt++;
48: h->parentid = 0;
49: h->qlist = 0;
50: h->olist = 0;
51: h->precision = (PetscPrecision) sizeof(PetscReal);
52: h->bops->destroy = des;
53: h->bops->view = vie;
54: h->bops->getcomm = PetscObjectGetComm_Petsc;
55: h->bops->compose = PetscObjectCompose_Petsc;
56: h->bops->query = PetscObjectQuery_Petsc;
57: h->bops->composefunction = PetscObjectComposeFunction_Petsc;
58: h->bops->queryfunction = PetscObjectQueryFunction_Petsc;
60: PetscCommDuplicate(comm,&h->comm,&h->tag);
62: #if defined(PETSC_USE_LOG)
63: /* Keep a record of object created */
64: if (PetscObjectsLog) {
65: PetscObjectsCounts++;
66: for (i=0; i<PetscObjectsMaxCounts; i++) {
67: if (!PetscObjects[i]) {
68: PetscObjects[i] = h;
69: return(0);
70: }
71: }
72: /* Need to increase the space for storing PETSc objects */
73: if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100;
74: else newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts;
75: PetscMalloc1(newPetscObjectsMaxCounts,&newPetscObjects);
76: PetscMemcpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts*sizeof(PetscObject));
77: PetscMemzero(newPetscObjects+PetscObjectsMaxCounts,(newPetscObjectsMaxCounts - PetscObjectsMaxCounts)*sizeof(PetscObject));
78: PetscFree(PetscObjects);
80: PetscObjects = newPetscObjects;
81: PetscObjects[PetscObjectsMaxCounts] = h;
82: PetscObjectsMaxCounts = newPetscObjectsMaxCounts;
83: }
84: #endif
85: return(0);
86: }
88: extern PetscBool PetscMemoryCollectMaximumUsage;
89: extern PetscLogDouble PetscMemoryMaximumUsage;
93: /*
94: PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
95: the macro PetscHeaderDestroy().
96: */
97: PetscErrorCode PetscHeaderDestroy_Private(PetscObject h)
98: {
103: PetscLogObjectDestroy(h);
104: PetscComposedQuantitiesDestroy(h);
105: if (PetscMemoryCollectMaximumUsage) {
106: PetscLogDouble usage;
107: PetscMemoryGetCurrentUsage(&usage);
108: if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
109: }
110: /* first destroy things that could execute arbitrary code */
111: if (h->python_destroy) {
112: void *python_context = h->python_context;
113: PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
114: h->python_context = 0;
115: h->python_destroy = 0;
117: (*python_destroy)(python_context);
118: }
119: PetscObjectDestroyOptionsHandlers(h);
120: PetscObjectListDestroy(&h->olist);
121: PetscCommDestroy(&h->comm);
122: /* next destroy other things */
123: h->classid = PETSCFREEDHEADER;
125: PetscFree(h->bops);
126: PetscFunctionListDestroy(&h->qlist);
127: PetscFree(h->type_name);
128: PetscFree(h->name);
129: PetscFree(h->prefix);
130: PetscFree(h->fortran_func_pointers);
131: PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_CLASS]);
132: PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
134: #if defined(PETSC_USE_LOG)
135: if (PetscObjectsLog) {
136: PetscInt i;
137: /* Record object removal from list of all objects */
138: for (i=0; i<PetscObjectsMaxCounts; i++) {
139: if (PetscObjects[i] == h) {
140: PetscObjects[i] = 0;
141: PetscObjectsCounts--;
142: break;
143: }
144: }
145: if (!PetscObjectsCounts) {
146: PetscFree(PetscObjects);
147: PetscObjectsMaxCounts = 0;
148: }
149: }
150: #endif
151: return(0);
152: }
156: /*@C
157: PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object
159: Logically Collective on PetscObject
161: Input Parameter:
162: + src - source object
163: - dest - destination object
165: Level: developer
167: Note:
168: Both objects must have the same class.
169: @*/
170: PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest)
171: {
173: PetscInt cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE];
178: if (src->classid != dest->classid) SETERRQ(src->comm,PETSC_ERR_ARG_INCOMP,"Objects must be of the same class");
180: PetscFree(dest->fortran_func_pointers);
181: PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);
182: PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));
184: dest->num_fortran_func_pointers = src->num_fortran_func_pointers;
186: PetscFortranCallbackGetSizes(src->classid,&numcb[PETSC_FORTRAN_CALLBACK_CLASS],&numcb[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
187: for (cbtype=PETSC_FORTRAN_CALLBACK_CLASS; cbtype<PETSC_FORTRAN_CALLBACK_MAXTYPE; cbtype++) {
188: PetscFree(dest->fortrancallback[cbtype]);
189: PetscCalloc1(numcb[cbtype],&dest->fortrancallback[cbtype]);
190: PetscMemcpy(dest->fortrancallback[cbtype],src->fortrancallback[cbtype],src->num_fortrancallback[cbtype]*sizeof(PetscFortranCallback));
191: }
192: return(0);
193: }
197: /*@C
198: PetscObjectSetFortranCallback - set fortran callback function pointer and context
200: Logically Collective
202: Input Arguments:
203: + obj - object on which to set callback
204: . cbtype - callback type (class or subtype)
205: . cid - address of callback Id, updated if not yet initialized (zero)
206: . func - Fortran function
207: - ctx - Fortran context
209: Level: developer
211: .seealso: PetscObjectGetFortranCallback()
212: @*/
213: PetscErrorCode PetscObjectSetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId *cid,void (*func)(void),void *ctx)
214: {
216: const char *subtype = NULL;
220: if (cbtype == PETSC_FORTRAN_CALLBACK_SUBTYPE) subtype = obj->type_name;
221: if (!*cid) {PetscFortranCallbackRegister(obj->classid,subtype,cid);}
222: if (*cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype]) {
223: PetscInt oldnum = obj->num_fortrancallback[cbtype],newnum = PetscMax(1,2*oldnum);
224: PetscFortranCallback *callback;
225: PetscMalloc1(newnum,&callback);
226: PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));
227: PetscFree(obj->fortrancallback[cbtype]);
229: obj->fortrancallback[cbtype] = callback;
230: obj->num_fortrancallback[cbtype] = newnum;
231: }
232: obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func;
233: obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx;
234: return(0);
235: }
239: /*@C
240: PetscObjectGetFortranCallback - get fortran callback function pointer and context
242: Logically Collective
244: Input Arguments:
245: + obj - object on which to get callback
246: . cbtype - callback type
247: - cid - address of callback Id
249: Output Arguments:
250: + func - Fortran function (or NULL if not needed)
251: - ctx - Fortran context (or NULL if not needed)
253: Level: developer
255: .seealso: PetscObjectSetFortranCallback()
256: @*/
257: PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx)
258: {
259: PetscFortranCallback *cb;
263: if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid");
264: 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");
265: cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK];
266: if (func) *func = cb->func;
267: if (ctx) *ctx = cb->ctx;
268: return(0);
269: }
271: #if defined(PETSC_USE_LOG)
274: /*@C
275: PetscObjectsDump - Prints the currently existing objects.
277: Logically Collective on PetscViewer
279: Input Parameter:
280: + viewer - must be an PETSCVIEWERASCII viewer
281: - all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects
283: Level: advanced
285: Concepts: options database^printing
287: @*/
288: PetscErrorCode PetscObjectsDump(FILE *fd,PetscBool all)
289: {
291: PetscInt i;
292: #if defined(PETSC_USE_DEBUG)
293: PetscInt j,k=0;
294: #endif
295: PetscObject h;
298: if (PetscObjectsCounts) {
299: PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");
300: PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");
301: for (i=0; i<PetscObjectsMaxCounts; i++) {
302: if ((h = PetscObjects[i])) {
303: PetscObjectName(h);
304: {
305: #if defined(PETSC_USE_DEBUG)
306: PetscStack *stack = 0;
307: char *create,*rclass;
309: /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */
310: PetscMallocGetStack(h,&stack);
311: if (stack) {
312: k = stack->currentsize-2;
313: if (!all) {
314: k = 0;
315: while (!stack->petscroutine[k]) k++;
316: PetscStrstr(stack->function[k],"Create",&create);
317: if (!create) {
318: PetscStrstr(stack->function[k],"Get",&create);
319: }
320: PetscStrstr(stack->function[k],h->class_name,&rclass);
321: if (!create) continue;
322: if (!rclass) continue;
323: }
324: }
325: #endif
327: PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);
329: #if defined(PETSC_USE_DEBUG)
330: PetscMallocGetStack(h,&stack);
331: if (stack) {
332: for (j=k; j>=0; j--) {
333: fprintf(fd," [%d] %s() in %s\n",PetscGlobalRank,stack->function[j],stack->file[j]);
334: }
335: }
336: #endif
337: }
338: }
339: }
340: }
341: return(0);
342: }
343: #endif
345: #if defined(PETSC_USE_LOG)
349: /*@C
350: PetscObjectsView - Prints the currently existing objects.
352: Logically Collective on PetscViewer
354: Input Parameter:
355: . viewer - must be an PETSCVIEWERASCII viewer
357: Level: advanced
359: Concepts: options database^printing
361: @*/
362: PetscErrorCode PetscObjectsView(PetscViewer viewer)
363: {
365: PetscBool isascii;
366: FILE *fd;
369: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
370: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
371: if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
372: PetscViewerASCIIGetPointer(viewer,&fd);
373: PetscObjectsDump(fd,PETSC_TRUE);
374: return(0);
375: }
379: /*@C
380: PetscObjectsGetObject - Get a pointer to a named object
382: Not collective
384: Input Parameter:
385: . name - the name of an object
387: Output Parameter:
388: . obj - the object or null if there is no object
390: Level: advanced
392: Concepts: options database^printing
394: @*/
395: PetscErrorCode PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
396: {
398: PetscInt i;
399: PetscObject h;
400: PetscBool flg;
403: *obj = NULL;
404: for (i=0; i<PetscObjectsMaxCounts; i++) {
405: if ((h = PetscObjects[i])) {
406: PetscObjectName(h);
407: PetscStrcmp(h->name,name,&flg);
408: if (flg) {
409: *obj = h;
410: if (classname) *classname = h->class_name;
411: return(0);
412: }
413: }
414: }
415: return(0);
416: }
420: char *PetscObjectsGetObjectMatlab(const char* name,PetscObject *obj)
421: {
423: PetscInt i;
424: PetscObject h;
425: PetscBool flg;
428: *obj = NULL;
429: for (i=0; i<PetscObjectsMaxCounts; i++) {
430: if ((h = PetscObjects[i])) {
431: PetscObjectName(h);if (ierr) return(0);
432: PetscStrcmp(h->name,name,&flg);if (ierr) return(0);
433: if (flg) {
434: *obj = h;
435: PetscFunctionReturn(h->class_name);
436: }
437: }
438: }
439: return(0);
440: }
441: #endif
445: /*@C
446: PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
448: Not Collective
450: Input Parameter:
451: + obj - the PETSc object
452: . handle - function that checks for options
453: . destroy - function to destroy context if provided
454: - ctx - optional context for check function
456: Level: developer
459: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()
461: @*/
462: PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
463: {
466: if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
467: obj->optionhandler[obj->noptionhandler] = handle;
468: obj->optiondestroy[obj->noptionhandler] = destroy;
469: obj->optionctx[obj->noptionhandler++] = ctx;
470: return(0);
471: }
475: /*@C
476: PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object
478: Not Collective
480: Input Parameter:
481: . obj - the PETSc object
483: Level: developer
486: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()
488: @*/
489: PetscErrorCode PetscObjectProcessOptionsHandlers(PetscObject obj)
490: {
491: PetscInt i;
496: for (i=0; i<obj->noptionhandler; i++) {
497: (*obj->optionhandler[i])(obj,obj->optionctx[i]);
498: }
499: return(0);
500: }
504: /*@C
505: PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object
507: Not Collective
509: Input Parameter:
510: . obj - the PETSc object
512: Level: developer
515: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
517: @*/
518: PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj)
519: {
520: PetscInt i;
525: for (i=0; i<obj->noptionhandler; i++) {
526: if (obj->optiondestroy[i]) {
527: (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
528: }
529: }
530: obj->noptionhandler = 0;
531: return(0);
532: }
537: /*@
538: PetscObjectReference - Indicates to any PetscObject that it is being
539: referenced by another PetscObject. This increases the reference
540: count for that object by one.
542: Logically Collective on PetscObject
544: Input Parameter:
545: . obj - the PETSc object. This must be cast with (PetscObject), for example,
546: PetscObjectReference((PetscObject)mat);
548: Level: advanced
550: .seealso: PetscObjectCompose(), PetscObjectDereference()
551: @*/
552: PetscErrorCode PetscObjectReference(PetscObject obj)
553: {
555: if (!obj) return(0);
557: obj->refct++;
558: return(0);
559: }
563: /*@
564: PetscObjectGetReference - Gets the current reference count for
565: any PETSc object.
567: Not Collective
569: Input Parameter:
570: . obj - the PETSc object; this must be cast with (PetscObject), for example,
571: PetscObjectGetReference((PetscObject)mat,&cnt);
573: Output Parameter:
574: . cnt - the reference count
576: Level: advanced
578: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
579: @*/
580: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
581: {
585: *cnt = obj->refct;
586: return(0);
587: }
591: /*@
592: PetscObjectDereference - Indicates to any PetscObject that it is being
593: referenced by one less PetscObject. This decreases the reference
594: count for that object by one.
596: Collective on PetscObject if reference reaches 0 otherwise Logically Collective
598: Input Parameter:
599: . obj - the PETSc object; this must be cast with (PetscObject), for example,
600: PetscObjectDereference((PetscObject)mat);
602: Notes: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not.
604: Level: advanced
606: .seealso: PetscObjectCompose(), PetscObjectReference()
607: @*/
608: PetscErrorCode PetscObjectDereference(PetscObject obj)
609: {
613: if (!obj) return(0);
615: if (obj->bops->destroy) {
616: (*obj->bops->destroy)(&obj);
617: } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
618: return(0);
619: }
621: /* ----------------------------------------------------------------------- */
622: /*
623: The following routines are the versions private to the PETSc object
624: data structures.
625: */
628: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
629: {
632: *comm = obj->comm;
633: return(0);
634: }
638: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
639: {
644: PetscObjectListRemoveReference(&obj->olist,name);
645: return(0);
646: }
650: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
651: {
653: char *tname;
654: PetscBool skipreference;
657: if (ptr) {
658: PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
659: if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
660: }
661: PetscObjectListAdd(&obj->olist,name,ptr);
662: return(0);
663: }
667: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
668: {
673: PetscObjectListFind(obj->olist,name,ptr);
674: return(0);
675: }
679: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
680: {
685: PetscFunctionListAdd(&obj->qlist,name,ptr);
686: return(0);
687: }
691: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
692: {
697: PetscFunctionListFind(obj->qlist,name,ptr);
698: return(0);
699: }
703: /*@C
704: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
706: Not Collective
708: Input Parameters:
709: + obj - the PETSc object; this must be cast with (PetscObject), for example,
710: PetscObjectCompose((PetscObject)mat,...);
711: . name - name associated with the child object
712: - ptr - the other PETSc object to associate with the PETSc object; this must also be
713: cast with (PetscObject)
715: Level: advanced
717: Notes:
718: The second objects reference count is automatically increased by one when it is
719: composed.
721: Replaces any previous object that had the same name.
723: If ptr is null and name has previously been composed using an object, then that
724: entry is removed from the obj.
726: PetscObjectCompose() can be used with any PETSc object (such as
727: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
728: PetscContainerCreate() for info on how to create an object from a
729: user-provided pointer that may then be composed with PETSc objects.
731: Concepts: objects^composing
732: Concepts: composing objects
734: .seealso: PetscObjectQuery(), PetscContainerCreate()
735: @*/
736: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
737: {
744: (*obj->bops->compose)(obj,name,ptr);
745: return(0);
746: }
750: /*@C
751: PetscObjectSetPrecision - sets the precision used within a given object.
753: Collective on the PetscObject
755: Input Parameters:
756: + obj - the PETSc object; this must be cast with (PetscObject), for example,
757: PetscObjectCompose((PetscObject)mat,...);
758: - precision - the precision
760: Level: advanced
762: .seealso: PetscObjectQuery(), PetscContainerCreate()
763: @*/
764: PetscErrorCode PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
765: {
768: obj->precision = precision;
769: return(0);
770: }
774: /*@C
775: PetscObjectQuery - Gets a PETSc object associated with a given object.
777: Not Collective
779: Input Parameters:
780: + obj - the PETSc object
781: Thus must be cast with a (PetscObject), for example,
782: PetscObjectCompose((PetscObject)mat,...);
783: . name - name associated with child object
784: - ptr - the other PETSc object associated with the PETSc object, this must be
785: cast with (PetscObject*)
787: Level: advanced
789: The reference count of neither object is increased in this call
791: Concepts: objects^composing
792: Concepts: composing objects
793: Concepts: objects^querying
794: Concepts: querying objects
796: .seealso: PetscObjectCompose()
797: @*/
798: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
799: {
806: (*obj->bops->query)(obj,name,ptr);
807: return(0);
808: }
810: /*MC
811: PetscObjectComposeFunction - Associates a function with a given PETSc object.
813: Synopsis:
814: #include <petscsys.h>
815: PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))
817: Logically Collective on PetscObject
819: Input Parameters:
820: + obj - the PETSc object; this must be cast with a (PetscObject), for example,
821: PetscObjectCompose((PetscObject)mat,...);
822: . name - name associated with the child function
823: . fname - name of the function
824: - fptr - function pointer
826: Level: advanced
828: Notes:
829: To remove a registered routine, pass in NULL for fptr().
831: PetscObjectComposeFunction() can be used with any PETSc object (such as
832: Mat, Vec, KSP, SNES, etc.) or any user-provided object.
834: Concepts: objects^composing functions
835: Concepts: composing functions
836: Concepts: functions^querying
837: Concepts: objects^querying
838: Concepts: querying objects
840: .seealso: PetscObjectQueryFunction(), PetscContainerCreate()
841: M*/
845: PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
846: {
852: (*obj->bops->composefunction)(obj,name,fptr);
853: return(0);
854: }
856: /*MC
857: PetscObjectQueryFunction - Gets a function associated with a given object.
859: Synopsis:
860: #include <petscsys.h>
861: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))
863: Logically Collective on PetscObject
865: Input Parameters:
866: + obj - the PETSc object; this must be cast with (PetscObject), for example,
867: PetscObjectQueryFunction((PetscObject)ksp,...);
868: - name - name associated with the child function
870: Output Parameter:
871: . fptr - function pointer
873: Level: advanced
875: Concepts: objects^composing functions
876: Concepts: composing functions
877: Concepts: functions^querying
878: Concepts: objects^querying
879: Concepts: querying objects
881: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind()
882: M*/
885: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
886: {
892: (*obj->bops->queryfunction)(obj,name,ptr);
893: return(0);
894: }
896: struct _p_PetscContainer {
897: PETSCHEADER(int);
898: void *ptr;
899: PetscErrorCode (*userdestroy)(void*);
900: };
904: /*@C
905: PetscContainerGetPointer - Gets the pointer value contained in the container.
907: Not Collective
909: Input Parameter:
910: . obj - the object created with PetscContainerCreate()
912: Output Parameter:
913: . ptr - the pointer value
915: Level: advanced
917: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
918: PetscContainerSetPointer()
919: @*/
920: PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr)
921: {
925: *ptr = obj->ptr;
926: return(0);
927: }
932: /*@C
933: PetscContainerSetPointer - Sets the pointer value contained in the container.
935: Logically Collective on PetscContainer
937: Input Parameters:
938: + obj - the object created with PetscContainerCreate()
939: - ptr - the pointer value
941: Level: advanced
943: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
944: PetscContainerGetPointer()
945: @*/
946: PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr)
947: {
951: obj->ptr = ptr;
952: return(0);
953: }
957: /*@C
958: PetscContainerDestroy - Destroys a PETSc container object.
960: Collective on PetscContainer
962: Input Parameter:
963: . obj - an object that was created with PetscContainerCreate()
965: Level: advanced
967: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
968: @*/
969: PetscErrorCode PetscContainerDestroy(PetscContainer *obj)
970: {
974: if (!*obj) return(0);
976: if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; return(0);}
977: if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
978: PetscHeaderDestroy(obj);
979: return(0);
980: }
984: /*@C
985: PetscContainerSetUserDestroy - Sets name of the user destroy function.
987: Logically Collective on PetscContainer
989: Input Parameter:
990: + obj - an object that was created with PetscContainerCreate()
991: - des - name of the user destroy function
993: Level: advanced
995: .seealso: PetscContainerDestroy()
996: @*/
997: PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
998: {
1001: obj->userdestroy = des;
1002: return(0);
1003: }
1005: PetscClassId PETSC_CONTAINER_CLASSID;
1009: /*@C
1010: PetscContainerCreate - Creates a PETSc object that has room to hold
1011: a single pointer. This allows one to attach any type of data (accessible
1012: through a pointer) with the PetscObjectCompose() function to a PetscObject.
1013: The data item itself is attached by a call to PetscContainerSetPointer().
1015: Collective on MPI_Comm
1017: Input Parameters:
1018: . comm - MPI communicator that shares the object
1020: Output Parameters:
1021: . container - the container created
1023: Level: advanced
1025: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
1026: @*/
1027: PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
1028: {
1030: PetscContainer contain;
1034: PetscSysInitializePackage();
1035: PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);
1036: *container = contain;
1037: return(0);
1038: }
1042: /*@
1043: PetscObjectSetFromOptions - Sets generic parameters from user options.
1045: Collective on obj
1047: Input Parameter:
1048: . obj - the PetscObjcet
1050: Options Database Keys:
1052: Notes:
1053: We have no generic options at present, so this does nothing
1055: Level: beginner
1057: .keywords: set, options, database
1058: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
1059: @*/
1060: PetscErrorCode PetscObjectSetFromOptions(PetscObject obj)
1061: {
1064: return(0);
1065: }
1069: /*@
1070: PetscObjectSetUp - Sets up the internal data structures for the later use.
1072: Collective on PetscObject
1074: Input Parameters:
1075: . obj - the PetscObject
1077: Notes:
1078: This does nothing at present.
1080: Level: advanced
1082: .keywords: setup
1083: .seealso: PetscObjectDestroy()
1084: @*/
1085: PetscErrorCode PetscObjectSetUp(PetscObject obj)
1086: {
1089: return(0);
1090: }