Actual source code: inherit.c
1: /*
2: Provides utility routines for manipulating any type of PETSc object.
3: */
4: #include <petsc/private/petscimpl.h>
5: #include <petscviewer.h>
7: #if defined(PETSC_USE_LOG)
8: PETSC_INTERN PetscObject *PetscObjects;
9: PETSC_INTERN PetscInt PetscObjectsCounts;
10: PETSC_INTERN PetscInt PetscObjectsMaxCounts;
11: PETSC_INTERN PetscBool PetscObjectsLog;
12: #endif
14: #if defined(PETSC_USE_LOG)
15: PetscObject *PetscObjects = NULL;
16: PetscInt PetscObjectsCounts = 0, PetscObjectsMaxCounts = 0;
17: PetscBool PetscObjectsLog = PETSC_FALSE;
18: #endif
20: PETSC_EXTERN PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm*);
21: PETSC_EXTERN PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject);
22: PETSC_EXTERN PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject*);
23: PETSC_EXTERN PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],void (*)(void));
24: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void));
26: /*
27: PetscHeaderCreate_Private - Creates a base PETSc object header and fills
28: in the default values. Called by the macro PetscHeaderCreate().
29: */
30: PetscErrorCode PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,const char class_name[],const char descr[],const char mansec[],
31: MPI_Comm comm,PetscObjectDestroyFunction destroy,PetscObjectViewFunction view)
32: {
33: static PetscInt idcnt = 1;
34: #if defined(PETSC_USE_LOG)
35: PetscObject *newPetscObjects;
36: PetscInt newPetscObjectsMaxCounts,i;
37: #endif
39: h->classid = classid;
40: h->type = 0;
41: h->class_name = (char*)class_name;
42: h->description = (char*)descr;
43: h->mansec = (char*)mansec;
44: h->prefix = NULL;
45: h->refct = 1;
46: #if defined(PETSC_HAVE_SAWS)
47: h->amsmem = PETSC_FALSE;
48: #endif
49: h->id = idcnt++;
50: h->parentid = 0;
51: h->qlist = NULL;
52: h->olist = NULL;
53: h->bops->destroy = destroy;
54: h->bops->view = view;
55: h->bops->getcomm = PetscObjectGetComm_Petsc;
56: h->bops->compose = PetscObjectCompose_Petsc;
57: h->bops->query = PetscObjectQuery_Petsc;
58: h->bops->composefunction = PetscObjectComposeFunction_Petsc;
59: h->bops->queryfunction = PetscObjectQueryFunction_Petsc;
61: PetscCommDuplicate(comm,&h->comm,&h->tag);
63: #if defined(PETSC_USE_LOG)
64: /* Keep a record of object created */
65: if (PetscObjectsLog) {
66: PetscObjectsCounts++;
67: for (i=0; i<PetscObjectsMaxCounts; i++) {
68: if (!PetscObjects[i]) {
69: PetscObjects[i] = h;
70: return 0;
71: }
72: }
73: /* Need to increase the space for storing PETSc objects */
74: if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100;
75: else newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts;
76: PetscCalloc1(newPetscObjectsMaxCounts,&newPetscObjects);
77: PetscArraycpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts);
78: PetscFree(PetscObjects);
80: PetscObjects = newPetscObjects;
81: PetscObjects[PetscObjectsMaxCounts] = h;
82: PetscObjectsMaxCounts = newPetscObjectsMaxCounts;
83: }
84: #endif
85: return 0;
86: }
88: PETSC_INTERN PetscBool PetscMemoryCollectMaximumUsage;
89: PETSC_INTERN PetscLogDouble PetscMemoryMaximumUsage;
91: /*
92: PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
93: the macro PetscHeaderDestroy().
94: */
95: PetscErrorCode PetscHeaderDestroy_Private(PetscObject h)
96: {
98: PetscLogObjectDestroy(h);
99: PetscComposedQuantitiesDestroy(h);
100: if (PetscMemoryCollectMaximumUsage) {
101: PetscLogDouble usage;
102: PetscMemoryGetCurrentUsage(&usage);
103: if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
104: }
105: /* first destroy things that could execute arbitrary code */
106: if (h->python_destroy) {
107: void *python_context = h->python_context;
108: PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
109: h->python_context = NULL;
110: h->python_destroy = NULL;
112: (*python_destroy)(python_context);
113: }
114: PetscObjectDestroyOptionsHandlers(h);
115: PetscObjectListDestroy(&h->olist);
116: PetscCommDestroy(&h->comm);
117: /* next destroy other things */
118: h->classid = PETSCFREEDHEADER;
120: PetscFunctionListDestroy(&h->qlist);
121: PetscFree(h->type_name);
122: PetscFree(h->name);
123: PetscFree(h->prefix);
124: PetscFree(h->fortran_func_pointers);
125: PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_CLASS]);
126: PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
128: #if defined(PETSC_USE_LOG)
129: if (PetscObjectsLog) {
130: PetscInt i;
131: /* Record object removal from list of all objects */
132: for (i=0; i<PetscObjectsMaxCounts; i++) {
133: if (PetscObjects[i] == h) {
134: PetscObjects[i] = NULL;
135: PetscObjectsCounts--;
136: break;
137: }
138: }
139: if (!PetscObjectsCounts) {
140: PetscFree(PetscObjects);
141: PetscObjectsMaxCounts = 0;
142: }
143: }
144: #endif
145: return 0;
146: }
148: /*@C
149: PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object
151: Logically Collective on PetscObject
153: Input Parameters:
154: + src - source object
155: - dest - destination object
157: Level: developer
159: Note:
160: Both objects must have the same class.
161: @*/
162: PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest)
163: {
164: PetscFortranCallbackId cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE];
170: PetscFree(dest->fortran_func_pointers);
171: PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);
172: PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));
174: dest->num_fortran_func_pointers = src->num_fortran_func_pointers;
176: PetscFortranCallbackGetSizes(src->classid,&numcb[PETSC_FORTRAN_CALLBACK_CLASS],&numcb[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
177: for (cbtype=PETSC_FORTRAN_CALLBACK_CLASS; cbtype<PETSC_FORTRAN_CALLBACK_MAXTYPE; cbtype++) {
178: PetscFree(dest->fortrancallback[cbtype]);
179: PetscCalloc1(numcb[cbtype],&dest->fortrancallback[cbtype]);
180: PetscMemcpy(dest->fortrancallback[cbtype],src->fortrancallback[cbtype],src->num_fortrancallback[cbtype]*sizeof(PetscFortranCallback));
181: dest->num_fortrancallback[cbtype] = src->num_fortrancallback[cbtype];
182: }
183: return 0;
184: }
186: /*@C
187: PetscObjectSetFortranCallback - set fortran callback function pointer and context
189: Logically Collective
191: Input Parameters:
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: {
204: const char *subtype = NULL;
207: if (cbtype == PETSC_FORTRAN_CALLBACK_SUBTYPE) subtype = obj->type_name;
208: if (!*cid) PetscFortranCallbackRegister(obj->classid,subtype,cid);
209: if (*cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype]) {
210: PetscFortranCallbackId oldnum = obj->num_fortrancallback[cbtype];
211: PetscFortranCallbackId newnum = PetscMax(*cid - PETSC_SMALLEST_FORTRAN_CALLBACK + 1, 2*oldnum);
212: PetscFortranCallback *callback;
213: PetscMalloc1(newnum,&callback);
214: PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));
215: PetscFree(obj->fortrancallback[cbtype]);
217: obj->fortrancallback[cbtype] = callback;
218: obj->num_fortrancallback[cbtype] = newnum;
219: }
220: obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func;
221: obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx;
222: return 0;
223: }
225: /*@C
226: PetscObjectGetFortranCallback - get fortran callback function pointer and context
228: Logically Collective
230: Input Parameters:
231: + obj - object on which to get callback
232: . cbtype - callback type
233: - cid - address of callback Id
235: Output Parameters:
236: + func - Fortran function (or NULL if not needed)
237: - ctx - Fortran context (or NULL if not needed)
239: Level: developer
241: .seealso: PetscObjectSetFortranCallback()
242: @*/
243: PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx)
244: {
245: PetscFortranCallback *cb;
250: cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK];
251: if (func) *func = cb->func;
252: if (ctx) *ctx = cb->ctx;
253: return 0;
254: }
256: #if defined(PETSC_USE_LOG)
257: /*@C
258: PetscObjectsDump - Prints the currently existing objects.
260: Logically Collective on PetscViewer
262: Input Parameters:
263: + fd - file pointer
264: - all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects
266: Options Database:
267: . -objects_dump <all> - print information about all the objects that exist at the end of the programs run
269: Level: advanced
271: @*/
272: PetscErrorCode PetscObjectsDump(FILE *fd,PetscBool all)
273: {
274: PetscInt i;
275: #if defined(PETSC_USE_DEBUG)
276: PetscInt j,k=0;
277: #endif
278: PetscObject h;
280: if (PetscObjectsCounts) {
281: PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");
282: PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");
283: for (i=0; i<PetscObjectsMaxCounts; i++) {
284: if ((h = PetscObjects[i])) {
285: PetscObjectName(h);
286: {
287: #if defined(PETSC_USE_DEBUG)
288: PetscStack *stack = NULL;
289: char *create,*rclass;
291: /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */
292: PetscMallocGetStack(h,&stack);
293: if (stack) {
294: k = stack->currentsize-2;
295: if (!all) {
296: k = 0;
297: while (!stack->petscroutine[k]) k++;
298: PetscStrstr(stack->function[k],"Create",&create);
299: if (!create) {
300: PetscStrstr(stack->function[k],"Get",&create);
301: }
302: PetscStrstr(stack->function[k],h->class_name,&rclass);
303: if (!create) continue;
304: if (!rclass) continue;
305: }
306: }
307: #endif
309: PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);
311: #if defined(PETSC_USE_DEBUG)
312: PetscMallocGetStack(h,&stack);
313: if (stack) {
314: for (j=k; j>=0; j--) {
315: fprintf(fd," [%d] %s() in %s\n",PetscGlobalRank,stack->function[j],stack->file[j]);
316: }
317: }
318: #endif
319: }
320: }
321: }
322: }
323: return 0;
324: }
325: #endif
327: #if defined(PETSC_USE_LOG)
329: /*@C
330: PetscObjectsView - Prints the currently existing objects.
332: Logically Collective on PetscViewer
334: Input Parameter:
335: . viewer - must be an PETSCVIEWERASCII viewer
337: Level: advanced
339: @*/
340: PetscErrorCode PetscObjectsView(PetscViewer viewer)
341: {
342: PetscBool isascii;
343: FILE *fd;
345: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
346: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
348: PetscViewerASCIIGetPointer(viewer,&fd);
349: PetscObjectsDump(fd,PETSC_TRUE);
350: return 0;
351: }
353: /*@C
354: PetscObjectsGetObject - Get a pointer to a named object
356: Not collective
358: Input Parameter:
359: . name - the name of an object
361: Output Parameters:
362: + obj - the object or null if there is no object
363: - classname - the name of the class
365: Level: advanced
367: @*/
368: PetscErrorCode PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
369: {
370: PetscInt i;
371: PetscObject h;
372: PetscBool flg;
376: *obj = NULL;
377: for (i=0; i<PetscObjectsMaxCounts; i++) {
378: if ((h = PetscObjects[i])) {
379: PetscObjectName(h);
380: PetscStrcmp(h->name,name,&flg);
381: if (flg) {
382: *obj = h;
383: if (classname) *classname = h->class_name;
384: return 0;
385: }
386: }
387: }
388: return 0;
389: }
390: #endif
392: /*@
393: PetscObjectSetPrintedOptions - indicate to an object that it should behave as if it has already printed the help for its options
395: Input Parameters:
396: . obj - the PetscObject
398: Level: developer
400: Developer Notes:
401: This is used, for example to prevent sequential objects that are created from a parallel object; such as the KSP created by
402: PCBJACOBI from all printing the same help messages to the screen
404: .seealso: PetscOptionsInsert()
405: @*/
406: PetscErrorCode PetscObjectSetPrintedOptions(PetscObject obj)
407: {
409: obj->optionsprinted = PETSC_TRUE;
410: return 0;
411: }
413: /*@
414: PetscObjectInheritPrintedOptions - If the child object is not on the rank 0 process of the parent object and the child is sequential then the child gets it set.
416: Input Parameters:
417: + pobj - the parent object
418: - obj - the PetscObject
420: Level: developer
422: Developer Notes:
423: This is used, for example to prevent sequential objects that are created from a parallel object; such as the KSP created by
424: PCBJACOBI from all printing the same help messages to the screen
426: This will not handle more complicated situations like with GASM where children may live on any subset of the parent's processes and overlap
428: .seealso: PetscOptionsInsert(), PetscObjectSetPrintedOptions()
429: @*/
430: PetscErrorCode PetscObjectInheritPrintedOptions(PetscObject pobj,PetscObject obj)
431: {
432: PetscMPIInt prank,size;
436: MPI_Comm_rank(pobj->comm,&prank);
437: MPI_Comm_size(obj->comm,&size);
438: if (size == 1 && prank > 0) obj->optionsprinted = PETSC_TRUE;
439: return 0;
440: }
442: /*@C
443: PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
445: Not Collective
447: Input Parameters:
448: + obj - the PETSc object
449: . handle - function that checks for options
450: . destroy - function to destroy context if provided
451: - ctx - optional context for check function
453: Level: developer
455: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()
457: @*/
458: PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscOptionItems*,PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
459: {
462: obj->optionhandler[obj->noptionhandler] = handle;
463: obj->optiondestroy[obj->noptionhandler] = destroy;
464: obj->optionctx[obj->noptionhandler++] = ctx;
465: return 0;
466: }
468: /*@C
469: PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object
471: Not Collective
473: Input Parameter:
474: . obj - the PETSc object
476: Level: developer
478: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()
480: @*/
481: PetscErrorCode PetscObjectProcessOptionsHandlers(PetscOptionItems *PetscOptionsObject,PetscObject obj)
482: {
484: for (PetscInt i=0; i<obj->noptionhandler; i++) (*obj->optionhandler[i])(PetscOptionsObject,obj,obj->optionctx[i]);
485: return 0;
486: }
488: /*@C
489: PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object
491: Not Collective
493: Input Parameter:
494: . obj - the PETSc object
496: Level: developer
498: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
500: @*/
501: PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj)
502: {
504: for (PetscInt i=0; i<obj->noptionhandler; i++) {
505: if (obj->optiondestroy[i]) (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
506: }
507: obj->noptionhandler = 0;
508: return 0;
509: }
511: /*@C
512: PetscObjectReference - Indicates to any PetscObject that it is being
513: referenced by another PetscObject. This increases the reference
514: count for that object by one.
516: Logically Collective on PetscObject
518: Input Parameter:
519: . obj - the PETSc object. This must be cast with (PetscObject), for example,
520: PetscObjectReference((PetscObject)mat);
522: Level: advanced
524: .seealso: PetscObjectCompose(), PetscObjectDereference()
525: @*/
526: PetscErrorCode PetscObjectReference(PetscObject obj)
527: {
528: if (!obj) return 0;
530: obj->refct++;
531: return 0;
532: }
534: /*@C
535: PetscObjectGetReference - Gets the current reference count for
536: any PETSc object.
538: Not Collective
540: Input Parameter:
541: . obj - the PETSc object; this must be cast with (PetscObject), for example,
542: PetscObjectGetReference((PetscObject)mat,&cnt);
544: Output Parameter:
545: . cnt - the reference count
547: Level: advanced
549: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
550: @*/
551: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
552: {
555: *cnt = obj->refct;
556: return 0;
557: }
559: /*@C
560: PetscObjectDereference - Indicates to any PetscObject that it is being
561: referenced by one less PetscObject. This decreases the reference
562: count for that object by one.
564: Collective on PetscObject if reference reaches 0 otherwise Logically Collective
566: Input Parameter:
567: . obj - the PETSc object; this must be cast with (PetscObject), for example,
568: PetscObjectDereference((PetscObject)mat);
570: Notes:
571: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not.
573: Level: advanced
575: .seealso: PetscObjectCompose(), PetscObjectReference()
576: @*/
577: PetscErrorCode PetscObjectDereference(PetscObject obj)
578: {
579: if (!obj) return 0;
581: if (obj->bops->destroy) (*obj->bops->destroy)(&obj);
583: return 0;
584: }
586: /* ----------------------------------------------------------------------- */
587: /*
588: The following routines are the versions private to the PETSc object
589: data structures.
590: */
591: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
592: {
595: *comm = obj->comm;
596: return 0;
597: }
599: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
600: {
602: PetscObjectListRemoveReference(&obj->olist,name);
603: return 0;
604: }
606: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
607: {
608: if (ptr) {
609: char *tname;
610: PetscBool skipreference;
612: PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
614: }
615: PetscObjectListAdd(&obj->olist,name,ptr);
616: return 0;
617: }
619: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
620: {
622: PetscObjectListFind(obj->olist,name,ptr);
623: return 0;
624: }
626: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
627: {
629: PetscFunctionListAdd(&obj->qlist,name,ptr);
630: return 0;
631: }
633: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
634: {
636: PetscFunctionListFind(obj->qlist,name,ptr);
637: return 0;
638: }
640: /*@C
641: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
643: Not Collective
645: Input Parameters:
646: + obj - the PETSc object; this must be cast with (PetscObject), for example,
647: PetscObjectCompose((PetscObject)mat,...);
648: . name - name associated with the child object
649: - ptr - the other PETSc object to associate with the PETSc object; this must also be
650: cast with (PetscObject)
652: Level: advanced
654: Notes:
655: The second objects reference count is automatically increased by one when it is
656: composed.
658: Replaces any previous object that had the same name.
660: If ptr is null and name has previously been composed using an object, then that
661: entry is removed from the obj.
663: PetscObjectCompose() can be used with any PETSc object (such as
664: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
665: PetscContainerCreate() for info on how to create an object from a
666: user-provided pointer that may then be composed with PETSc objects.
668: .seealso: PetscObjectQuery(), PetscContainerCreate(), PetscObjectComposeFunction(), PetscObjectQueryFunction()
669: @*/
670: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
671: {
676: (*obj->bops->compose)(obj,name,ptr);
677: return 0;
678: }
680: /*@C
681: PetscObjectQuery - Gets a PETSc object associated with a given object.
683: Not Collective
685: Input Parameters:
686: + obj - the PETSc object
687: Thus must be cast with a (PetscObject), for example,
688: PetscObjectCompose((PetscObject)mat,...);
689: . name - name associated with child object
690: - ptr - the other PETSc object associated with the PETSc object, this must be
691: cast with (PetscObject*)
693: Level: advanced
695: The reference count of neither object is increased in this call
697: .seealso: PetscObjectCompose(), PetscObjectComposeFunction(), PetscObjectQueryFunction()
698: @*/
699: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
700: {
704: (*obj->bops->query)(obj,name,ptr);
705: return 0;
706: }
708: /*MC
709: PetscObjectComposeFunction - Associates a function with a given PETSc object.
711: Synopsis:
712: #include <petscsys.h>
713: PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))
715: Logically Collective on PetscObject
717: Input Parameters:
718: + obj - the PETSc object; this must be cast with a (PetscObject), for example,
719: PetscObjectCompose((PetscObject)mat,...);
720: . name - name associated with the child function
721: . fname - name of the function
722: - fptr - function pointer
724: Level: advanced
726: Notes:
727: To remove a registered routine, pass in NULL for fptr().
729: PetscObjectComposeFunction() can be used with any PETSc object (such as
730: Mat, Vec, KSP, SNES, etc.) or any user-provided object.
732: .seealso: PetscObjectQueryFunction(), PetscContainerCreate() PetscObjectCompose(), PetscObjectQuery()
733: M*/
735: PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
736: {
739: (*obj->bops->composefunction)(obj,name,fptr);
740: return 0;
741: }
743: /*MC
744: PetscObjectQueryFunction - Gets a function associated with a given object.
746: Synopsis:
747: #include <petscsys.h>
748: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))
750: Logically Collective on PetscObject
752: Input Parameters:
753: + obj - the PETSc object; this must be cast with (PetscObject), for example,
754: PetscObjectQueryFunction((PetscObject)ksp,...);
755: - name - name associated with the child function
757: Output Parameter:
758: . fptr - function pointer
760: Level: advanced
762: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind(), PetscObjectCompose(), PetscObjectQuery()
763: M*/
764: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
765: {
768: (*obj->bops->queryfunction)(obj,name,ptr);
769: return 0;
770: }
772: struct _p_PetscContainer {
773: PETSCHEADER(int);
774: void *ptr;
775: PetscErrorCode (*userdestroy)(void*);
776: };
778: /*@C
779: PetscContainerUserDestroyDefault - Default destroy routine for user-provided data that simply calls PetscFree().
781: Logically Collective on PetscContainer
783: Input Parameter:
784: . ctx - pointer to user-provided data
786: Level: advanced
788: .seealso: PetscContainerDestroy(), PetscContainerSetUserDestroy()
789: @*/
790: PetscErrorCode PetscContainerUserDestroyDefault(void* ctx)
791: {
792: PetscFree(ctx);
793: return 0;
794: }
796: /*@C
797: PetscContainerGetPointer - Gets the pointer value contained in the container.
799: Not Collective
801: Input Parameter:
802: . obj - the object created with PetscContainerCreate()
804: Output Parameter:
805: . ptr - the pointer value
807: Level: advanced
809: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
810: PetscContainerSetPointer()
811: @*/
812: PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr)
813: {
816: *ptr = obj->ptr;
817: return 0;
818: }
820: /*@C
821: PetscContainerSetPointer - Sets the pointer value contained in the container.
823: Logically Collective on PetscContainer
825: Input Parameters:
826: + obj - the object created with PetscContainerCreate()
827: - ptr - the pointer value
829: Level: advanced
831: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
832: PetscContainerGetPointer()
833: @*/
834: PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr)
835: {
838: obj->ptr = ptr;
839: return 0;
840: }
842: /*@C
843: PetscContainerDestroy - Destroys a PETSc container object.
845: Collective on PetscContainer
847: Input Parameter:
848: . obj - an object that was created with PetscContainerCreate()
850: Level: advanced
852: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
853: @*/
854: PetscErrorCode PetscContainerDestroy(PetscContainer *obj)
855: {
856: if (!*obj) return 0;
858: if (--((PetscObject)(*obj))->refct > 0) {*obj = NULL; return 0;}
859: if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
860: PetscHeaderDestroy(obj);
861: return 0;
862: }
864: /*@C
865: PetscContainerSetUserDestroy - Sets name of the user destroy function.
867: Logically Collective on PetscContainer
869: Input Parameters:
870: + obj - an object that was created with PetscContainerCreate()
871: - des - name of the user destroy function
873: Notes:
874: Use PetscContainerUserDestroyDefault() if the memory was obtained by calling PetscMalloc or one of its variants for single memory allocation.
876: Level: advanced
878: .seealso: PetscContainerDestroy(), PetscContainerUserDestroyDefault(), PetscMalloc(), PetscMalloc1(), PetscCalloc(), PetscCalloc1()
879: @*/
880: PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
881: {
883: obj->userdestroy = des;
884: return 0;
885: }
887: PetscClassId PETSC_CONTAINER_CLASSID;
889: /*@C
890: PetscContainerCreate - Creates a PETSc object that has room to hold
891: a single pointer. This allows one to attach any type of data (accessible
892: through a pointer) with the PetscObjectCompose() function to a PetscObject.
893: The data item itself is attached by a call to PetscContainerSetPointer().
895: Collective
897: Input Parameters:
898: . comm - MPI communicator that shares the object
900: Output Parameters:
901: . container - the container created
903: Level: advanced
905: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer(), PetscObjectCompose(), PetscObjectQuery()
906: @*/
907: PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
908: {
910: PetscSysInitializePackage();
911: PetscHeaderCreate(*container,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);
912: return 0;
913: }
915: /*@
916: PetscObjectSetFromOptions - Sets generic parameters from user options.
918: Collective on obj
920: Input Parameter:
921: . obj - the PetscObjcet
923: Options Database Keys:
925: Notes:
926: We have no generic options at present, so this does nothing
928: Level: beginner
930: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
931: @*/
932: PetscErrorCode PetscObjectSetFromOptions(PetscObject obj)
933: {
935: return 0;
936: }
938: /*@
939: PetscObjectSetUp - Sets up the internal data structures for the later use.
941: Collective on PetscObject
943: Input Parameters:
944: . obj - the PetscObject
946: Notes:
947: This does nothing at present.
949: Level: advanced
951: .seealso: PetscObjectDestroy()
952: @*/
953: PetscErrorCode PetscObjectSetUp(PetscObject obj)
954: {
956: return 0;
957: }