Actual source code: inherit.c
petsc-3.9.4 2018-09-11
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: PetscObject *PetscObjects = 0;
10: PetscInt PetscObjectsCounts = 0, PetscObjectsMaxCounts = 0;
11: PetscBool PetscObjectsLog = PETSC_FALSE;
12: #endif
14: extern PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm*);
15: extern PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject);
16: extern PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject*);
17: extern PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],void (*)(void));
18: extern PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void));
20: /*
21: PetscHeaderCreate_Private - Creates a base PETSc object header and fills
22: in the default values. Called by the macro PetscHeaderCreate().
23: */
24: PetscErrorCode PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,const char class_name[],const char descr[],const char mansec[],
25: MPI_Comm comm,PetscObjectDestroyFunction destroy,PetscObjectViewFunction view)
26: {
27: static PetscInt idcnt = 1;
28: PetscErrorCode ierr;
29: #if defined(PETSC_USE_LOG)
30: PetscObject *newPetscObjects;
31: PetscInt newPetscObjectsMaxCounts,i;
32: #endif
35: h->classid = classid;
36: h->type = 0;
37: h->class_name = (char*)class_name;
38: h->description = (char*)descr;
39: h->mansec = (char*)mansec;
40: h->prefix = 0;
41: h->refct = 1;
42: #if defined(PETSC_HAVE_SAWS)
43: h->amsmem = PETSC_FALSE;
44: #endif
45: h->id = idcnt++;
46: h->parentid = 0;
47: h->qlist = 0;
48: h->olist = 0;
49: h->bops->destroy = destroy;
50: h->bops->view = view;
51: h->bops->getcomm = PetscObjectGetComm_Petsc;
52: h->bops->compose = PetscObjectCompose_Petsc;
53: h->bops->query = PetscObjectQuery_Petsc;
54: h->bops->composefunction = PetscObjectComposeFunction_Petsc;
55: h->bops->queryfunction = PetscObjectQueryFunction_Petsc;
57: PetscCommDuplicate(comm,&h->comm,&h->tag);
59: #if defined(PETSC_USE_LOG)
60: /* Keep a record of object created */
61: if (PetscObjectsLog) {
62: PetscObjectsCounts++;
63: for (i=0; i<PetscObjectsMaxCounts; i++) {
64: if (!PetscObjects[i]) {
65: PetscObjects[i] = h;
66: return(0);
67: }
68: }
69: /* Need to increase the space for storing PETSc objects */
70: if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100;
71: else newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts;
72: PetscMalloc1(newPetscObjectsMaxCounts,&newPetscObjects);
73: PetscMemcpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts*sizeof(PetscObject));
74: PetscMemzero(newPetscObjects+PetscObjectsMaxCounts,(newPetscObjectsMaxCounts - PetscObjectsMaxCounts)*sizeof(PetscObject));
75: PetscFree(PetscObjects);
77: PetscObjects = newPetscObjects;
78: PetscObjects[PetscObjectsMaxCounts] = h;
79: PetscObjectsMaxCounts = newPetscObjectsMaxCounts;
80: }
81: #endif
82: return(0);
83: }
85: extern PetscBool PetscMemoryCollectMaximumUsage;
86: extern PetscLogDouble PetscMemoryMaximumUsage;
88: /*
89: PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
90: the macro PetscHeaderDestroy().
91: */
92: PetscErrorCode PetscHeaderDestroy_Private(PetscObject h)
93: {
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 = 0;
110: h->python_destroy = 0;
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] = 0;
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 Parameter:
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: {
165: PetscInt cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE];
170: if (src->classid != dest->classid) SETERRQ(src->comm,PETSC_ERR_ARG_INCOMP,"Objects must be of the same class");
172: PetscFree(dest->fortran_func_pointers);
173: PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);
174: PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));
176: dest->num_fortran_func_pointers = src->num_fortran_func_pointers;
178: PetscFortranCallbackGetSizes(src->classid,&numcb[PETSC_FORTRAN_CALLBACK_CLASS],&numcb[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
179: for (cbtype=PETSC_FORTRAN_CALLBACK_CLASS; cbtype<PETSC_FORTRAN_CALLBACK_MAXTYPE; cbtype++) {
180: PetscFree(dest->fortrancallback[cbtype]);
181: PetscCalloc1(numcb[cbtype],&dest->fortrancallback[cbtype]);
182: PetscMemcpy(dest->fortrancallback[cbtype],src->fortrancallback[cbtype],src->num_fortrancallback[cbtype]*sizeof(PetscFortranCallback));
183: dest->num_fortrancallback[cbtype] = src->num_fortrancallback[cbtype];
184: }
185: return(0);
186: }
188: /*@C
189: PetscObjectSetFortranCallback - set fortran callback function pointer and context
191: Logically Collective
193: Input Arguments:
194: + obj - object on which to set callback
195: . cbtype - callback type (class or subtype)
196: . cid - address of callback Id, updated if not yet initialized (zero)
197: . func - Fortran function
198: - ctx - Fortran context
200: Level: developer
202: .seealso: PetscObjectGetFortranCallback()
203: @*/
204: PetscErrorCode PetscObjectSetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId *cid,void (*func)(void),void *ctx)
205: {
207: const char *subtype = NULL;
211: if (cbtype == PETSC_FORTRAN_CALLBACK_SUBTYPE) subtype = obj->type_name;
212: if (!*cid) {PetscFortranCallbackRegister(obj->classid,subtype,cid);}
213: if (*cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype]) {
214: PetscInt oldnum = obj->num_fortrancallback[cbtype],newnum = PetscMax(1,2*oldnum);
215: PetscFortranCallback *callback;
216: PetscMalloc1(newnum,&callback);
217: PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));
218: PetscFree(obj->fortrancallback[cbtype]);
220: obj->fortrancallback[cbtype] = callback;
221: obj->num_fortrancallback[cbtype] = newnum;
222: }
223: obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func;
224: obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx;
225: return(0);
226: }
228: /*@C
229: PetscObjectGetFortranCallback - get fortran callback function pointer and context
231: Logically Collective
233: Input Arguments:
234: + obj - object on which to get callback
235: . cbtype - callback type
236: - cid - address of callback Id
238: Output Arguments:
239: + func - Fortran function (or NULL if not needed)
240: - ctx - Fortran context (or NULL if not needed)
242: Level: developer
244: .seealso: PetscObjectSetFortranCallback()
245: @*/
246: PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx)
247: {
248: PetscFortranCallback *cb;
252: if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid");
253: 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");
254: cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK];
255: if (func) *func = cb->func;
256: if (ctx) *ctx = cb->ctx;
257: return(0);
258: }
260: #if defined(PETSC_USE_LOG)
261: /*@C
262: PetscObjectsDump - Prints the currently existing objects.
264: Logically Collective on PetscViewer
266: Input Parameter:
267: + fd - file pointer
268: - all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects
270: Options Database:
271: . -objects_dump <all>
273: Level: advanced
275: Concepts: options database^printing
277: @*/
278: PetscErrorCode PetscObjectsDump(FILE *fd,PetscBool all)
279: {
281: PetscInt i;
282: #if defined(PETSC_USE_DEBUG)
283: PetscInt j,k=0;
284: #endif
285: PetscObject h;
288: if (PetscObjectsCounts) {
289: PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");
290: PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");
291: for (i=0; i<PetscObjectsMaxCounts; i++) {
292: if ((h = PetscObjects[i])) {
293: PetscObjectName(h);
294: {
295: #if defined(PETSC_USE_DEBUG)
296: PetscStack *stack = 0;
297: char *create,*rclass;
299: /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */
300: PetscMallocGetStack(h,&stack);
301: if (stack) {
302: k = stack->currentsize-2;
303: if (!all) {
304: k = 0;
305: while (!stack->petscroutine[k]) k++;
306: PetscStrstr(stack->function[k],"Create",&create);
307: if (!create) {
308: PetscStrstr(stack->function[k],"Get",&create);
309: }
310: PetscStrstr(stack->function[k],h->class_name,&rclass);
311: if (!create) continue;
312: if (!rclass) continue;
313: }
314: }
315: #endif
317: PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);
319: #if defined(PETSC_USE_DEBUG)
320: PetscMallocGetStack(h,&stack);
321: if (stack) {
322: for (j=k; j>=0; j--) {
323: fprintf(fd," [%d] %s() in %s\n",PetscGlobalRank,stack->function[j],stack->file[j]);
324: }
325: }
326: #endif
327: }
328: }
329: }
330: }
331: return(0);
332: }
333: #endif
335: #if defined(PETSC_USE_LOG)
337: /*@C
338: PetscObjectsView - Prints the currently existing objects.
340: Logically Collective on PetscViewer
342: Input Parameter:
343: . viewer - must be an PETSCVIEWERASCII viewer
345: Level: advanced
347: Concepts: options database^printing
349: @*/
350: PetscErrorCode PetscObjectsView(PetscViewer viewer)
351: {
353: PetscBool isascii;
354: FILE *fd;
357: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
358: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
359: if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
360: PetscViewerASCIIGetPointer(viewer,&fd);
361: PetscObjectsDump(fd,PETSC_TRUE);
362: return(0);
363: }
365: /*@C
366: PetscObjectsGetObject - Get a pointer to a named object
368: Not collective
370: Input Parameter:
371: . name - the name of an object
373: Output Parameter:
374: . obj - the object or null if there is no object
376: Level: advanced
378: Concepts: options database^printing
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: /*@C
406: PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
408: Not Collective
410: Input Parameter:
411: + obj - the PETSc object
412: . handle - function that checks for options
413: . destroy - function to destroy context if provided
414: - ctx - optional context for check function
416: Level: developer
419: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()
421: @*/
422: PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscOptionItems*,PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
423: {
426: if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
427: obj->optionhandler[obj->noptionhandler] = handle;
428: obj->optiondestroy[obj->noptionhandler] = destroy;
429: obj->optionctx[obj->noptionhandler++] = ctx;
430: return(0);
431: }
433: /*@C
434: PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object
436: Not Collective
438: Input Parameter:
439: . obj - the PETSc object
441: Level: developer
444: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()
446: @*/
447: PetscErrorCode PetscObjectProcessOptionsHandlers(PetscOptionItems *PetscOptionsObject,PetscObject obj)
448: {
449: PetscInt i;
454: for (i=0; i<obj->noptionhandler; i++) {
455: (*obj->optionhandler[i])(PetscOptionsObject,obj,obj->optionctx[i]);
456: }
457: return(0);
458: }
460: /*@C
461: PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object
463: Not Collective
465: Input Parameter:
466: . obj - the PETSc object
468: Level: developer
471: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
473: @*/
474: PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj)
475: {
476: PetscInt i;
481: for (i=0; i<obj->noptionhandler; i++) {
482: if (obj->optiondestroy[i]) {
483: (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
484: }
485: }
486: obj->noptionhandler = 0;
487: return(0);
488: }
491: /*@C
492: PetscObjectReference - Indicates to any PetscObject that it is being
493: referenced by another PetscObject. This increases the reference
494: count for that object by one.
496: Logically Collective on PetscObject
498: Input Parameter:
499: . obj - the PETSc object. This must be cast with (PetscObject), for example,
500: PetscObjectReference((PetscObject)mat);
502: Level: advanced
504: .seealso: PetscObjectCompose(), PetscObjectDereference()
505: @*/
506: PetscErrorCode PetscObjectReference(PetscObject obj)
507: {
509: if (!obj) return(0);
511: obj->refct++;
512: return(0);
513: }
515: /*@C
516: PetscObjectGetReference - Gets the current reference count for
517: any PETSc object.
519: Not Collective
521: Input Parameter:
522: . obj - the PETSc object; this must be cast with (PetscObject), for example,
523: PetscObjectGetReference((PetscObject)mat,&cnt);
525: Output Parameter:
526: . cnt - the reference count
528: Level: advanced
530: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
531: @*/
532: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
533: {
537: *cnt = obj->refct;
538: return(0);
539: }
541: /*@C
542: PetscObjectDereference - Indicates to any PetscObject that it is being
543: referenced by one less PetscObject. This decreases the reference
544: count for that object by one.
546: Collective on PetscObject if reference reaches 0 otherwise Logically Collective
548: Input Parameter:
549: . obj - the PETSc object; this must be cast with (PetscObject), for example,
550: PetscObjectDereference((PetscObject)mat);
552: Notes: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not.
554: Level: advanced
556: .seealso: PetscObjectCompose(), PetscObjectReference()
557: @*/
558: PetscErrorCode PetscObjectDereference(PetscObject obj)
559: {
563: if (!obj) return(0);
565: if (obj->bops->destroy) {
566: (*obj->bops->destroy)(&obj);
567: } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
568: return(0);
569: }
571: /* ----------------------------------------------------------------------- */
572: /*
573: The following routines are the versions private to the PETSc object
574: data structures.
575: */
576: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
577: {
580: *comm = obj->comm;
581: return(0);
582: }
584: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
585: {
590: PetscObjectListRemoveReference(&obj->olist,name);
591: return(0);
592: }
594: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
595: {
597: char *tname;
598: PetscBool skipreference;
601: if (ptr) {
602: PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
603: if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
604: }
605: PetscObjectListAdd(&obj->olist,name,ptr);
606: return(0);
607: }
609: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
610: {
615: PetscObjectListFind(obj->olist,name,ptr);
616: return(0);
617: }
619: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
620: {
625: PetscFunctionListAdd(&obj->qlist,name,ptr);
626: return(0);
627: }
629: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
630: {
635: PetscFunctionListFind(obj->qlist,name,ptr);
636: return(0);
637: }
639: /*@C
640: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
642: Not Collective
644: Input Parameters:
645: + obj - the PETSc object; this must be cast with (PetscObject), for example,
646: PetscObjectCompose((PetscObject)mat,...);
647: . name - name associated with the child object
648: - ptr - the other PETSc object to associate with the PETSc object; this must also be
649: cast with (PetscObject)
651: Level: advanced
653: Notes:
654: The second objects reference count is automatically increased by one when it is
655: composed.
657: Replaces any previous object that had the same name.
659: If ptr is null and name has previously been composed using an object, then that
660: entry is removed from the obj.
662: PetscObjectCompose() can be used with any PETSc object (such as
663: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
664: PetscContainerCreate() for info on how to create an object from a
665: user-provided pointer that may then be composed with PETSc objects.
667: Concepts: objects^composing
668: Concepts: composing objects
670: .seealso: PetscObjectQuery(), PetscContainerCreate()
671: @*/
672: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
673: {
680: if (obj == ptr) SETERRQ(PetscObjectComm((PetscObject)obj),PETSC_ERR_SUP,"Cannot compose object with itself");
681: (*obj->bops->compose)(obj,name,ptr);
682: return(0);
683: }
685: /*@C
686: PetscObjectQuery - Gets a PETSc object associated with a given object.
688: Not Collective
690: Input Parameters:
691: + obj - the PETSc object
692: Thus must be cast with a (PetscObject), for example,
693: PetscObjectCompose((PetscObject)mat,...);
694: . name - name associated with child object
695: - ptr - the other PETSc object associated with the PETSc object, this must be
696: cast with (PetscObject*)
698: Level: advanced
700: The reference count of neither object is increased in this call
702: Concepts: objects^composing
703: Concepts: composing objects
704: Concepts: objects^querying
705: Concepts: querying objects
707: .seealso: PetscObjectCompose()
708: @*/
709: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
710: {
717: (*obj->bops->query)(obj,name,ptr);
718: return(0);
719: }
721: /*MC
722: PetscObjectComposeFunction - Associates a function with a given PETSc object.
724: Synopsis:
725: #include <petscsys.h>
726: PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))
728: Logically Collective on PetscObject
730: Input Parameters:
731: + obj - the PETSc object; this must be cast with a (PetscObject), for example,
732: PetscObjectCompose((PetscObject)mat,...);
733: . name - name associated with the child function
734: . fname - name of the function
735: - fptr - function pointer
737: Level: advanced
739: Notes:
740: To remove a registered routine, pass in NULL for fptr().
742: PetscObjectComposeFunction() can be used with any PETSc object (such as
743: Mat, Vec, KSP, SNES, etc.) or any user-provided object.
745: Concepts: objects^composing functions
746: Concepts: composing functions
747: Concepts: functions^querying
748: Concepts: objects^querying
749: Concepts: querying objects
751: .seealso: PetscObjectQueryFunction(), PetscContainerCreate()
752: M*/
754: PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
755: {
761: (*obj->bops->composefunction)(obj,name,fptr);
762: return(0);
763: }
765: /*MC
766: PetscObjectQueryFunction - Gets a function associated with a given object.
768: Synopsis:
769: #include <petscsys.h>
770: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))
772: Logically Collective on PetscObject
774: Input Parameters:
775: + obj - the PETSc object; this must be cast with (PetscObject), for example,
776: PetscObjectQueryFunction((PetscObject)ksp,...);
777: - name - name associated with the child function
779: Output Parameter:
780: . fptr - function pointer
782: Level: advanced
784: Concepts: objects^composing functions
785: Concepts: composing functions
786: Concepts: functions^querying
787: Concepts: objects^querying
788: Concepts: querying objects
790: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind()
791: M*/
792: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
793: {
799: (*obj->bops->queryfunction)(obj,name,ptr);
800: return(0);
801: }
803: struct _p_PetscContainer {
804: PETSCHEADER(int);
805: void *ptr;
806: PetscErrorCode (*userdestroy)(void*);
807: };
809: /*@C
810: PetscContainerUserDestroyDefault - Default destroy routine for user-provided data that simply calls PetscFree().
812: Logically Collective on PetscContainer
814: Input Parameter:
815: . ctx - pointer to user-provided data
817: Level: advanced
819: .seealso: PetscContainerDestroy(), PetscContainterSetUserDestroy()
820: @*/
821: PetscErrorCode PetscContainerUserDestroyDefault(void* ctx)
822: {
827: PetscFree(ctx);
828: return(0);
829: }
831: /*@C
832: PetscContainerGetPointer - Gets the pointer value contained in the container.
834: Not Collective
836: Input Parameter:
837: . obj - the object created with PetscContainerCreate()
839: Output Parameter:
840: . ptr - the pointer value
842: Level: advanced
844: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
845: PetscContainerSetPointer()
846: @*/
847: PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr)
848: {
852: *ptr = obj->ptr;
853: return(0);
854: }
857: /*@C
858: PetscContainerSetPointer - Sets the pointer value contained in the container.
860: Logically Collective on PetscContainer
862: Input Parameters:
863: + obj - the object created with PetscContainerCreate()
864: - ptr - the pointer value
866: Level: advanced
868: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
869: PetscContainerGetPointer()
870: @*/
871: PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr)
872: {
876: obj->ptr = ptr;
877: return(0);
878: }
880: /*@C
881: PetscContainerDestroy - Destroys a PETSc container object.
883: Collective on PetscContainer
885: Input Parameter:
886: . obj - an object that was created with PetscContainerCreate()
888: Level: advanced
890: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
891: @*/
892: PetscErrorCode PetscContainerDestroy(PetscContainer *obj)
893: {
897: if (!*obj) return(0);
899: if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; return(0);}
900: if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
901: PetscHeaderDestroy(obj);
902: return(0);
903: }
905: /*@C
906: PetscContainerSetUserDestroy - Sets name of the user destroy function.
908: Logically Collective on PetscContainer
910: Input Parameter:
911: + obj - an object that was created with PetscContainerCreate()
912: - des - name of the user destroy function
914: Notes:
915: Use PetscContainerUserDestroyDefault() if the memory was obtained by calling PetscMalloc or one of its variants for single memory allocation.
917: Level: advanced
919: .seealso: PetscContainerDestroy(), PetscContainerUserDestroyDefault(), PetscMalloc(), PetscMalloc1(), PetscCalloc(), PetscCalloc1()
920: @*/
921: PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
922: {
925: obj->userdestroy = des;
926: return(0);
927: }
929: PetscClassId PETSC_CONTAINER_CLASSID;
931: /*@C
932: PetscContainerCreate - Creates a PETSc object that has room to hold
933: a single pointer. This allows one to attach any type of data (accessible
934: through a pointer) with the PetscObjectCompose() function to a PetscObject.
935: The data item itself is attached by a call to PetscContainerSetPointer().
937: Collective on MPI_Comm
939: Input Parameters:
940: . comm - MPI communicator that shares the object
942: Output Parameters:
943: . container - the container created
945: Level: advanced
947: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
948: @*/
949: PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
950: {
952: PetscContainer contain;
956: PetscSysInitializePackage();
957: PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);
958: *container = contain;
959: return(0);
960: }
962: /*@
963: PetscObjectSetFromOptions - Sets generic parameters from user options.
965: Collective on obj
967: Input Parameter:
968: . obj - the PetscObjcet
970: Options Database Keys:
972: Notes:
973: We have no generic options at present, so this does nothing
975: Level: beginner
977: .keywords: set, options, database
978: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
979: @*/
980: PetscErrorCode PetscObjectSetFromOptions(PetscObject obj)
981: {
984: return(0);
985: }
987: /*@
988: PetscObjectSetUp - Sets up the internal data structures for the later use.
990: Collective on PetscObject
992: Input Parameters:
993: . obj - the PetscObject
995: Notes:
996: This does nothing at present.
998: Level: advanced
1000: .keywords: setup
1001: .seealso: PetscObjectDestroy()
1002: @*/
1003: PetscErrorCode PetscObjectSetUp(PetscObject obj)
1004: {
1007: return(0);
1008: }