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];
220: PetscInt newnum = PetscMax(*cid - PETSC_SMALLEST_FORTRAN_CALLBACK + 1, 2*oldnum);
221: PetscFortranCallback *callback;
222: PetscMalloc1(newnum,&callback);
223: PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));
224: PetscFree(obj->fortrancallback[cbtype]);
226: obj->fortrancallback[cbtype] = callback;
227: obj->num_fortrancallback[cbtype] = newnum;
228: }
229: obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func;
230: obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx;
231: return(0);
232: }
234: /*@C
235: PetscObjectGetFortranCallback - get fortran callback function pointer and context
237: Logically Collective
239: Input Parameters:
240: + obj - object on which to get callback
241: . cbtype - callback type
242: - cid - address of callback Id
244: Output Parameters:
245: + func - Fortran function (or NULL if not needed)
246: - ctx - Fortran context (or NULL if not needed)
248: Level: developer
250: .seealso: PetscObjectSetFortranCallback()
251: @*/
252: PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx)
253: {
254: PetscFortranCallback *cb;
258: if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid");
259: 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");
260: cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK];
261: if (func) *func = cb->func;
262: if (ctx) *ctx = cb->ctx;
263: return(0);
264: }
266: #if defined(PETSC_USE_LOG)
267: /*@C
268: PetscObjectsDump - Prints the currently existing objects.
270: Logically Collective on PetscViewer
272: Input Parameters:
273: + fd - file pointer
274: - all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects
276: Options Database:
277: . -objects_dump <all> - print information about all the objects that exist at the end of the programs run
279: Level: advanced
281: @*/
282: PetscErrorCode PetscObjectsDump(FILE *fd,PetscBool all)
283: {
285: PetscInt i;
286: #if defined(PETSC_USE_DEBUG)
287: PetscInt j,k=0;
288: #endif
289: PetscObject h;
292: if (PetscObjectsCounts) {
293: PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");
294: PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");
295: for (i=0; i<PetscObjectsMaxCounts; i++) {
296: if ((h = PetscObjects[i])) {
297: PetscObjectName(h);
298: {
299: #if defined(PETSC_USE_DEBUG)
300: PetscStack *stack = NULL;
301: char *create,*rclass;
303: /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */
304: PetscMallocGetStack(h,&stack);
305: if (stack) {
306: k = stack->currentsize-2;
307: if (!all) {
308: k = 0;
309: while (!stack->petscroutine[k]) k++;
310: PetscStrstr(stack->function[k],"Create",&create);
311: if (!create) {
312: PetscStrstr(stack->function[k],"Get",&create);
313: }
314: PetscStrstr(stack->function[k],h->class_name,&rclass);
315: if (!create) continue;
316: if (!rclass) continue;
317: }
318: }
319: #endif
321: PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);
323: #if defined(PETSC_USE_DEBUG)
324: PetscMallocGetStack(h,&stack);
325: if (stack) {
326: for (j=k; j>=0; j--) {
327: fprintf(fd," [%d] %s() in %s\n",PetscGlobalRank,stack->function[j],stack->file[j]);
328: }
329: }
330: #endif
331: }
332: }
333: }
334: }
335: return(0);
336: }
337: #endif
339: #if defined(PETSC_USE_LOG)
341: /*@C
342: PetscObjectsView - Prints the currently existing objects.
344: Logically Collective on PetscViewer
346: Input Parameter:
347: . viewer - must be an PETSCVIEWERASCII viewer
349: Level: advanced
351: @*/
352: PetscErrorCode PetscObjectsView(PetscViewer viewer)
353: {
355: PetscBool isascii;
356: FILE *fd;
359: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
360: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
361: if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
362: PetscViewerASCIIGetPointer(viewer,&fd);
363: PetscObjectsDump(fd,PETSC_TRUE);
364: return(0);
365: }
367: /*@C
368: PetscObjectsGetObject - Get a pointer to a named object
370: Not collective
372: Input Parameter:
373: . name - the name of an object
375: Output Parameters:
376: + obj - the object or null if there is no object
377: - classname - the name of the class
379: Level: advanced
381: @*/
382: PetscErrorCode PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
383: {
385: PetscInt i;
386: PetscObject h;
387: PetscBool flg;
390: *obj = NULL;
391: for (i=0; i<PetscObjectsMaxCounts; i++) {
392: if ((h = PetscObjects[i])) {
393: PetscObjectName(h);
394: PetscStrcmp(h->name,name,&flg);
395: if (flg) {
396: *obj = h;
397: if (classname) *classname = h->class_name;
398: return(0);
399: }
400: }
401: }
402: return(0);
403: }
404: #endif
406: /*@
407: PetscObjectSetPrintedOptions - indicate to an object that it should behave as if it has already printed the help for its options
409: Input Parameters:
410: . obj - the PetscObject
412: Level: developer
414: Developer Notes:
415: This is used, for example to prevent sequential objects that are created from a parallel object; such as the KSP created by
416: PCBJACOBI from all printing the same help messages to the screen
418: .seealso: PetscOptionsInsert()
419: @*/
420: PetscErrorCode PetscObjectSetPrintedOptions(PetscObject obj)
421: {
423: obj->optionsprinted = PETSC_TRUE;
424: return(0);
425: }
427: /*@
428: 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.
430: Input Parameters:
431: + pobj - the parent object
432: - obj - the PetscObject
434: Level: developer
436: Developer Notes:
437: This is used, for example to prevent sequential objects that are created from a parallel object; such as the KSP created by
438: PCBJACOBI from all printing the same help messages to the screen
440: This will not handle more complicated situations like with GASM where children may live on any subset of the parent's processes and overlap
442: .seealso: PetscOptionsInsert(), PetscObjectSetPrintedOptions()
443: @*/
444: PetscErrorCode PetscObjectInheritPrintedOptions(PetscObject pobj,PetscObject obj)
445: {
447: PetscMPIInt prank,size;
450: MPI_Comm_rank(pobj->comm,&prank);
451: MPI_Comm_size(obj->comm,&size);
452: if (size == 1 && prank > 0) obj->optionsprinted = PETSC_TRUE;
453: return(0);
454: }
456: /*@C
457: PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
459: Not Collective
461: Input Parameters:
462: + obj - the PETSc object
463: . handle - function that checks for options
464: . destroy - function to destroy context if provided
465: - ctx - optional context for check function
467: Level: developer
469: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()
471: @*/
472: PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscOptionItems*,PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
473: {
476: if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
477: obj->optionhandler[obj->noptionhandler] = handle;
478: obj->optiondestroy[obj->noptionhandler] = destroy;
479: obj->optionctx[obj->noptionhandler++] = ctx;
480: return(0);
481: }
483: /*@C
484: PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object
486: Not Collective
488: Input Parameter:
489: . obj - the PETSc object
491: Level: developer
493: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()
495: @*/
496: PetscErrorCode PetscObjectProcessOptionsHandlers(PetscOptionItems *PetscOptionsObject,PetscObject obj)
497: {
498: PetscInt i;
503: for (i=0; i<obj->noptionhandler; i++) {
504: (*obj->optionhandler[i])(PetscOptionsObject,obj,obj->optionctx[i]);
505: }
506: return(0);
507: }
509: /*@C
510: PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object
512: Not Collective
514: Input Parameter:
515: . obj - the PETSc object
517: Level: developer
519: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
521: @*/
522: PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj)
523: {
524: PetscInt i;
529: for (i=0; i<obj->noptionhandler; i++) {
530: if (obj->optiondestroy[i]) {
531: (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
532: }
533: }
534: obj->noptionhandler = 0;
535: return(0);
536: }
538: /*@C
539: PetscObjectReference - Indicates to any PetscObject that it is being
540: referenced by another PetscObject. This increases the reference
541: count for that object by one.
543: Logically Collective on PetscObject
545: Input Parameter:
546: . obj - the PETSc object. This must be cast with (PetscObject), for example,
547: PetscObjectReference((PetscObject)mat);
549: Level: advanced
551: .seealso: PetscObjectCompose(), PetscObjectDereference()
552: @*/
553: PetscErrorCode PetscObjectReference(PetscObject obj)
554: {
556: if (!obj) return(0);
558: obj->refct++;
559: return(0);
560: }
562: /*@C
563: PetscObjectGetReference - Gets the current reference count for
564: any PETSc object.
566: Not Collective
568: Input Parameter:
569: . obj - the PETSc object; this must be cast with (PetscObject), for example,
570: PetscObjectGetReference((PetscObject)mat,&cnt);
572: Output Parameter:
573: . cnt - the reference count
575: Level: advanced
577: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
578: @*/
579: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
580: {
584: *cnt = obj->refct;
585: return(0);
586: }
588: /*@C
589: PetscObjectDereference - Indicates to any PetscObject that it is being
590: referenced by one less PetscObject. This decreases the reference
591: count for that object by one.
593: Collective on PetscObject if reference reaches 0 otherwise Logically Collective
595: Input Parameter:
596: . obj - the PETSc object; this must be cast with (PetscObject), for example,
597: PetscObjectDereference((PetscObject)mat);
599: Notes:
600: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not.
602: Level: advanced
604: .seealso: PetscObjectCompose(), PetscObjectReference()
605: @*/
606: PetscErrorCode PetscObjectDereference(PetscObject obj)
607: {
611: if (!obj) return(0);
613: if (obj->bops->destroy) {
614: (*obj->bops->destroy)(&obj);
615: } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
616: return(0);
617: }
619: /* ----------------------------------------------------------------------- */
620: /*
621: The following routines are the versions private to the PETSc object
622: data structures.
623: */
624: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
625: {
628: *comm = obj->comm;
629: return(0);
630: }
632: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
633: {
638: PetscObjectListRemoveReference(&obj->olist,name);
639: return(0);
640: }
642: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
643: {
645: char *tname;
646: PetscBool skipreference;
649: if (ptr) {
650: PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
651: if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
652: }
653: PetscObjectListAdd(&obj->olist,name,ptr);
654: return(0);
655: }
657: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
658: {
663: PetscObjectListFind(obj->olist,name,ptr);
664: return(0);
665: }
667: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
668: {
673: PetscFunctionListAdd(&obj->qlist,name,ptr);
674: return(0);
675: }
677: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
678: {
683: PetscFunctionListFind(obj->qlist,name,ptr);
684: return(0);
685: }
687: /*@C
688: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
690: Not Collective
692: Input Parameters:
693: + obj - the PETSc object; this must be cast with (PetscObject), for example,
694: PetscObjectCompose((PetscObject)mat,...);
695: . name - name associated with the child object
696: - ptr - the other PETSc object to associate with the PETSc object; this must also be
697: cast with (PetscObject)
699: Level: advanced
701: Notes:
702: The second objects reference count is automatically increased by one when it is
703: composed.
705: Replaces any previous object that had the same name.
707: If ptr is null and name has previously been composed using an object, then that
708: entry is removed from the obj.
710: PetscObjectCompose() can be used with any PETSc object (such as
711: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
712: PetscContainerCreate() for info on how to create an object from a
713: user-provided pointer that may then be composed with PETSc objects.
715: .seealso: PetscObjectQuery(), PetscContainerCreate(), PetscObjectComposeFunction(), PetscObjectQueryFunction()
716: @*/
717: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
718: {
725: if (obj == ptr) SETERRQ(PetscObjectComm((PetscObject)obj),PETSC_ERR_SUP,"Cannot compose object with itself");
726: (*obj->bops->compose)(obj,name,ptr);
727: return(0);
728: }
730: /*@C
731: PetscObjectQuery - Gets a PETSc object associated with a given object.
733: Not Collective
735: Input Parameters:
736: + obj - the PETSc object
737: Thus must be cast with a (PetscObject), for example,
738: PetscObjectCompose((PetscObject)mat,...);
739: . name - name associated with child object
740: - ptr - the other PETSc object associated with the PETSc object, this must be
741: cast with (PetscObject*)
743: Level: advanced
745: The reference count of neither object is increased in this call
747: .seealso: PetscObjectCompose(), PetscObjectComposeFunction(), PetscObjectQueryFunction()
748: @*/
749: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
750: {
757: (*obj->bops->query)(obj,name,ptr);
758: return(0);
759: }
761: /*MC
762: PetscObjectComposeFunction - Associates a function with a given PETSc object.
764: Synopsis:
765: #include <petscsys.h>
766: PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))
768: Logically Collective on PetscObject
770: Input Parameters:
771: + obj - the PETSc object; this must be cast with a (PetscObject), for example,
772: PetscObjectCompose((PetscObject)mat,...);
773: . name - name associated with the child function
774: . fname - name of the function
775: - fptr - function pointer
777: Level: advanced
779: Notes:
780: To remove a registered routine, pass in NULL for fptr().
782: PetscObjectComposeFunction() can be used with any PETSc object (such as
783: Mat, Vec, KSP, SNES, etc.) or any user-provided object.
785: .seealso: PetscObjectQueryFunction(), PetscContainerCreate() PetscObjectCompose(), PetscObjectQuery()
786: M*/
788: PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
789: {
795: (*obj->bops->composefunction)(obj,name,fptr);
796: return(0);
797: }
799: /*MC
800: PetscObjectQueryFunction - Gets a function associated with a given object.
802: Synopsis:
803: #include <petscsys.h>
804: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))
806: Logically Collective on PetscObject
808: Input Parameters:
809: + obj - the PETSc object; this must be cast with (PetscObject), for example,
810: PetscObjectQueryFunction((PetscObject)ksp,...);
811: - name - name associated with the child function
813: Output Parameter:
814: . fptr - function pointer
816: Level: advanced
818: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind(), PetscObjectCompose(), PetscObjectQuery()
819: M*/
820: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
821: {
827: (*obj->bops->queryfunction)(obj,name,ptr);
828: return(0);
829: }
831: struct _p_PetscContainer {
832: PETSCHEADER(int);
833: void *ptr;
834: PetscErrorCode (*userdestroy)(void*);
835: };
837: /*@C
838: PetscContainerUserDestroyDefault - Default destroy routine for user-provided data that simply calls PetscFree().
840: Logically Collective on PetscContainer
842: Input Parameter:
843: . ctx - pointer to user-provided data
845: Level: advanced
847: .seealso: PetscContainerDestroy(), PetscContainerSetUserDestroy()
848: @*/
849: PetscErrorCode PetscContainerUserDestroyDefault(void* ctx)
850: {
854: PetscFree(ctx);
855: return(0);
856: }
858: /*@C
859: PetscContainerGetPointer - Gets the pointer value contained in the container.
861: Not Collective
863: Input Parameter:
864: . obj - the object created with PetscContainerCreate()
866: Output Parameter:
867: . ptr - the pointer value
869: Level: advanced
871: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
872: PetscContainerSetPointer()
873: @*/
874: PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr)
875: {
879: *ptr = obj->ptr;
880: return(0);
881: }
883: /*@C
884: PetscContainerSetPointer - Sets the pointer value contained in the container.
886: Logically Collective on PetscContainer
888: Input Parameters:
889: + obj - the object created with PetscContainerCreate()
890: - ptr - the pointer value
892: Level: advanced
894: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
895: PetscContainerGetPointer()
896: @*/
897: PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr)
898: {
902: obj->ptr = ptr;
903: return(0);
904: }
906: /*@C
907: PetscContainerDestroy - Destroys a PETSc container object.
909: Collective on PetscContainer
911: Input Parameter:
912: . obj - an object that was created with PetscContainerCreate()
914: Level: advanced
916: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
917: @*/
918: PetscErrorCode PetscContainerDestroy(PetscContainer *obj)
919: {
923: if (!*obj) return(0);
925: if (--((PetscObject)(*obj))->refct > 0) {*obj = NULL; return(0);}
926: if ((*obj)->userdestroy) { (*(*obj)->userdestroy)((*obj)->ptr); }
927: PetscHeaderDestroy(obj);
928: return(0);
929: }
931: /*@C
932: PetscContainerSetUserDestroy - Sets name of the user destroy function.
934: Logically Collective on PetscContainer
936: Input Parameters:
937: + obj - an object that was created with PetscContainerCreate()
938: - des - name of the user destroy function
940: Notes:
941: Use PetscContainerUserDestroyDefault() if the memory was obtained by calling PetscMalloc or one of its variants for single memory allocation.
943: Level: advanced
945: .seealso: PetscContainerDestroy(), PetscContainerUserDestroyDefault(), PetscMalloc(), PetscMalloc1(), PetscCalloc(), PetscCalloc1()
946: @*/
947: PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
948: {
951: obj->userdestroy = des;
952: return(0);
953: }
955: PetscClassId PETSC_CONTAINER_CLASSID;
957: /*@C
958: PetscContainerCreate - Creates a PETSc object that has room to hold
959: a single pointer. This allows one to attach any type of data (accessible
960: through a pointer) with the PetscObjectCompose() function to a PetscObject.
961: The data item itself is attached by a call to PetscContainerSetPointer().
963: Collective
965: Input Parameters:
966: . comm - MPI communicator that shares the object
968: Output Parameters:
969: . container - the container created
971: Level: advanced
973: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer(), PetscObjectCompose(), PetscObjectQuery()
974: @*/
975: PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
976: {
978: PetscContainer contain;
982: PetscSysInitializePackage();
983: PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);
984: *container = contain;
985: return(0);
986: }
988: /*@
989: PetscObjectSetFromOptions - Sets generic parameters from user options.
991: Collective on obj
993: Input Parameter:
994: . obj - the PetscObjcet
996: Options Database Keys:
998: Notes:
999: We have no generic options at present, so this does nothing
1001: Level: beginner
1003: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
1004: @*/
1005: PetscErrorCode PetscObjectSetFromOptions(PetscObject obj)
1006: {
1009: return(0);
1010: }
1012: /*@
1013: PetscObjectSetUp - Sets up the internal data structures for the later use.
1015: Collective on PetscObject
1017: Input Parameters:
1018: . obj - the PetscObject
1020: Notes:
1021: This does nothing at present.
1023: Level: advanced
1025: .seealso: PetscObjectDestroy()
1026: @*/
1027: PetscErrorCode PetscObjectSetUp(PetscObject obj)
1028: {
1031: return(0);
1032: }