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: PetscErrorCode ierr;
35: #if defined(PETSC_USE_LOG)
36: PetscObject *newPetscObjects;
37: PetscInt newPetscObjectsMaxCounts,i;
38: #endif
41: h->classid = classid;
42: h->type = 0;
43: h->class_name = (char*)class_name;
44: h->description = (char*)descr;
45: h->mansec = (char*)mansec;
46: h->prefix = NULL;
47: h->refct = 1;
48: #if defined(PETSC_HAVE_SAWS)
49: h->amsmem = PETSC_FALSE;
50: #endif
51: h->id = idcnt++;
52: h->parentid = 0;
53: h->qlist = NULL;
54: h->olist = NULL;
55: h->bops->destroy = destroy;
56: h->bops->view = view;
57: h->bops->getcomm = PetscObjectGetComm_Petsc;
58: h->bops->compose = PetscObjectCompose_Petsc;
59: h->bops->query = PetscObjectQuery_Petsc;
60: h->bops->composefunction = PetscObjectComposeFunction_Petsc;
61: h->bops->queryfunction = PetscObjectQueryFunction_Petsc;
63: PetscCommDuplicate(comm,&h->comm,&h->tag);
65: #if defined(PETSC_USE_LOG)
66: /* Keep a record of object created */
67: if (PetscObjectsLog) {
68: PetscObjectsCounts++;
69: for (i=0; i<PetscObjectsMaxCounts; i++) {
70: if (!PetscObjects[i]) {
71: PetscObjects[i] = h;
72: return(0);
73: }
74: }
75: /* Need to increase the space for storing PETSc objects */
76: if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100;
77: else newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts;
78: PetscCalloc1(newPetscObjectsMaxCounts,&newPetscObjects);
79: PetscArraycpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts);
80: PetscFree(PetscObjects);
82: PetscObjects = newPetscObjects;
83: PetscObjects[PetscObjectsMaxCounts] = h;
84: PetscObjectsMaxCounts = newPetscObjectsMaxCounts;
85: }
86: #endif
87: return(0);
88: }
90: PETSC_INTERN PetscBool PetscMemoryCollectMaximumUsage;
91: PETSC_INTERN 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 = NULL;
115: h->python_destroy = NULL;
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] = NULL;
140: PetscObjectsCounts--;
141: break;
142: }
143: }
144: if (!PetscObjectsCounts) {
145: PetscFree(PetscObjects);
146: PetscObjectsMaxCounts = 0;
147: }
148: }
149: #endif
150: return(0);
151: }
153: /*@C
154: PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object
156: Logically Collective on PetscObject
158: Input Parameters:
159: + src - source object
160: - dest - destination object
162: Level: developer
164: Note:
165: Both objects must have the same class.
166: @*/
167: PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest)
168: {
170: PetscInt cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE];
175: if (src->classid != dest->classid) SETERRQ(src->comm,PETSC_ERR_ARG_INCOMP,"Objects must be of the same class");
177: PetscFree(dest->fortran_func_pointers);
178: PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);
179: PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));
181: dest->num_fortran_func_pointers = src->num_fortran_func_pointers;
183: PetscFortranCallbackGetSizes(src->classid,&numcb[PETSC_FORTRAN_CALLBACK_CLASS],&numcb[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
184: for (cbtype=PETSC_FORTRAN_CALLBACK_CLASS; cbtype<PETSC_FORTRAN_CALLBACK_MAXTYPE; cbtype++) {
185: PetscFree(dest->fortrancallback[cbtype]);
186: PetscCalloc1(numcb[cbtype],&dest->fortrancallback[cbtype]);
187: PetscMemcpy(dest->fortrancallback[cbtype],src->fortrancallback[cbtype],src->num_fortrancallback[cbtype]*sizeof(PetscFortranCallback));
188: dest->num_fortrancallback[cbtype] = src->num_fortrancallback[cbtype];
189: }
190: return(0);
191: }
193: /*@C
194: PetscObjectSetFortranCallback - set fortran callback function pointer and context
196: Logically Collective
198: Input Parameters:
199: + obj - object on which to set callback
200: . cbtype - callback type (class or subtype)
201: . cid - address of callback Id, updated if not yet initialized (zero)
202: . func - Fortran function
203: - ctx - Fortran context
205: Level: developer
207: .seealso: PetscObjectGetFortranCallback()
208: @*/
209: PetscErrorCode PetscObjectSetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId *cid,void (*func)(void),void *ctx)
210: {
212: const char *subtype = NULL;
216: if (cbtype == PETSC_FORTRAN_CALLBACK_SUBTYPE) subtype = obj->type_name;
217: if (!*cid) {PetscFortranCallbackRegister(obj->classid,subtype,cid);}
218: if (*cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype]) {
219: PetscInt oldnum = obj->num_fortrancallback[cbtype],newnum = PetscMax(1,2*oldnum);
220: PetscFortranCallback *callback;
221: PetscMalloc1(newnum,&callback);
222: PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));
223: PetscFree(obj->fortrancallback[cbtype]);
225: obj->fortrancallback[cbtype] = callback;
226: obj->num_fortrancallback[cbtype] = newnum;
227: }
228: obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func;
229: obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx;
230: return(0);
231: }
233: /*@C
234: PetscObjectGetFortranCallback - get fortran callback function pointer and context
236: Logically Collective
238: Input Parameters:
239: + obj - object on which to get callback
240: . cbtype - callback type
241: - cid - address of callback Id
243: Output Parameters:
244: + func - Fortran function (or NULL if not needed)
245: - ctx - Fortran context (or NULL if not needed)
247: Level: developer
249: .seealso: PetscObjectSetFortranCallback()
250: @*/
251: PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx)
252: {
253: PetscFortranCallback *cb;
257: if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid");
258: 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");
259: cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK];
260: if (func) *func = cb->func;
261: if (ctx) *ctx = cb->ctx;
262: return(0);
263: }
265: #if defined(PETSC_USE_LOG)
266: /*@C
267: PetscObjectsDump - Prints the currently existing objects.
269: Logically Collective on PetscViewer
271: Input Parameters:
272: + fd - file pointer
273: - all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects
275: Options Database:
276: . -objects_dump <all> - print information about all the objects that exist at the end of the programs run
278: Level: advanced
280: @*/
281: PetscErrorCode PetscObjectsDump(FILE *fd,PetscBool all)
282: {
284: PetscInt i;
285: #if defined(PETSC_USE_DEBUG)
286: PetscInt j,k=0;
287: #endif
288: PetscObject h;
291: if (PetscObjectsCounts) {
292: PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");
293: PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");
294: for (i=0; i<PetscObjectsMaxCounts; i++) {
295: if ((h = PetscObjects[i])) {
296: PetscObjectName(h);
297: {
298: #if defined(PETSC_USE_DEBUG)
299: PetscStack *stack = NULL;
300: char *create,*rclass;
302: /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */
303: PetscMallocGetStack(h,&stack);
304: if (stack) {
305: k = stack->currentsize-2;
306: if (!all) {
307: k = 0;
308: while (!stack->petscroutine[k]) k++;
309: PetscStrstr(stack->function[k],"Create",&create);
310: if (!create) {
311: PetscStrstr(stack->function[k],"Get",&create);
312: }
313: PetscStrstr(stack->function[k],h->class_name,&rclass);
314: if (!create) continue;
315: if (!rclass) continue;
316: }
317: }
318: #endif
320: PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);
322: #if defined(PETSC_USE_DEBUG)
323: PetscMallocGetStack(h,&stack);
324: if (stack) {
325: for (j=k; j>=0; j--) {
326: fprintf(fd," [%d] %s() in %s\n",PetscGlobalRank,stack->function[j],stack->file[j]);
327: }
328: }
329: #endif
330: }
331: }
332: }
333: }
334: return(0);
335: }
336: #endif
338: #if defined(PETSC_USE_LOG)
340: /*@C
341: PetscObjectsView - Prints the currently existing objects.
343: Logically Collective on PetscViewer
345: Input Parameter:
346: . viewer - must be an PETSCVIEWERASCII viewer
348: Level: advanced
350: @*/
351: PetscErrorCode PetscObjectsView(PetscViewer viewer)
352: {
354: PetscBool isascii;
355: FILE *fd;
358: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
359: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
360: if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
361: PetscViewerASCIIGetPointer(viewer,&fd);
362: PetscObjectsDump(fd,PETSC_TRUE);
363: return(0);
364: }
366: /*@C
367: PetscObjectsGetObject - Get a pointer to a named object
369: Not collective
371: Input Parameter:
372: . name - the name of an object
374: Output Parameters:
375: + obj - the object or null if there is no object
376: - classname - the name of the class
378: Level: advanced
380: @*/
381: PetscErrorCode PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
382: {
384: PetscInt i;
385: PetscObject h;
386: PetscBool flg;
389: *obj = NULL;
390: for (i=0; i<PetscObjectsMaxCounts; i++) {
391: if ((h = PetscObjects[i])) {
392: PetscObjectName(h);
393: PetscStrcmp(h->name,name,&flg);
394: if (flg) {
395: *obj = h;
396: if (classname) *classname = h->class_name;
397: return(0);
398: }
399: }
400: }
401: return(0);
402: }
403: #endif
405: /*@
406: PetscObjectSetPrintedOptions - indicate to an object that it should behave as if it has already printed the help for its options
408: Input Parameters:
409: . obj - the PetscObject
411: Level: developer
413: Developer Notes:
414: This is used, for example to prevent sequential objects that are created from a parallel object; such as the KSP created by
415: PCBJACOBI from all printing the same help messages to the screen
417: .seealso: PetscOptionsInsert()
418: @*/
419: PetscErrorCode PetscObjectSetPrintedOptions(PetscObject obj)
420: {
422: obj->optionsprinted = PETSC_TRUE;
423: return(0);
424: }
426: /*@
427: 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.
429: Input Parameters:
430: + pobj - the parent object
431: - obj - the PetscObject
433: Level: developer
435: Developer Notes:
436: This is used, for example to prevent sequential objects that are created from a parallel object; such as the KSP created by
437: PCBJACOBI from all printing the same help messages to the screen
439: This will not handle more complicated situations like with GASM where children may live on any subset of the parent's processes and overlap
441: .seealso: PetscOptionsInsert(), PetscObjectSetPrintedOptions()
442: @*/
443: PetscErrorCode PetscObjectInheritPrintedOptions(PetscObject pobj,PetscObject obj)
444: {
446: PetscMPIInt prank,size;
449: MPI_Comm_rank(pobj->comm,&prank);
450: MPI_Comm_size(obj->comm,&size);
451: if (size == 1 && prank > 0) obj->optionsprinted = PETSC_TRUE;
452: return(0);
453: }
455: /*@C
456: PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
458: Not Collective
460: Input Parameters:
461: + obj - the PETSc object
462: . handle - function that checks for options
463: . destroy - function to destroy context if provided
464: - ctx - optional context for check function
466: Level: developer
468: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()
470: @*/
471: PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscOptionItems*,PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
472: {
475: if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
476: obj->optionhandler[obj->noptionhandler] = handle;
477: obj->optiondestroy[obj->noptionhandler] = destroy;
478: obj->optionctx[obj->noptionhandler++] = ctx;
479: return(0);
480: }
482: /*@C
483: PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object
485: Not Collective
487: Input Parameter:
488: . obj - the PETSc object
490: Level: developer
492: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()
494: @*/
495: PetscErrorCode PetscObjectProcessOptionsHandlers(PetscOptionItems *PetscOptionsObject,PetscObject obj)
496: {
497: PetscInt i;
502: for (i=0; i<obj->noptionhandler; i++) {
503: (*obj->optionhandler[i])(PetscOptionsObject,obj,obj->optionctx[i]);
504: }
505: return(0);
506: }
508: /*@C
509: PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object
511: Not Collective
513: Input Parameter:
514: . obj - the PETSc object
516: Level: developer
518: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
520: @*/
521: PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj)
522: {
523: PetscInt i;
528: for (i=0; i<obj->noptionhandler; i++) {
529: if (obj->optiondestroy[i]) {
530: (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
531: }
532: }
533: obj->noptionhandler = 0;
534: return(0);
535: }
537: /*@C
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: }
561: /*@C
562: PetscObjectGetReference - Gets the current reference count for
563: any PETSc object.
565: Not Collective
567: Input Parameter:
568: . obj - the PETSc object; this must be cast with (PetscObject), for example,
569: PetscObjectGetReference((PetscObject)mat,&cnt);
571: Output Parameter:
572: . cnt - the reference count
574: Level: advanced
576: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
577: @*/
578: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
579: {
583: *cnt = obj->refct;
584: return(0);
585: }
587: /*@C
588: PetscObjectDereference - Indicates to any PetscObject that it is being
589: referenced by one less PetscObject. This decreases the reference
590: count for that object by one.
592: Collective on PetscObject if reference reaches 0 otherwise Logically Collective
594: Input Parameter:
595: . obj - the PETSc object; this must be cast with (PetscObject), for example,
596: PetscObjectDereference((PetscObject)mat);
598: Notes:
599: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not.
601: Level: advanced
603: .seealso: PetscObjectCompose(), PetscObjectReference()
604: @*/
605: PetscErrorCode PetscObjectDereference(PetscObject obj)
606: {
610: if (!obj) return(0);
612: if (obj->bops->destroy) {
613: (*obj->bops->destroy)(&obj);
614: } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
615: return(0);
616: }
618: /* ----------------------------------------------------------------------- */
619: /*
620: The following routines are the versions private to the PETSc object
621: data structures.
622: */
623: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
624: {
627: *comm = obj->comm;
628: return(0);
629: }
631: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
632: {
637: PetscObjectListRemoveReference(&obj->olist,name);
638: return(0);
639: }
641: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
642: {
644: char *tname;
645: PetscBool skipreference;
648: if (ptr) {
649: PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
650: if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
651: }
652: PetscObjectListAdd(&obj->olist,name,ptr);
653: return(0);
654: }
656: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
657: {
662: PetscObjectListFind(obj->olist,name,ptr);
663: return(0);
664: }
666: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
667: {
672: PetscFunctionListAdd(&obj->qlist,name,ptr);
673: return(0);
674: }
676: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
677: {
682: PetscFunctionListFind(obj->qlist,name,ptr);
683: return(0);
684: }
686: /*@C
687: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
689: Not Collective
691: Input Parameters:
692: + obj - the PETSc object; this must be cast with (PetscObject), for example,
693: PetscObjectCompose((PetscObject)mat,...);
694: . name - name associated with the child object
695: - ptr - the other PETSc object to associate with the PETSc object; this must also be
696: cast with (PetscObject)
698: Level: advanced
700: Notes:
701: The second objects reference count is automatically increased by one when it is
702: composed.
704: Replaces any previous object that had the same name.
706: If ptr is null and name has previously been composed using an object, then that
707: entry is removed from the obj.
709: PetscObjectCompose() can be used with any PETSc object (such as
710: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
711: PetscContainerCreate() for info on how to create an object from a
712: user-provided pointer that may then be composed with PETSc objects.
714: .seealso: PetscObjectQuery(), PetscContainerCreate(), PetscObjectComposeFunction(), PetscObjectQueryFunction()
715: @*/
716: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
717: {
724: if (obj == ptr) SETERRQ(PetscObjectComm((PetscObject)obj),PETSC_ERR_SUP,"Cannot compose object with itself");
725: (*obj->bops->compose)(obj,name,ptr);
726: return(0);
727: }
729: /*@C
730: PetscObjectQuery - Gets a PETSc object associated with a given object.
732: Not Collective
734: Input Parameters:
735: + obj - the PETSc object
736: Thus must be cast with a (PetscObject), for example,
737: PetscObjectCompose((PetscObject)mat,...);
738: . name - name associated with child object
739: - ptr - the other PETSc object associated with the PETSc object, this must be
740: cast with (PetscObject*)
742: Level: advanced
744: The reference count of neither object is increased in this call
746: .seealso: PetscObjectCompose(), PetscObjectComposeFunction(), PetscObjectQueryFunction()
747: @*/
748: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
749: {
756: (*obj->bops->query)(obj,name,ptr);
757: return(0);
758: }
760: /*MC
761: PetscObjectComposeFunction - Associates a function with a given PETSc object.
763: Synopsis:
764: #include <petscsys.h>
765: PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))
767: Logically Collective on PetscObject
769: Input Parameters:
770: + obj - the PETSc object; this must be cast with a (PetscObject), for example,
771: PetscObjectCompose((PetscObject)mat,...);
772: . name - name associated with the child function
773: . fname - name of the function
774: - fptr - function pointer
776: Level: advanced
778: Notes:
779: To remove a registered routine, pass in NULL for fptr().
781: PetscObjectComposeFunction() can be used with any PETSc object (such as
782: Mat, Vec, KSP, SNES, etc.) or any user-provided object.
784: .seealso: PetscObjectQueryFunction(), PetscContainerCreate() PetscObjectCompose(), PetscObjectQuery()
785: M*/
787: PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
788: {
794: (*obj->bops->composefunction)(obj,name,fptr);
795: return(0);
796: }
798: /*MC
799: PetscObjectQueryFunction - Gets a function associated with a given object.
801: Synopsis:
802: #include <petscsys.h>
803: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))
805: Logically Collective on PetscObject
807: Input Parameters:
808: + obj - the PETSc object; this must be cast with (PetscObject), for example,
809: PetscObjectQueryFunction((PetscObject)ksp,...);
810: - name - name associated with the child function
812: Output Parameter:
813: . fptr - function pointer
815: Level: advanced
817: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind(), PetscObjectCompose(), PetscObjectQuery()
818: M*/
819: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
820: {
826: (*obj->bops->queryfunction)(obj,name,ptr);
827: return(0);
828: }
830: struct _p_PetscContainer {
831: PETSCHEADER(int);
832: void *ptr;
833: PetscErrorCode (*userdestroy)(void*);
834: };
836: /*@C
837: PetscContainerUserDestroyDefault - Default destroy routine for user-provided data that simply calls PetscFree().
839: Logically Collective on PetscContainer
841: Input Parameter:
842: . ctx - pointer to user-provided data
844: Level: advanced
846: .seealso: PetscContainerDestroy(), PetscContainerSetUserDestroy()
847: @*/
848: PetscErrorCode PetscContainerUserDestroyDefault(void* ctx)
849: {
853: PetscFree(ctx);
854: return(0);
855: }
857: /*@C
858: PetscContainerGetPointer - Gets the pointer value contained in the container.
860: Not Collective
862: Input Parameter:
863: . obj - the object created with PetscContainerCreate()
865: Output Parameter:
866: . ptr - the pointer value
868: Level: advanced
870: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
871: PetscContainerSetPointer()
872: @*/
873: PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr)
874: {
878: *ptr = obj->ptr;
879: return(0);
880: }
882: /*@C
883: PetscContainerSetPointer - Sets the pointer value contained in the container.
885: Logically Collective on PetscContainer
887: Input Parameters:
888: + obj - the object created with PetscContainerCreate()
889: - ptr - the pointer value
891: Level: advanced
893: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
894: PetscContainerGetPointer()
895: @*/
896: PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr)
897: {
901: obj->ptr = ptr;
902: return(0);
903: }
905: /*@C
906: PetscContainerDestroy - Destroys a PETSc container object.
908: Collective on PetscContainer
910: Input Parameter:
911: . obj - an object that was created with PetscContainerCreate()
913: Level: advanced
915: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
916: @*/
917: PetscErrorCode PetscContainerDestroy(PetscContainer *obj)
918: {
922: if (!*obj) return(0);
924: if (--((PetscObject)(*obj))->refct > 0) {*obj = NULL; return(0);}
925: if ((*obj)->userdestroy) { (*(*obj)->userdestroy)((*obj)->ptr); }
926: PetscHeaderDestroy(obj);
927: return(0);
928: }
930: /*@C
931: PetscContainerSetUserDestroy - Sets name of the user destroy function.
933: Logically Collective on PetscContainer
935: Input Parameters:
936: + obj - an object that was created with PetscContainerCreate()
937: - des - name of the user destroy function
939: Notes:
940: Use PetscContainerUserDestroyDefault() if the memory was obtained by calling PetscMalloc or one of its variants for single memory allocation.
942: Level: advanced
944: .seealso: PetscContainerDestroy(), PetscContainerUserDestroyDefault(), PetscMalloc(), PetscMalloc1(), PetscCalloc(), PetscCalloc1()
945: @*/
946: PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
947: {
950: obj->userdestroy = des;
951: return(0);
952: }
954: PetscClassId PETSC_CONTAINER_CLASSID;
956: /*@C
957: PetscContainerCreate - Creates a PETSc object that has room to hold
958: a single pointer. This allows one to attach any type of data (accessible
959: through a pointer) with the PetscObjectCompose() function to a PetscObject.
960: The data item itself is attached by a call to PetscContainerSetPointer().
962: Collective
964: Input Parameters:
965: . comm - MPI communicator that shares the object
967: Output Parameters:
968: . container - the container created
970: Level: advanced
972: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer(), PetscObjectCompose(), PetscObjectQuery()
973: @*/
974: PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
975: {
977: PetscContainer contain;
981: PetscSysInitializePackage();
982: PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);
983: *container = contain;
984: return(0);
985: }
987: /*@
988: PetscObjectSetFromOptions - Sets generic parameters from user options.
990: Collective on obj
992: Input Parameter:
993: . obj - the PetscObjcet
995: Options Database Keys:
997: Notes:
998: We have no generic options at present, so this does nothing
1000: Level: beginner
1002: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
1003: @*/
1004: PetscErrorCode PetscObjectSetFromOptions(PetscObject obj)
1005: {
1008: return(0);
1009: }
1011: /*@
1012: PetscObjectSetUp - Sets up the internal data structures for the later use.
1014: Collective on PetscObject
1016: Input Parameters:
1017: . obj - the PetscObject
1019: Notes:
1020: This does nothing at present.
1022: Level: advanced
1024: .seealso: PetscObjectDestroy()
1025: @*/
1026: PetscErrorCode PetscObjectSetUp(PetscObject obj)
1027: {
1030: return(0);
1031: }