Actual source code: inherit.c
petsc-3.7.7 2017-09-25
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,PetscObjectDestroyFunction destroy,PetscObjectViewFunction view)
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 = destroy;
53: h->bops->view = view;
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: PetscFunctionListDestroy(&h->qlist);
126: PetscFree(h->type_name);
127: PetscFree(h->name);
128: PetscFree(h->prefix);
129: PetscFree(h->fortran_func_pointers);
130: PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_CLASS]);
131: PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
133: #if defined(PETSC_USE_LOG)
134: if (PetscObjectsLog) {
135: PetscInt i;
136: /* Record object removal from list of all objects */
137: for (i=0; i<PetscObjectsMaxCounts; i++) {
138: if (PetscObjects[i] == h) {
139: PetscObjects[i] = 0;
140: PetscObjectsCounts--;
141: break;
142: }
143: }
144: if (!PetscObjectsCounts) {
145: PetscFree(PetscObjects);
146: PetscObjectsMaxCounts = 0;
147: }
148: }
149: #endif
150: return(0);
151: }
155: /*@C
156: PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object
158: Logically Collective on PetscObject
160: Input Parameter:
161: + src - source object
162: - dest - destination object
164: Level: developer
166: Note:
167: Both objects must have the same class.
168: @*/
169: PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest)
170: {
172: PetscInt cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE];
177: if (src->classid != dest->classid) SETERRQ(src->comm,PETSC_ERR_ARG_INCOMP,"Objects must be of the same class");
179: PetscFree(dest->fortran_func_pointers);
180: PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);
181: PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));
183: dest->num_fortran_func_pointers = src->num_fortran_func_pointers;
185: PetscFortranCallbackGetSizes(src->classid,&numcb[PETSC_FORTRAN_CALLBACK_CLASS],&numcb[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
186: for (cbtype=PETSC_FORTRAN_CALLBACK_CLASS; cbtype<PETSC_FORTRAN_CALLBACK_MAXTYPE; cbtype++) {
187: PetscFree(dest->fortrancallback[cbtype]);
188: PetscCalloc1(numcb[cbtype],&dest->fortrancallback[cbtype]);
189: PetscMemcpy(dest->fortrancallback[cbtype],src->fortrancallback[cbtype],src->num_fortrancallback[cbtype]*sizeof(PetscFortranCallback));
190: }
191: return(0);
192: }
196: /*@C
197: PetscObjectSetFortranCallback - set fortran callback function pointer and context
199: Logically Collective
201: Input Arguments:
202: + obj - object on which to set callback
203: . cbtype - callback type (class or subtype)
204: . cid - address of callback Id, updated if not yet initialized (zero)
205: . func - Fortran function
206: - ctx - Fortran context
208: Level: developer
210: .seealso: PetscObjectGetFortranCallback()
211: @*/
212: PetscErrorCode PetscObjectSetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId *cid,void (*func)(void),void *ctx)
213: {
215: const char *subtype = NULL;
219: if (cbtype == PETSC_FORTRAN_CALLBACK_SUBTYPE) subtype = obj->type_name;
220: if (!*cid) {PetscFortranCallbackRegister(obj->classid,subtype,cid);}
221: if (*cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype]) {
222: PetscInt oldnum = obj->num_fortrancallback[cbtype],newnum = PetscMax(1,2*oldnum);
223: PetscFortranCallback *callback;
224: PetscMalloc1(newnum,&callback);
225: PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));
226: PetscFree(obj->fortrancallback[cbtype]);
228: obj->fortrancallback[cbtype] = callback;
229: obj->num_fortrancallback[cbtype] = newnum;
230: }
231: obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func;
232: obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx;
233: return(0);
234: }
238: /*@C
239: PetscObjectGetFortranCallback - get fortran callback function pointer and context
241: Logically Collective
243: Input Arguments:
244: + obj - object on which to get callback
245: . cbtype - callback type
246: - cid - address of callback Id
248: Output Arguments:
249: + func - Fortran function (or NULL if not needed)
250: - ctx - Fortran context (or NULL if not needed)
252: Level: developer
254: .seealso: PetscObjectSetFortranCallback()
255: @*/
256: PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx)
257: {
258: PetscFortranCallback *cb;
262: if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid");
263: 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");
264: cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK];
265: if (func) *func = cb->func;
266: if (ctx) *ctx = cb->ctx;
267: return(0);
268: }
270: #if defined(PETSC_USE_LOG)
273: /*@C
274: PetscObjectsDump - Prints the currently existing objects.
276: Logically Collective on PetscViewer
278: Input Parameter:
279: + fd - file pointer
280: - all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects
282: Options Database:
283: . -objects_dump <all>
285: Level: advanced
287: Concepts: options database^printing
289: @*/
290: PetscErrorCode PetscObjectsDump(FILE *fd,PetscBool all)
291: {
293: PetscInt i;
294: #if defined(PETSC_USE_DEBUG)
295: PetscInt j,k=0;
296: #endif
297: PetscObject h;
300: if (PetscObjectsCounts) {
301: PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");
302: PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");
303: for (i=0; i<PetscObjectsMaxCounts; i++) {
304: if ((h = PetscObjects[i])) {
305: PetscObjectName(h);
306: {
307: #if defined(PETSC_USE_DEBUG)
308: PetscStack *stack = 0;
309: char *create,*rclass;
311: /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */
312: PetscMallocGetStack(h,&stack);
313: if (stack) {
314: k = stack->currentsize-2;
315: if (!all) {
316: k = 0;
317: while (!stack->petscroutine[k]) k++;
318: PetscStrstr(stack->function[k],"Create",&create);
319: if (!create) {
320: PetscStrstr(stack->function[k],"Get",&create);
321: }
322: PetscStrstr(stack->function[k],h->class_name,&rclass);
323: if (!create) continue;
324: if (!rclass) continue;
325: }
326: }
327: #endif
329: PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);
331: #if defined(PETSC_USE_DEBUG)
332: PetscMallocGetStack(h,&stack);
333: if (stack) {
334: for (j=k; j>=0; j--) {
335: fprintf(fd," [%d] %s() in %s\n",PetscGlobalRank,stack->function[j],stack->file[j]);
336: }
337: }
338: #endif
339: }
340: }
341: }
342: }
343: return(0);
344: }
345: #endif
347: #if defined(PETSC_USE_LOG)
351: /*@C
352: PetscObjectsView - Prints the currently existing objects.
354: Logically Collective on PetscViewer
356: Input Parameter:
357: . viewer - must be an PETSCVIEWERASCII viewer
359: Level: advanced
361: Concepts: options database^printing
363: @*/
364: PetscErrorCode PetscObjectsView(PetscViewer viewer)
365: {
367: PetscBool isascii;
368: FILE *fd;
371: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
372: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
373: if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
374: PetscViewerASCIIGetPointer(viewer,&fd);
375: PetscObjectsDump(fd,PETSC_TRUE);
376: return(0);
377: }
381: /*@C
382: PetscObjectsGetObject - Get a pointer to a named object
384: Not collective
386: Input Parameter:
387: . name - the name of an object
389: Output Parameter:
390: . obj - the object or null if there is no object
392: Level: advanced
394: Concepts: options database^printing
396: @*/
397: PetscErrorCode PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
398: {
400: PetscInt i;
401: PetscObject h;
402: PetscBool flg;
405: *obj = NULL;
406: for (i=0; i<PetscObjectsMaxCounts; i++) {
407: if ((h = PetscObjects[i])) {
408: PetscObjectName(h);
409: PetscStrcmp(h->name,name,&flg);
410: if (flg) {
411: *obj = h;
412: if (classname) *classname = h->class_name;
413: return(0);
414: }
415: }
416: }
417: return(0);
418: }
419: #endif
423: /*@C
424: PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
426: Not Collective
428: Input Parameter:
429: + obj - the PETSc object
430: . handle - function that checks for options
431: . destroy - function to destroy context if provided
432: - ctx - optional context for check function
434: Level: developer
437: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()
439: @*/
440: PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscOptionItems*,PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
441: {
444: if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
445: obj->optionhandler[obj->noptionhandler] = handle;
446: obj->optiondestroy[obj->noptionhandler] = destroy;
447: obj->optionctx[obj->noptionhandler++] = ctx;
448: return(0);
449: }
453: /*@C
454: PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object
456: Not Collective
458: Input Parameter:
459: . obj - the PETSc object
461: Level: developer
464: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()
466: @*/
467: PetscErrorCode PetscObjectProcessOptionsHandlers(PetscOptionItems *PetscOptionsObject,PetscObject obj)
468: {
469: PetscInt i;
474: for (i=0; i<obj->noptionhandler; i++) {
475: (*obj->optionhandler[i])(PetscOptionsObject,obj,obj->optionctx[i]);
476: }
477: return(0);
478: }
482: /*@C
483: PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object
485: Not Collective
487: Input Parameter:
488: . obj - the PETSc object
490: Level: developer
493: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
495: @*/
496: PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj)
497: {
498: PetscInt i;
503: for (i=0; i<obj->noptionhandler; i++) {
504: if (obj->optiondestroy[i]) {
505: (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
506: }
507: }
508: obj->noptionhandler = 0;
509: return(0);
510: }
515: /*@
516: PetscObjectReference - Indicates to any PetscObject that it is being
517: referenced by another PetscObject. This increases the reference
518: count for that object by one.
520: Logically Collective on PetscObject
522: Input Parameter:
523: . obj - the PETSc object. This must be cast with (PetscObject), for example,
524: PetscObjectReference((PetscObject)mat);
526: Level: advanced
528: .seealso: PetscObjectCompose(), PetscObjectDereference()
529: @*/
530: PetscErrorCode PetscObjectReference(PetscObject obj)
531: {
533: if (!obj) return(0);
535: obj->refct++;
536: return(0);
537: }
541: /*@
542: PetscObjectGetReference - Gets the current reference count for
543: any PETSc object.
545: Not Collective
547: Input Parameter:
548: . obj - the PETSc object; this must be cast with (PetscObject), for example,
549: PetscObjectGetReference((PetscObject)mat,&cnt);
551: Output Parameter:
552: . cnt - the reference count
554: Level: advanced
556: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
557: @*/
558: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
559: {
563: *cnt = obj->refct;
564: return(0);
565: }
569: /*@
570: PetscObjectDereference - Indicates to any PetscObject that it is being
571: referenced by one less PetscObject. This decreases the reference
572: count for that object by one.
574: Collective on PetscObject if reference reaches 0 otherwise Logically Collective
576: Input Parameter:
577: . obj - the PETSc object; this must be cast with (PetscObject), for example,
578: PetscObjectDereference((PetscObject)mat);
580: Notes: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not.
582: Level: advanced
584: .seealso: PetscObjectCompose(), PetscObjectReference()
585: @*/
586: PetscErrorCode PetscObjectDereference(PetscObject obj)
587: {
591: if (!obj) return(0);
593: if (obj->bops->destroy) {
594: (*obj->bops->destroy)(&obj);
595: } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
596: return(0);
597: }
599: /* ----------------------------------------------------------------------- */
600: /*
601: The following routines are the versions private to the PETSc object
602: data structures.
603: */
606: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
607: {
610: *comm = obj->comm;
611: return(0);
612: }
616: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
617: {
622: PetscObjectListRemoveReference(&obj->olist,name);
623: return(0);
624: }
628: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
629: {
631: char *tname;
632: PetscBool skipreference;
635: if (ptr) {
636: PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
637: if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
638: }
639: PetscObjectListAdd(&obj->olist,name,ptr);
640: return(0);
641: }
645: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
646: {
651: PetscObjectListFind(obj->olist,name,ptr);
652: return(0);
653: }
657: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
658: {
663: PetscFunctionListAdd(&obj->qlist,name,ptr);
664: return(0);
665: }
669: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
670: {
675: PetscFunctionListFind(obj->qlist,name,ptr);
676: return(0);
677: }
681: /*@C
682: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
684: Not Collective
686: Input Parameters:
687: + obj - the PETSc object; this must be cast with (PetscObject), for example,
688: PetscObjectCompose((PetscObject)mat,...);
689: . name - name associated with the child object
690: - ptr - the other PETSc object to associate with the PETSc object; this must also be
691: cast with (PetscObject)
693: Level: advanced
695: Notes:
696: The second objects reference count is automatically increased by one when it is
697: composed.
699: Replaces any previous object that had the same name.
701: If ptr is null and name has previously been composed using an object, then that
702: entry is removed from the obj.
704: PetscObjectCompose() can be used with any PETSc object (such as
705: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
706: PetscContainerCreate() for info on how to create an object from a
707: user-provided pointer that may then be composed with PETSc objects.
709: Concepts: objects^composing
710: Concepts: composing objects
712: .seealso: PetscObjectQuery(), PetscContainerCreate()
713: @*/
714: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
715: {
722: (*obj->bops->compose)(obj,name,ptr);
723: return(0);
724: }
728: /*@C
729: PetscObjectSetPrecision - sets the precision used within a given object.
731: Collective on the PetscObject
733: Input Parameters:
734: + obj - the PETSc object; this must be cast with (PetscObject), for example,
735: PetscObjectCompose((PetscObject)mat,...);
736: - precision - the precision
738: Level: advanced
740: .seealso: PetscObjectQuery(), PetscContainerCreate()
741: @*/
742: PetscErrorCode PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
743: {
746: obj->precision = precision;
747: return(0);
748: }
752: /*@C
753: PetscObjectQuery - Gets a PETSc object associated with a given object.
755: Not Collective
757: Input Parameters:
758: + obj - the PETSc object
759: Thus must be cast with a (PetscObject), for example,
760: PetscObjectCompose((PetscObject)mat,...);
761: . name - name associated with child object
762: - ptr - the other PETSc object associated with the PETSc object, this must be
763: cast with (PetscObject*)
765: Level: advanced
767: The reference count of neither object is increased in this call
769: Concepts: objects^composing
770: Concepts: composing objects
771: Concepts: objects^querying
772: Concepts: querying objects
774: .seealso: PetscObjectCompose()
775: @*/
776: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
777: {
784: (*obj->bops->query)(obj,name,ptr);
785: return(0);
786: }
788: /*MC
789: PetscObjectComposeFunction - Associates a function with a given PETSc object.
791: Synopsis:
792: #include <petscsys.h>
793: PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))
795: Logically Collective on PetscObject
797: Input Parameters:
798: + obj - the PETSc object; this must be cast with a (PetscObject), for example,
799: PetscObjectCompose((PetscObject)mat,...);
800: . name - name associated with the child function
801: . fname - name of the function
802: - fptr - function pointer
804: Level: advanced
806: Notes:
807: To remove a registered routine, pass in NULL for fptr().
809: PetscObjectComposeFunction() can be used with any PETSc object (such as
810: Mat, Vec, KSP, SNES, etc.) or any user-provided object.
812: Concepts: objects^composing functions
813: Concepts: composing functions
814: Concepts: functions^querying
815: Concepts: objects^querying
816: Concepts: querying objects
818: .seealso: PetscObjectQueryFunction(), PetscContainerCreate()
819: M*/
823: PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
824: {
830: (*obj->bops->composefunction)(obj,name,fptr);
831: return(0);
832: }
834: /*MC
835: PetscObjectQueryFunction - Gets a function associated with a given object.
837: Synopsis:
838: #include <petscsys.h>
839: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))
841: Logically Collective on PetscObject
843: Input Parameters:
844: + obj - the PETSc object; this must be cast with (PetscObject), for example,
845: PetscObjectQueryFunction((PetscObject)ksp,...);
846: - name - name associated with the child function
848: Output Parameter:
849: . fptr - function pointer
851: Level: advanced
853: Concepts: objects^composing functions
854: Concepts: composing functions
855: Concepts: functions^querying
856: Concepts: objects^querying
857: Concepts: querying objects
859: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind()
860: M*/
863: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
864: {
870: (*obj->bops->queryfunction)(obj,name,ptr);
871: return(0);
872: }
874: struct _p_PetscContainer {
875: PETSCHEADER(int);
876: void *ptr;
877: PetscErrorCode (*userdestroy)(void*);
878: };
882: /*@C
883: PetscContainerGetPointer - Gets the pointer value contained in the container.
885: Not Collective
887: Input Parameter:
888: . obj - the object created with PetscContainerCreate()
890: Output Parameter:
891: . ptr - the pointer value
893: Level: advanced
895: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
896: PetscContainerSetPointer()
897: @*/
898: PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr)
899: {
903: *ptr = obj->ptr;
904: return(0);
905: }
910: /*@C
911: PetscContainerSetPointer - Sets the pointer value contained in the container.
913: Logically Collective on PetscContainer
915: Input Parameters:
916: + obj - the object created with PetscContainerCreate()
917: - ptr - the pointer value
919: Level: advanced
921: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
922: PetscContainerGetPointer()
923: @*/
924: PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr)
925: {
929: obj->ptr = ptr;
930: return(0);
931: }
935: /*@C
936: PetscContainerDestroy - Destroys a PETSc container object.
938: Collective on PetscContainer
940: Input Parameter:
941: . obj - an object that was created with PetscContainerCreate()
943: Level: advanced
945: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
946: @*/
947: PetscErrorCode PetscContainerDestroy(PetscContainer *obj)
948: {
952: if (!*obj) return(0);
954: if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; return(0);}
955: if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
956: PetscHeaderDestroy(obj);
957: return(0);
958: }
962: /*@C
963: PetscContainerSetUserDestroy - Sets name of the user destroy function.
965: Logically Collective on PetscContainer
967: Input Parameter:
968: + obj - an object that was created with PetscContainerCreate()
969: - des - name of the user destroy function
971: Level: advanced
973: .seealso: PetscContainerDestroy()
974: @*/
975: PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
976: {
979: obj->userdestroy = des;
980: return(0);
981: }
983: PetscClassId PETSC_CONTAINER_CLASSID;
987: /*@C
988: PetscContainerCreate - Creates a PETSc object that has room to hold
989: a single pointer. This allows one to attach any type of data (accessible
990: through a pointer) with the PetscObjectCompose() function to a PetscObject.
991: The data item itself is attached by a call to PetscContainerSetPointer().
993: Collective on MPI_Comm
995: Input Parameters:
996: . comm - MPI communicator that shares the object
998: Output Parameters:
999: . container - the container created
1001: Level: advanced
1003: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
1004: @*/
1005: PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
1006: {
1008: PetscContainer contain;
1012: PetscSysInitializePackage();
1013: PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);
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: }