Actual source code: inherit.c
petsc-3.11.4 2019-09-28
2: /*
3: Provides utility routines for manipulating any type of PETSc object.
4: */
5: #include <petsc/private/petscimpl.h>
6: #include <petscviewer.h>
8: #if defined(PETSC_USE_LOG)
9: PETSC_INTERN PetscObject *PetscObjects;
10: PETSC_INTERN PetscInt PetscObjectsCounts;
11: PETSC_INTERN PetscInt PetscObjectsMaxCounts;
12: PETSC_INTERN PetscBool PetscObjectsLog;
13: #endif
15: #if defined(PETSC_USE_LOG)
16: PetscObject *PetscObjects = 0;
17: PetscInt PetscObjectsCounts = 0, PetscObjectsMaxCounts = 0;
18: PetscBool PetscObjectsLog = PETSC_FALSE;
19: #endif
21: PETSC_EXTERN PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm*);
22: PETSC_EXTERN PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject);
23: PETSC_EXTERN PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject*);
24: PETSC_EXTERN PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],void (*)(void));
25: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void));
27: /*
28: PetscHeaderCreate_Private - Creates a base PETSc object header and fills
29: in the default values. Called by the macro PetscHeaderCreate().
30: */
31: PetscErrorCode PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,const char class_name[],const char descr[],const char mansec[],
32: MPI_Comm comm,PetscObjectDestroyFunction destroy,PetscObjectViewFunction view)
33: {
34: static PetscInt idcnt = 1;
35: PetscErrorCode ierr;
36: #if defined(PETSC_USE_LOG)
37: PetscObject *newPetscObjects;
38: PetscInt newPetscObjectsMaxCounts,i;
39: #endif
42: h->classid = classid;
43: h->type = 0;
44: h->class_name = (char*)class_name;
45: h->description = (char*)descr;
46: h->mansec = (char*)mansec;
47: h->prefix = 0;
48: h->refct = 1;
49: #if defined(PETSC_HAVE_SAWS)
50: h->amsmem = PETSC_FALSE;
51: #endif
52: h->id = idcnt++;
53: h->parentid = 0;
54: h->qlist = 0;
55: h->olist = 0;
56: h->bops->destroy = destroy;
57: h->bops->view = view;
58: h->bops->getcomm = PetscObjectGetComm_Petsc;
59: h->bops->compose = PetscObjectCompose_Petsc;
60: h->bops->query = PetscObjectQuery_Petsc;
61: h->bops->composefunction = PetscObjectComposeFunction_Petsc;
62: h->bops->queryfunction = PetscObjectQueryFunction_Petsc;
64: PetscCommDuplicate(comm,&h->comm,&h->tag);
66: #if defined(PETSC_USE_LOG)
67: /* Keep a record of object created */
68: if (PetscObjectsLog) {
69: PetscObjectsCounts++;
70: for (i=0; i<PetscObjectsMaxCounts; i++) {
71: if (!PetscObjects[i]) {
72: PetscObjects[i] = h;
73: return(0);
74: }
75: }
76: /* Need to increase the space for storing PETSc objects */
77: if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100;
78: else newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts;
79: PetscMalloc1(newPetscObjectsMaxCounts,&newPetscObjects);
80: PetscMemcpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts*sizeof(PetscObject));
81: PetscMemzero(newPetscObjects+PetscObjectsMaxCounts,(newPetscObjectsMaxCounts - PetscObjectsMaxCounts)*sizeof(PetscObject));
82: PetscFree(PetscObjects);
84: PetscObjects = newPetscObjects;
85: PetscObjects[PetscObjectsMaxCounts] = h;
86: PetscObjectsMaxCounts = newPetscObjectsMaxCounts;
87: }
88: #endif
89: return(0);
90: }
92: PETSC_INTERN PetscBool PetscMemoryCollectMaximumUsage;
93: PETSC_INTERN PetscLogDouble PetscMemoryMaximumUsage;
95: /*
96: PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
97: the macro PetscHeaderDestroy().
98: */
99: PetscErrorCode PetscHeaderDestroy_Private(PetscObject h)
100: {
105: PetscLogObjectDestroy(h);
106: PetscComposedQuantitiesDestroy(h);
107: if (PetscMemoryCollectMaximumUsage) {
108: PetscLogDouble usage;
109: PetscMemoryGetCurrentUsage(&usage);
110: if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
111: }
112: /* first destroy things that could execute arbitrary code */
113: if (h->python_destroy) {
114: void *python_context = h->python_context;
115: PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
116: h->python_context = 0;
117: h->python_destroy = 0;
119: (*python_destroy)(python_context);
120: }
121: PetscObjectDestroyOptionsHandlers(h);
122: PetscObjectListDestroy(&h->olist);
123: PetscCommDestroy(&h->comm);
124: /* next destroy other things */
125: h->classid = PETSCFREEDHEADER;
127: PetscFunctionListDestroy(&h->qlist);
128: PetscFree(h->type_name);
129: PetscFree(h->name);
130: PetscFree(h->prefix);
131: PetscFree(h->fortran_func_pointers);
132: PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_CLASS]);
133: PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
135: #if defined(PETSC_USE_LOG)
136: if (PetscObjectsLog) {
137: PetscInt i;
138: /* Record object removal from list of all objects */
139: for (i=0; i<PetscObjectsMaxCounts; i++) {
140: if (PetscObjects[i] == h) {
141: PetscObjects[i] = 0;
142: PetscObjectsCounts--;
143: break;
144: }
145: }
146: if (!PetscObjectsCounts) {
147: PetscFree(PetscObjects);
148: PetscObjectsMaxCounts = 0;
149: }
150: }
151: #endif
152: return(0);
153: }
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: dest->num_fortrancallback[cbtype] = src->num_fortrancallback[cbtype];
191: }
192: return(0);
193: }
195: /*@C
196: PetscObjectSetFortranCallback - set fortran callback function pointer and context
198: Logically Collective
200: Input Arguments:
201: + obj - object on which to set callback
202: . cbtype - callback type (class or subtype)
203: . cid - address of callback Id, updated if not yet initialized (zero)
204: . func - Fortran function
205: - ctx - Fortran context
207: Level: developer
209: .seealso: PetscObjectGetFortranCallback()
210: @*/
211: PetscErrorCode PetscObjectSetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId *cid,void (*func)(void),void *ctx)
212: {
214: const char *subtype = NULL;
218: if (cbtype == PETSC_FORTRAN_CALLBACK_SUBTYPE) subtype = obj->type_name;
219: if (!*cid) {PetscFortranCallbackRegister(obj->classid,subtype,cid);}
220: if (*cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype]) {
221: PetscInt oldnum = obj->num_fortrancallback[cbtype],newnum = PetscMax(1,2*oldnum);
222: PetscFortranCallback *callback;
223: PetscMalloc1(newnum,&callback);
224: PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));
225: PetscFree(obj->fortrancallback[cbtype]);
227: obj->fortrancallback[cbtype] = callback;
228: obj->num_fortrancallback[cbtype] = newnum;
229: }
230: obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func;
231: obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx;
232: return(0);
233: }
235: /*@C
236: PetscObjectGetFortranCallback - get fortran callback function pointer and context
238: Logically Collective
240: Input Arguments:
241: + obj - object on which to get callback
242: . cbtype - callback type
243: - cid - address of callback Id
245: Output Arguments:
246: + func - Fortran function (or NULL if not needed)
247: - ctx - Fortran context (or NULL if not needed)
249: Level: developer
251: .seealso: PetscObjectSetFortranCallback()
252: @*/
253: PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx)
254: {
255: PetscFortranCallback *cb;
259: if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid");
260: 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");
261: cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK];
262: if (func) *func = cb->func;
263: if (ctx) *ctx = cb->ctx;
264: return(0);
265: }
267: #if defined(PETSC_USE_LOG)
268: /*@C
269: PetscObjectsDump - Prints the currently existing objects.
271: Logically Collective on PetscViewer
273: Input Parameter:
274: + fd - file pointer
275: - all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects
277: Options Database:
278: . -objects_dump <all>
280: Level: advanced
282: Concepts: options database^printing
284: @*/
285: PetscErrorCode PetscObjectsDump(FILE *fd,PetscBool all)
286: {
288: PetscInt i;
289: #if defined(PETSC_USE_DEBUG)
290: PetscInt j,k=0;
291: #endif
292: PetscObject h;
295: if (PetscObjectsCounts) {
296: PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");
297: PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");
298: for (i=0; i<PetscObjectsMaxCounts; i++) {
299: if ((h = PetscObjects[i])) {
300: PetscObjectName(h);
301: {
302: #if defined(PETSC_USE_DEBUG)
303: PetscStack *stack = 0;
304: char *create,*rclass;
306: /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */
307: PetscMallocGetStack(h,&stack);
308: if (stack) {
309: k = stack->currentsize-2;
310: if (!all) {
311: k = 0;
312: while (!stack->petscroutine[k]) k++;
313: PetscStrstr(stack->function[k],"Create",&create);
314: if (!create) {
315: PetscStrstr(stack->function[k],"Get",&create);
316: }
317: PetscStrstr(stack->function[k],h->class_name,&rclass);
318: if (!create) continue;
319: if (!rclass) continue;
320: }
321: }
322: #endif
324: PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);
326: #if defined(PETSC_USE_DEBUG)
327: PetscMallocGetStack(h,&stack);
328: if (stack) {
329: for (j=k; j>=0; j--) {
330: fprintf(fd," [%d] %s() in %s\n",PetscGlobalRank,stack->function[j],stack->file[j]);
331: }
332: }
333: #endif
334: }
335: }
336: }
337: }
338: return(0);
339: }
340: #endif
342: #if defined(PETSC_USE_LOG)
344: /*@C
345: PetscObjectsView - Prints the currently existing objects.
347: Logically Collective on PetscViewer
349: Input Parameter:
350: . viewer - must be an PETSCVIEWERASCII viewer
352: Level: advanced
354: Concepts: options database^printing
356: @*/
357: PetscErrorCode PetscObjectsView(PetscViewer viewer)
358: {
360: PetscBool isascii;
361: FILE *fd;
364: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
365: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
366: if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
367: PetscViewerASCIIGetPointer(viewer,&fd);
368: PetscObjectsDump(fd,PETSC_TRUE);
369: return(0);
370: }
372: /*@C
373: PetscObjectsGetObject - Get a pointer to a named object
375: Not collective
377: Input Parameter:
378: . name - the name of an object
380: Output Parameter:
381: . obj - the object or null if there is no object
383: Level: advanced
385: Concepts: options database^printing
387: @*/
388: PetscErrorCode PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
389: {
391: PetscInt i;
392: PetscObject h;
393: PetscBool flg;
396: *obj = NULL;
397: for (i=0; i<PetscObjectsMaxCounts; i++) {
398: if ((h = PetscObjects[i])) {
399: PetscObjectName(h);
400: PetscStrcmp(h->name,name,&flg);
401: if (flg) {
402: *obj = h;
403: if (classname) *classname = h->class_name;
404: return(0);
405: }
406: }
407: }
408: return(0);
409: }
410: #endif
412: /*@
413: PetscObjectSetPrintedOptions - indicate to an object that it should behave as if it has already printed the help for its options
415: Input Parameters:
416: . obj - the PetscObject
418: Level: developer
420: Developer Notes:
421: This is used, for example to prevent sequential objects that are created from a parallel object; such as the KSP created by
422: PCBJACOBI from all printing the same help messages to the screen
424: .seealso: PetscOptionsInsert()
425: @*/
426: PetscErrorCode PetscObjectSetPrintedOptions(PetscObject obj)
427: {
429: obj->optionsprinted = PETSC_TRUE;
430: return(0);
431: }
433: /*@
434: 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.
436: Input Parameters:
437: + pobj - the parent object
438: - obj - the PetscObject
440: Level: developer
442: Developer Notes:
443: This is used, for example to prevent sequential objects that are created from a parallel object; such as the KSP created by
444: PCBJACOBI from all printing the same help messages to the screen
446: This will not handle more complicated situations like with GASM where children may live on any subset of the parent's processes and overlap
448: .seealso: PetscOptionsInsert(), PetscObjectSetPrintedOptions()
449: @*/
450: PetscErrorCode PetscObjectInheritPrintedOptions(PetscObject pobj,PetscObject obj)
451: {
453: PetscMPIInt prank,size;
456: MPI_Comm_rank(pobj->comm,&prank);
457: MPI_Comm_size(obj->comm,&size);
458: if (size == 1 && prank > 0) obj->optionsprinted = PETSC_TRUE;
459: return(0);
460: }
462: /*@C
463: PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
465: Not Collective
467: Input Parameter:
468: + obj - the PETSc object
469: . handle - function that checks for options
470: . destroy - function to destroy context if provided
471: - ctx - optional context for check function
473: Level: developer
476: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()
478: @*/
479: PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscOptionItems*,PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
480: {
483: if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
484: obj->optionhandler[obj->noptionhandler] = handle;
485: obj->optiondestroy[obj->noptionhandler] = destroy;
486: obj->optionctx[obj->noptionhandler++] = ctx;
487: return(0);
488: }
490: /*@C
491: PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object
493: Not Collective
495: Input Parameter:
496: . obj - the PETSc object
498: Level: developer
501: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()
503: @*/
504: PetscErrorCode PetscObjectProcessOptionsHandlers(PetscOptionItems *PetscOptionsObject,PetscObject obj)
505: {
506: PetscInt i;
511: for (i=0; i<obj->noptionhandler; i++) {
512: (*obj->optionhandler[i])(PetscOptionsObject,obj,obj->optionctx[i]);
513: }
514: return(0);
515: }
517: /*@C
518: PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object
520: Not Collective
522: Input Parameter:
523: . obj - the PETSc object
525: Level: developer
528: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
530: @*/
531: PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj)
532: {
533: PetscInt i;
538: for (i=0; i<obj->noptionhandler; i++) {
539: if (obj->optiondestroy[i]) {
540: (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
541: }
542: }
543: obj->noptionhandler = 0;
544: return(0);
545: }
548: /*@C
549: PetscObjectReference - Indicates to any PetscObject that it is being
550: referenced by another PetscObject. This increases the reference
551: count for that object by one.
553: Logically Collective on PetscObject
555: Input Parameter:
556: . obj - the PETSc object. This must be cast with (PetscObject), for example,
557: PetscObjectReference((PetscObject)mat);
559: Level: advanced
561: .seealso: PetscObjectCompose(), PetscObjectDereference()
562: @*/
563: PetscErrorCode PetscObjectReference(PetscObject obj)
564: {
566: if (!obj) return(0);
568: obj->refct++;
569: return(0);
570: }
572: /*@C
573: PetscObjectGetReference - Gets the current reference count for
574: any PETSc object.
576: Not Collective
578: Input Parameter:
579: . obj - the PETSc object; this must be cast with (PetscObject), for example,
580: PetscObjectGetReference((PetscObject)mat,&cnt);
582: Output Parameter:
583: . cnt - the reference count
585: Level: advanced
587: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
588: @*/
589: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
590: {
594: *cnt = obj->refct;
595: return(0);
596: }
598: /*@C
599: PetscObjectDereference - Indicates to any PetscObject that it is being
600: referenced by one less PetscObject. This decreases the reference
601: count for that object by one.
603: Collective on PetscObject if reference reaches 0 otherwise Logically Collective
605: Input Parameter:
606: . obj - the PETSc object; this must be cast with (PetscObject), for example,
607: PetscObjectDereference((PetscObject)mat);
609: Notes:
610: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not.
612: Level: advanced
614: .seealso: PetscObjectCompose(), PetscObjectReference()
615: @*/
616: PetscErrorCode PetscObjectDereference(PetscObject obj)
617: {
621: if (!obj) return(0);
623: if (obj->bops->destroy) {
624: (*obj->bops->destroy)(&obj);
625: } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
626: return(0);
627: }
629: /* ----------------------------------------------------------------------- */
630: /*
631: The following routines are the versions private to the PETSc object
632: data structures.
633: */
634: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
635: {
638: *comm = obj->comm;
639: return(0);
640: }
642: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
643: {
648: PetscObjectListRemoveReference(&obj->olist,name);
649: return(0);
650: }
652: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
653: {
655: char *tname;
656: PetscBool skipreference;
659: if (ptr) {
660: PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
661: if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
662: }
663: PetscObjectListAdd(&obj->olist,name,ptr);
664: return(0);
665: }
667: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
668: {
673: PetscObjectListFind(obj->olist,name,ptr);
674: return(0);
675: }
677: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
678: {
683: PetscFunctionListAdd(&obj->qlist,name,ptr);
684: return(0);
685: }
687: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
688: {
693: PetscFunctionListFind(obj->qlist,name,ptr);
694: return(0);
695: }
697: /*@C
698: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
700: Not Collective
702: Input Parameters:
703: + obj - the PETSc object; this must be cast with (PetscObject), for example,
704: PetscObjectCompose((PetscObject)mat,...);
705: . name - name associated with the child object
706: - ptr - the other PETSc object to associate with the PETSc object; this must also be
707: cast with (PetscObject)
709: Level: advanced
711: Notes:
712: The second objects reference count is automatically increased by one when it is
713: composed.
715: Replaces any previous object that had the same name.
717: If ptr is null and name has previously been composed using an object, then that
718: entry is removed from the obj.
720: PetscObjectCompose() can be used with any PETSc object (such as
721: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
722: PetscContainerCreate() for info on how to create an object from a
723: user-provided pointer that may then be composed with PETSc objects.
725: Concepts: objects^composing
726: Concepts: composing objects
728: .seealso: PetscObjectQuery(), PetscContainerCreate()
729: @*/
730: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
731: {
738: if (obj == ptr) SETERRQ(PetscObjectComm((PetscObject)obj),PETSC_ERR_SUP,"Cannot compose object with itself");
739: (*obj->bops->compose)(obj,name,ptr);
740: return(0);
741: }
743: /*@C
744: PetscObjectQuery - Gets a PETSc object associated with a given object.
746: Not Collective
748: Input Parameters:
749: + obj - the PETSc object
750: Thus must be cast with a (PetscObject), for example,
751: PetscObjectCompose((PetscObject)mat,...);
752: . name - name associated with child object
753: - ptr - the other PETSc object associated with the PETSc object, this must be
754: cast with (PetscObject*)
756: Level: advanced
758: The reference count of neither object is increased in this call
760: Concepts: objects^composing
761: Concepts: composing objects
762: Concepts: objects^querying
763: Concepts: querying objects
765: .seealso: PetscObjectCompose()
766: @*/
767: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
768: {
775: (*obj->bops->query)(obj,name,ptr);
776: return(0);
777: }
779: /*MC
780: PetscObjectComposeFunction - Associates a function with a given PETSc object.
782: Synopsis:
783: #include <petscsys.h>
784: PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))
786: Logically Collective on PetscObject
788: Input Parameters:
789: + obj - the PETSc object; this must be cast with a (PetscObject), for example,
790: PetscObjectCompose((PetscObject)mat,...);
791: . name - name associated with the child function
792: . fname - name of the function
793: - fptr - function pointer
795: Level: advanced
797: Notes:
798: To remove a registered routine, pass in NULL for fptr().
800: PetscObjectComposeFunction() can be used with any PETSc object (such as
801: Mat, Vec, KSP, SNES, etc.) or any user-provided object.
803: Concepts: objects^composing functions
804: Concepts: composing functions
805: Concepts: functions^querying
806: Concepts: objects^querying
807: Concepts: querying objects
809: .seealso: PetscObjectQueryFunction(), PetscContainerCreate()
810: M*/
812: PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
813: {
819: (*obj->bops->composefunction)(obj,name,fptr);
820: return(0);
821: }
823: /*MC
824: PetscObjectQueryFunction - Gets a function associated with a given object.
826: Synopsis:
827: #include <petscsys.h>
828: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))
830: Logically Collective on PetscObject
832: Input Parameters:
833: + obj - the PETSc object; this must be cast with (PetscObject), for example,
834: PetscObjectQueryFunction((PetscObject)ksp,...);
835: - name - name associated with the child function
837: Output Parameter:
838: . fptr - function pointer
840: Level: advanced
842: Concepts: objects^composing functions
843: Concepts: composing functions
844: Concepts: functions^querying
845: Concepts: objects^querying
846: Concepts: querying objects
848: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind()
849: M*/
850: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
851: {
857: (*obj->bops->queryfunction)(obj,name,ptr);
858: return(0);
859: }
861: struct _p_PetscContainer {
862: PETSCHEADER(int);
863: void *ptr;
864: PetscErrorCode (*userdestroy)(void*);
865: };
867: /*@C
868: PetscContainerUserDestroyDefault - Default destroy routine for user-provided data that simply calls PetscFree().
870: Logically Collective on PetscContainer
872: Input Parameter:
873: . ctx - pointer to user-provided data
875: Level: advanced
877: .seealso: PetscContainerDestroy(), PetscContainterSetUserDestroy()
878: @*/
879: PetscErrorCode PetscContainerUserDestroyDefault(void* ctx)
880: {
884: PetscFree(ctx);
885: return(0);
886: }
888: /*@C
889: PetscContainerGetPointer - Gets the pointer value contained in the container.
891: Not Collective
893: Input Parameter:
894: . obj - the object created with PetscContainerCreate()
896: Output Parameter:
897: . ptr - the pointer value
899: Level: advanced
901: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
902: PetscContainerSetPointer()
903: @*/
904: PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr)
905: {
909: *ptr = obj->ptr;
910: return(0);
911: }
914: /*@C
915: PetscContainerSetPointer - Sets the pointer value contained in the container.
917: Logically Collective on PetscContainer
919: Input Parameters:
920: + obj - the object created with PetscContainerCreate()
921: - ptr - the pointer value
923: Level: advanced
925: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
926: PetscContainerGetPointer()
927: @*/
928: PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr)
929: {
933: obj->ptr = ptr;
934: return(0);
935: }
937: /*@C
938: PetscContainerDestroy - Destroys a PETSc container object.
940: Collective on PetscContainer
942: Input Parameter:
943: . obj - an object that was created with PetscContainerCreate()
945: Level: advanced
947: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
948: @*/
949: PetscErrorCode PetscContainerDestroy(PetscContainer *obj)
950: {
954: if (!*obj) return(0);
956: if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; return(0);}
957: if ((*obj)->userdestroy) { (*(*obj)->userdestroy)((*obj)->ptr); }
958: PetscHeaderDestroy(obj);
959: return(0);
960: }
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: Notes:
972: Use PetscContainerUserDestroyDefault() if the memory was obtained by calling PetscMalloc or one of its variants for single memory allocation.
974: Level: advanced
976: .seealso: PetscContainerDestroy(), PetscContainerUserDestroyDefault(), PetscMalloc(), PetscMalloc1(), PetscCalloc(), PetscCalloc1()
977: @*/
978: PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
979: {
982: obj->userdestroy = des;
983: return(0);
984: }
986: PetscClassId PETSC_CONTAINER_CLASSID;
988: /*@C
989: PetscContainerCreate - Creates a PETSc object that has room to hold
990: a single pointer. This allows one to attach any type of data (accessible
991: through a pointer) with the PetscObjectCompose() function to a PetscObject.
992: The data item itself is attached by a call to PetscContainerSetPointer().
994: Collective on MPI_Comm
996: Input Parameters:
997: . comm - MPI communicator that shares the object
999: Output Parameters:
1000: . container - the container created
1002: Level: advanced
1004: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
1005: @*/
1006: PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
1007: {
1009: PetscContainer contain;
1013: PetscSysInitializePackage();
1014: PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);
1015: *container = contain;
1016: return(0);
1017: }
1019: /*@
1020: PetscObjectSetFromOptions - Sets generic parameters from user options.
1022: Collective on obj
1024: Input Parameter:
1025: . obj - the PetscObjcet
1027: Options Database Keys:
1029: Notes:
1030: We have no generic options at present, so this does nothing
1032: Level: beginner
1034: .keywords: set, options, database
1035: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
1036: @*/
1037: PetscErrorCode PetscObjectSetFromOptions(PetscObject obj)
1038: {
1041: return(0);
1042: }
1044: /*@
1045: PetscObjectSetUp - Sets up the internal data structures for the later use.
1047: Collective on PetscObject
1049: Input Parameters:
1050: . obj - the PetscObject
1052: Notes:
1053: This does nothing at present.
1055: Level: advanced
1057: .keywords: setup
1058: .seealso: PetscObjectDestroy()
1059: @*/
1060: PetscErrorCode PetscObjectSetUp(PetscObject obj)
1061: {
1064: return(0);
1065: }