Actual source code: inherit.c
petsc-3.14.6 2021-03-30
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 Parameter:
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 Arguments:
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 Arguments:
239: + obj - object on which to get callback
240: . cbtype - callback type
241: - cid - address of callback Id
243: Output Arguments:
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 Parameter:
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>
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 Parameter:
375: . obj - the object or null if there is no object
377: Level: advanced
379: @*/
380: PetscErrorCode PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
381: {
383: PetscInt i;
384: PetscObject h;
385: PetscBool flg;
388: *obj = NULL;
389: for (i=0; i<PetscObjectsMaxCounts; i++) {
390: if ((h = PetscObjects[i])) {
391: PetscObjectName(h);
392: PetscStrcmp(h->name,name,&flg);
393: if (flg) {
394: *obj = h;
395: if (classname) *classname = h->class_name;
396: return(0);
397: }
398: }
399: }
400: return(0);
401: }
402: #endif
404: /*@
405: PetscObjectSetPrintedOptions - indicate to an object that it should behave as if it has already printed the help for its options
407: Input Parameters:
408: . obj - the PetscObject
410: Level: developer
412: Developer Notes:
413: This is used, for example to prevent sequential objects that are created from a parallel object; such as the KSP created by
414: PCBJACOBI from all printing the same help messages to the screen
416: .seealso: PetscOptionsInsert()
417: @*/
418: PetscErrorCode PetscObjectSetPrintedOptions(PetscObject obj)
419: {
421: obj->optionsprinted = PETSC_TRUE;
422: return(0);
423: }
425: /*@
426: 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.
428: Input Parameters:
429: + pobj - the parent object
430: - obj - the PetscObject
432: Level: developer
434: Developer Notes:
435: This is used, for example to prevent sequential objects that are created from a parallel object; such as the KSP created by
436: PCBJACOBI from all printing the same help messages to the screen
438: This will not handle more complicated situations like with GASM where children may live on any subset of the parent's processes and overlap
440: .seealso: PetscOptionsInsert(), PetscObjectSetPrintedOptions()
441: @*/
442: PetscErrorCode PetscObjectInheritPrintedOptions(PetscObject pobj,PetscObject obj)
443: {
445: PetscMPIInt prank,size;
448: MPI_Comm_rank(pobj->comm,&prank);
449: MPI_Comm_size(obj->comm,&size);
450: if (size == 1 && prank > 0) obj->optionsprinted = PETSC_TRUE;
451: return(0);
452: }
454: /*@C
455: PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
457: Not Collective
459: Input Parameter:
460: + obj - the PETSc object
461: . handle - function that checks for options
462: . destroy - function to destroy context if provided
463: - ctx - optional context for check function
465: 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
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
520: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
522: @*/
523: PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj)
524: {
525: PetscInt i;
530: for (i=0; i<obj->noptionhandler; i++) {
531: if (obj->optiondestroy[i]) {
532: (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
533: }
534: }
535: obj->noptionhandler = 0;
536: return(0);
537: }
540: /*@C
541: PetscObjectReference - Indicates to any PetscObject that it is being
542: referenced by another PetscObject. This increases the reference
543: count for that object by one.
545: Logically Collective on PetscObject
547: Input Parameter:
548: . obj - the PETSc object. This must be cast with (PetscObject), for example,
549: PetscObjectReference((PetscObject)mat);
551: Level: advanced
553: .seealso: PetscObjectCompose(), PetscObjectDereference()
554: @*/
555: PetscErrorCode PetscObjectReference(PetscObject obj)
556: {
558: if (!obj) return(0);
560: obj->refct++;
561: return(0);
562: }
564: /*@C
565: PetscObjectGetReference - Gets the current reference count for
566: any PETSc object.
568: Not Collective
570: Input Parameter:
571: . obj - the PETSc object; this must be cast with (PetscObject), for example,
572: PetscObjectGetReference((PetscObject)mat,&cnt);
574: Output Parameter:
575: . cnt - the reference count
577: Level: advanced
579: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
580: @*/
581: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
582: {
586: *cnt = obj->refct;
587: return(0);
588: }
590: /*@C
591: PetscObjectDereference - Indicates to any PetscObject that it is being
592: referenced by one less PetscObject. This decreases the reference
593: count for that object by one.
595: Collective on PetscObject if reference reaches 0 otherwise Logically Collective
597: Input Parameter:
598: . obj - the PETSc object; this must be cast with (PetscObject), for example,
599: PetscObjectDereference((PetscObject)mat);
601: Notes:
602: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not.
604: Level: advanced
606: .seealso: PetscObjectCompose(), PetscObjectReference()
607: @*/
608: PetscErrorCode PetscObjectDereference(PetscObject obj)
609: {
613: if (!obj) return(0);
615: if (obj->bops->destroy) {
616: (*obj->bops->destroy)(&obj);
617: } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
618: return(0);
619: }
621: /* ----------------------------------------------------------------------- */
622: /*
623: The following routines are the versions private to the PETSc object
624: data structures.
625: */
626: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
627: {
630: *comm = obj->comm;
631: return(0);
632: }
634: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
635: {
640: PetscObjectListRemoveReference(&obj->olist,name);
641: return(0);
642: }
644: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
645: {
647: char *tname;
648: PetscBool skipreference;
651: if (ptr) {
652: PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
653: if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
654: }
655: PetscObjectListAdd(&obj->olist,name,ptr);
656: return(0);
657: }
659: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
660: {
665: PetscObjectListFind(obj->olist,name,ptr);
666: return(0);
667: }
669: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
670: {
675: PetscFunctionListAdd(&obj->qlist,name,ptr);
676: return(0);
677: }
679: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
680: {
685: PetscFunctionListFind(obj->qlist,name,ptr);
686: return(0);
687: }
689: /*@C
690: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
692: Not Collective
694: Input Parameters:
695: + obj - the PETSc object; this must be cast with (PetscObject), for example,
696: PetscObjectCompose((PetscObject)mat,...);
697: . name - name associated with the child object
698: - ptr - the other PETSc object to associate with the PETSc object; this must also be
699: cast with (PetscObject)
701: Level: advanced
703: Notes:
704: The second objects reference count is automatically increased by one when it is
705: composed.
707: Replaces any previous object that had the same name.
709: If ptr is null and name has previously been composed using an object, then that
710: entry is removed from the obj.
712: PetscObjectCompose() can be used with any PETSc object (such as
713: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
714: PetscContainerCreate() for info on how to create an object from a
715: user-provided pointer that may then be composed with PETSc objects.
718: .seealso: PetscObjectQuery(), PetscContainerCreate(), PetscObjectComposeFunction(), PetscObjectQueryFunction()
719: @*/
720: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
721: {
728: if (obj == ptr) SETERRQ(PetscObjectComm((PetscObject)obj),PETSC_ERR_SUP,"Cannot compose object with itself");
729: (*obj->bops->compose)(obj,name,ptr);
730: return(0);
731: }
733: /*@C
734: PetscObjectQuery - Gets a PETSc object associated with a given object.
736: Not Collective
738: Input Parameters:
739: + obj - the PETSc object
740: Thus must be cast with a (PetscObject), for example,
741: PetscObjectCompose((PetscObject)mat,...);
742: . name - name associated with child object
743: - ptr - the other PETSc object associated with the PETSc object, this must be
744: cast with (PetscObject*)
746: Level: advanced
748: The reference count of neither object is increased in this call
751: .seealso: PetscObjectCompose(), PetscObjectComposeFunction(), PetscObjectQueryFunction()
752: @*/
753: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
754: {
761: (*obj->bops->query)(obj,name,ptr);
762: return(0);
763: }
765: /*MC
766: PetscObjectComposeFunction - Associates a function with a given PETSc object.
768: Synopsis:
769: #include <petscsys.h>
770: PetscErrorCode PetscObjectComposeFunction(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 a (PetscObject), for example,
776: PetscObjectCompose((PetscObject)mat,...);
777: . name - name associated with the child function
778: . fname - name of the function
779: - fptr - function pointer
781: Level: advanced
783: Notes:
784: To remove a registered routine, pass in NULL for fptr().
786: PetscObjectComposeFunction() can be used with any PETSc object (such as
787: Mat, Vec, KSP, SNES, etc.) or any user-provided object.
789: .seealso: PetscObjectQueryFunction(), PetscContainerCreate() PetscObjectCompose(), PetscObjectQuery()
790: M*/
792: PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
793: {
799: (*obj->bops->composefunction)(obj,name,fptr);
800: return(0);
801: }
803: /*MC
804: PetscObjectQueryFunction - Gets a function associated with a given object.
806: Synopsis:
807: #include <petscsys.h>
808: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))
810: Logically Collective on PetscObject
812: Input Parameters:
813: + obj - the PETSc object; this must be cast with (PetscObject), for example,
814: PetscObjectQueryFunction((PetscObject)ksp,...);
815: - name - name associated with the child function
817: Output Parameter:
818: . fptr - function pointer
820: Level: advanced
822: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind(), PetscObjectCompose(), PetscObjectQuery()
823: M*/
824: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
825: {
831: (*obj->bops->queryfunction)(obj,name,ptr);
832: return(0);
833: }
835: struct _p_PetscContainer {
836: PETSCHEADER(int);
837: void *ptr;
838: PetscErrorCode (*userdestroy)(void*);
839: };
841: /*@C
842: PetscContainerUserDestroyDefault - Default destroy routine for user-provided data that simply calls PetscFree().
844: Logically Collective on PetscContainer
846: Input Parameter:
847: . ctx - pointer to user-provided data
849: Level: advanced
851: .seealso: PetscContainerDestroy(), PetscContainterSetUserDestroy()
852: @*/
853: PetscErrorCode PetscContainerUserDestroyDefault(void* ctx)
854: {
858: PetscFree(ctx);
859: return(0);
860: }
862: /*@C
863: PetscContainerGetPointer - Gets the pointer value contained in the container.
865: Not Collective
867: Input Parameter:
868: . obj - the object created with PetscContainerCreate()
870: Output Parameter:
871: . ptr - the pointer value
873: Level: advanced
875: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
876: PetscContainerSetPointer()
877: @*/
878: PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr)
879: {
883: *ptr = obj->ptr;
884: return(0);
885: }
888: /*@C
889: PetscContainerSetPointer - Sets the pointer value contained in the container.
891: Logically Collective on PetscContainer
893: Input Parameters:
894: + obj - the object created with PetscContainerCreate()
895: - ptr - the pointer value
897: Level: advanced
899: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
900: PetscContainerGetPointer()
901: @*/
902: PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr)
903: {
907: obj->ptr = ptr;
908: return(0);
909: }
911: /*@C
912: PetscContainerDestroy - Destroys a PETSc container object.
914: Collective on PetscContainer
916: Input Parameter:
917: . obj - an object that was created with PetscContainerCreate()
919: Level: advanced
921: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
922: @*/
923: PetscErrorCode PetscContainerDestroy(PetscContainer *obj)
924: {
928: if (!*obj) return(0);
930: if (--((PetscObject)(*obj))->refct > 0) {*obj = NULL; return(0);}
931: if ((*obj)->userdestroy) { (*(*obj)->userdestroy)((*obj)->ptr); }
932: PetscHeaderDestroy(obj);
933: return(0);
934: }
936: /*@C
937: PetscContainerSetUserDestroy - Sets name of the user destroy function.
939: Logically Collective on PetscContainer
941: Input Parameter:
942: + obj - an object that was created with PetscContainerCreate()
943: - des - name of the user destroy function
945: Notes:
946: Use PetscContainerUserDestroyDefault() if the memory was obtained by calling PetscMalloc or one of its variants for single memory allocation.
948: Level: advanced
950: .seealso: PetscContainerDestroy(), PetscContainerUserDestroyDefault(), PetscMalloc(), PetscMalloc1(), PetscCalloc(), PetscCalloc1()
951: @*/
952: PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
953: {
956: obj->userdestroy = des;
957: return(0);
958: }
960: PetscClassId PETSC_CONTAINER_CLASSID;
962: /*@C
963: PetscContainerCreate - Creates a PETSc object that has room to hold
964: a single pointer. This allows one to attach any type of data (accessible
965: through a pointer) with the PetscObjectCompose() function to a PetscObject.
966: The data item itself is attached by a call to PetscContainerSetPointer().
968: Collective
970: Input Parameters:
971: . comm - MPI communicator that shares the object
973: Output Parameters:
974: . container - the container created
976: Level: advanced
978: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer(), PetscObjectCompose(), PetscObjectQuery()
979: @*/
980: PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
981: {
983: PetscContainer contain;
987: PetscSysInitializePackage();
988: PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);
989: *container = contain;
990: return(0);
991: }
993: /*@
994: PetscObjectSetFromOptions - Sets generic parameters from user options.
996: Collective on obj
998: Input Parameter:
999: . obj - the PetscObjcet
1001: Options Database Keys:
1003: Notes:
1004: We have no generic options at present, so this does nothing
1006: Level: beginner
1008: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
1009: @*/
1010: PetscErrorCode PetscObjectSetFromOptions(PetscObject obj)
1011: {
1014: return(0);
1015: }
1017: /*@
1018: PetscObjectSetUp - Sets up the internal data structures for the later use.
1020: Collective on PetscObject
1022: Input Parameters:
1023: . obj - the PetscObject
1025: Notes:
1026: This does nothing at present.
1028: Level: advanced
1030: .seealso: PetscObjectDestroy()
1031: @*/
1032: PetscErrorCode PetscObjectSetUp(PetscObject obj)
1033: {
1036: return(0);
1037: }