Actual source code: inherit.c
petsc-3.12.5 2020-03-29
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: PetscCalloc1(newPetscObjectsMaxCounts,&newPetscObjects);
80: PetscArraycpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts);
81: PetscFree(PetscObjects);
83: PetscObjects = newPetscObjects;
84: PetscObjects[PetscObjectsMaxCounts] = h;
85: PetscObjectsMaxCounts = newPetscObjectsMaxCounts;
86: }
87: #endif
88: return(0);
89: }
91: PETSC_INTERN PetscBool PetscMemoryCollectMaximumUsage;
92: PETSC_INTERN PetscLogDouble PetscMemoryMaximumUsage;
94: /*
95: PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
96: the macro PetscHeaderDestroy().
97: */
98: PetscErrorCode PetscHeaderDestroy_Private(PetscObject h)
99: {
104: PetscLogObjectDestroy(h);
105: PetscComposedQuantitiesDestroy(h);
106: if (PetscMemoryCollectMaximumUsage) {
107: PetscLogDouble usage;
108: PetscMemoryGetCurrentUsage(&usage);
109: if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
110: }
111: /* first destroy things that could execute arbitrary code */
112: if (h->python_destroy) {
113: void *python_context = h->python_context;
114: PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
115: h->python_context = 0;
116: h->python_destroy = 0;
118: (*python_destroy)(python_context);
119: }
120: PetscObjectDestroyOptionsHandlers(h);
121: PetscObjectListDestroy(&h->olist);
122: PetscCommDestroy(&h->comm);
123: /* next destroy other things */
124: h->classid = PETSCFREEDHEADER;
126: PetscFunctionListDestroy(&h->qlist);
127: PetscFree(h->type_name);
128: PetscFree(h->name);
129: PetscFree(h->prefix);
130: PetscFree(h->fortran_func_pointers);
131: PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_CLASS]);
132: PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
134: #if defined(PETSC_USE_LOG)
135: if (PetscObjectsLog) {
136: PetscInt i;
137: /* Record object removal from list of all objects */
138: for (i=0; i<PetscObjectsMaxCounts; i++) {
139: if (PetscObjects[i] == h) {
140: PetscObjects[i] = 0;
141: PetscObjectsCounts--;
142: break;
143: }
144: }
145: if (!PetscObjectsCounts) {
146: PetscFree(PetscObjects);
147: PetscObjectsMaxCounts = 0;
148: }
149: }
150: #endif
151: return(0);
152: }
154: /*@C
155: PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object
157: Logically Collective on PetscObject
159: Input Parameter:
160: + src - source object
161: - dest - destination object
163: Level: developer
165: Note:
166: Both objects must have the same class.
167: @*/
168: PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest)
169: {
171: PetscInt cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE];
176: if (src->classid != dest->classid) SETERRQ(src->comm,PETSC_ERR_ARG_INCOMP,"Objects must be of the same class");
178: PetscFree(dest->fortran_func_pointers);
179: PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);
180: PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));
182: dest->num_fortran_func_pointers = src->num_fortran_func_pointers;
184: PetscFortranCallbackGetSizes(src->classid,&numcb[PETSC_FORTRAN_CALLBACK_CLASS],&numcb[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
185: for (cbtype=PETSC_FORTRAN_CALLBACK_CLASS; cbtype<PETSC_FORTRAN_CALLBACK_MAXTYPE; cbtype++) {
186: PetscFree(dest->fortrancallback[cbtype]);
187: PetscCalloc1(numcb[cbtype],&dest->fortrancallback[cbtype]);
188: PetscMemcpy(dest->fortrancallback[cbtype],src->fortrancallback[cbtype],src->num_fortrancallback[cbtype]*sizeof(PetscFortranCallback));
189: dest->num_fortrancallback[cbtype] = src->num_fortrancallback[cbtype];
190: }
191: return(0);
192: }
194: /*@C
195: PetscObjectSetFortranCallback - set fortran callback function pointer and context
197: Logically Collective
199: Input Arguments:
200: + obj - object on which to set callback
201: . cbtype - callback type (class or subtype)
202: . cid - address of callback Id, updated if not yet initialized (zero)
203: . func - Fortran function
204: - ctx - Fortran context
206: Level: developer
208: .seealso: PetscObjectGetFortranCallback()
209: @*/
210: PetscErrorCode PetscObjectSetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId *cid,void (*func)(void),void *ctx)
211: {
213: const char *subtype = NULL;
217: if (cbtype == PETSC_FORTRAN_CALLBACK_SUBTYPE) subtype = obj->type_name;
218: if (!*cid) {PetscFortranCallbackRegister(obj->classid,subtype,cid);}
219: if (*cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype]) {
220: PetscInt oldnum = obj->num_fortrancallback[cbtype],newnum = PetscMax(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 Arguments:
240: + obj - object on which to get callback
241: . cbtype - callback type
242: - cid - address of callback Id
244: Output Arguments:
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 Parameter:
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>
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 = 0;
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 Parameter:
376: . obj - the object or null if there is no object
378: Level: advanced
380: @*/
381: PetscErrorCode PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
382: {
384: PetscInt i;
385: PetscObject h;
386: PetscBool flg;
389: *obj = NULL;
390: for (i=0; i<PetscObjectsMaxCounts; i++) {
391: if ((h = PetscObjects[i])) {
392: PetscObjectName(h);
393: PetscStrcmp(h->name,name,&flg);
394: if (flg) {
395: *obj = h;
396: if (classname) *classname = h->class_name;
397: return(0);
398: }
399: }
400: }
401: return(0);
402: }
403: #endif
405: /*@
406: PetscObjectSetPrintedOptions - indicate to an object that it should behave as if it has already printed the help for its options
408: Input Parameters:
409: . obj - the PetscObject
411: Level: developer
413: Developer Notes:
414: This is used, for example to prevent sequential objects that are created from a parallel object; such as the KSP created by
415: PCBJACOBI from all printing the same help messages to the screen
417: .seealso: PetscOptionsInsert()
418: @*/
419: PetscErrorCode PetscObjectSetPrintedOptions(PetscObject obj)
420: {
422: obj->optionsprinted = PETSC_TRUE;
423: return(0);
424: }
426: /*@
427: PetscObjectInheritPrintedOptions - If the child object is not on the rank 0 process of the parent object and the child is sequential then the child gets it set.
429: Input Parameters:
430: + pobj - the parent object
431: - obj - the PetscObject
433: Level: developer
435: Developer Notes:
436: This is used, for example to prevent sequential objects that are created from a parallel object; such as the KSP created by
437: PCBJACOBI from all printing the same help messages to the screen
439: This will not handle more complicated situations like with GASM where children may live on any subset of the parent's processes and overlap
441: .seealso: PetscOptionsInsert(), PetscObjectSetPrintedOptions()
442: @*/
443: PetscErrorCode PetscObjectInheritPrintedOptions(PetscObject pobj,PetscObject obj)
444: {
446: PetscMPIInt prank,size;
449: MPI_Comm_rank(pobj->comm,&prank);
450: MPI_Comm_size(obj->comm,&size);
451: if (size == 1 && prank > 0) obj->optionsprinted = PETSC_TRUE;
452: return(0);
453: }
455: /*@C
456: PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
458: Not Collective
460: Input Parameter:
461: + obj - the PETSc object
462: . handle - function that checks for options
463: . destroy - function to destroy context if provided
464: - ctx - optional context for check function
466: Level: developer
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
494: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()
496: @*/
497: PetscErrorCode PetscObjectProcessOptionsHandlers(PetscOptionItems *PetscOptionsObject,PetscObject obj)
498: {
499: PetscInt i;
504: for (i=0; i<obj->noptionhandler; i++) {
505: (*obj->optionhandler[i])(PetscOptionsObject,obj,obj->optionctx[i]);
506: }
507: return(0);
508: }
510: /*@C
511: PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object
513: Not Collective
515: Input Parameter:
516: . obj - the PETSc object
518: Level: developer
521: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
523: @*/
524: PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj)
525: {
526: PetscInt i;
531: for (i=0; i<obj->noptionhandler; i++) {
532: if (obj->optiondestroy[i]) {
533: (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
534: }
535: }
536: obj->noptionhandler = 0;
537: return(0);
538: }
541: /*@C
542: PetscObjectReference - Indicates to any PetscObject that it is being
543: referenced by another PetscObject. This increases the reference
544: count for that object by one.
546: Logically Collective on PetscObject
548: Input Parameter:
549: . obj - the PETSc object. This must be cast with (PetscObject), for example,
550: PetscObjectReference((PetscObject)mat);
552: Level: advanced
554: .seealso: PetscObjectCompose(), PetscObjectDereference()
555: @*/
556: PetscErrorCode PetscObjectReference(PetscObject obj)
557: {
559: if (!obj) return(0);
561: obj->refct++;
562: return(0);
563: }
565: /*@C
566: PetscObjectGetReference - Gets the current reference count for
567: any PETSc object.
569: Not Collective
571: Input Parameter:
572: . obj - the PETSc object; this must be cast with (PetscObject), for example,
573: PetscObjectGetReference((PetscObject)mat,&cnt);
575: Output Parameter:
576: . cnt - the reference count
578: Level: advanced
580: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
581: @*/
582: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
583: {
587: *cnt = obj->refct;
588: return(0);
589: }
591: /*@C
592: PetscObjectDereference - Indicates to any PetscObject that it is being
593: referenced by one less PetscObject. This decreases the reference
594: count for that object by one.
596: Collective on PetscObject if reference reaches 0 otherwise Logically Collective
598: Input Parameter:
599: . obj - the PETSc object; this must be cast with (PetscObject), for example,
600: PetscObjectDereference((PetscObject)mat);
602: Notes:
603: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not.
605: Level: advanced
607: .seealso: PetscObjectCompose(), PetscObjectReference()
608: @*/
609: PetscErrorCode PetscObjectDereference(PetscObject obj)
610: {
614: if (!obj) return(0);
616: if (obj->bops->destroy) {
617: (*obj->bops->destroy)(&obj);
618: } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
619: return(0);
620: }
622: /* ----------------------------------------------------------------------- */
623: /*
624: The following routines are the versions private to the PETSc object
625: data structures.
626: */
627: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
628: {
631: *comm = obj->comm;
632: return(0);
633: }
635: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
636: {
641: PetscObjectListRemoveReference(&obj->olist,name);
642: return(0);
643: }
645: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
646: {
648: char *tname;
649: PetscBool skipreference;
652: if (ptr) {
653: PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
654: if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
655: }
656: PetscObjectListAdd(&obj->olist,name,ptr);
657: return(0);
658: }
660: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
661: {
666: PetscObjectListFind(obj->olist,name,ptr);
667: return(0);
668: }
670: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
671: {
676: PetscFunctionListAdd(&obj->qlist,name,ptr);
677: return(0);
678: }
680: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
681: {
686: PetscFunctionListFind(obj->qlist,name,ptr);
687: return(0);
688: }
690: /*@C
691: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
693: Not Collective
695: Input Parameters:
696: + obj - the PETSc object; this must be cast with (PetscObject), for example,
697: PetscObjectCompose((PetscObject)mat,...);
698: . name - name associated with the child object
699: - ptr - the other PETSc object to associate with the PETSc object; this must also be
700: cast with (PetscObject)
702: Level: advanced
704: Notes:
705: The second objects reference count is automatically increased by one when it is
706: composed.
708: Replaces any previous object that had the same name.
710: If ptr is null and name has previously been composed using an object, then that
711: entry is removed from the obj.
713: PetscObjectCompose() can be used with any PETSc object (such as
714: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
715: PetscContainerCreate() for info on how to create an object from a
716: user-provided pointer that may then be composed with PETSc objects.
719: .seealso: PetscObjectQuery(), PetscContainerCreate()
720: @*/
721: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
722: {
729: if (obj == ptr) SETERRQ(PetscObjectComm((PetscObject)obj),PETSC_ERR_SUP,"Cannot compose object with itself");
730: (*obj->bops->compose)(obj,name,ptr);
731: return(0);
732: }
734: /*@C
735: PetscObjectQuery - Gets a PETSc object associated with a given object.
737: Not Collective
739: Input Parameters:
740: + obj - the PETSc object
741: Thus must be cast with a (PetscObject), for example,
742: PetscObjectCompose((PetscObject)mat,...);
743: . name - name associated with child object
744: - ptr - the other PETSc object associated with the PETSc object, this must be
745: cast with (PetscObject*)
747: Level: advanced
749: The reference count of neither object is increased in this call
752: .seealso: PetscObjectCompose()
753: @*/
754: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
755: {
762: (*obj->bops->query)(obj,name,ptr);
763: return(0);
764: }
766: /*MC
767: PetscObjectComposeFunction - Associates a function with a given PETSc object.
769: Synopsis:
770: #include <petscsys.h>
771: PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))
773: Logically Collective on PetscObject
775: Input Parameters:
776: + obj - the PETSc object; this must be cast with a (PetscObject), for example,
777: PetscObjectCompose((PetscObject)mat,...);
778: . name - name associated with the child function
779: . fname - name of the function
780: - fptr - function pointer
782: Level: advanced
784: Notes:
785: To remove a registered routine, pass in NULL for fptr().
787: PetscObjectComposeFunction() can be used with any PETSc object (such as
788: Mat, Vec, KSP, SNES, etc.) or any user-provided object.
790: .seealso: PetscObjectQueryFunction(), PetscContainerCreate()
791: M*/
793: PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
794: {
800: (*obj->bops->composefunction)(obj,name,fptr);
801: return(0);
802: }
804: /*MC
805: PetscObjectQueryFunction - Gets a function associated with a given object.
807: Synopsis:
808: #include <petscsys.h>
809: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))
811: Logically Collective on PetscObject
813: Input Parameters:
814: + obj - the PETSc object; this must be cast with (PetscObject), for example,
815: PetscObjectQueryFunction((PetscObject)ksp,...);
816: - name - name associated with the child function
818: Output Parameter:
819: . fptr - function pointer
821: Level: advanced
823: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind()
824: M*/
825: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
826: {
832: (*obj->bops->queryfunction)(obj,name,ptr);
833: return(0);
834: }
836: struct _p_PetscContainer {
837: PETSCHEADER(int);
838: void *ptr;
839: PetscErrorCode (*userdestroy)(void*);
840: };
842: /*@C
843: PetscContainerUserDestroyDefault - Default destroy routine for user-provided data that simply calls PetscFree().
845: Logically Collective on PetscContainer
847: Input Parameter:
848: . ctx - pointer to user-provided data
850: Level: advanced
852: .seealso: PetscContainerDestroy(), PetscContainterSetUserDestroy()
853: @*/
854: PetscErrorCode PetscContainerUserDestroyDefault(void* ctx)
855: {
859: PetscFree(ctx);
860: return(0);
861: }
863: /*@C
864: PetscContainerGetPointer - Gets the pointer value contained in the container.
866: Not Collective
868: Input Parameter:
869: . obj - the object created with PetscContainerCreate()
871: Output Parameter:
872: . ptr - the pointer value
874: Level: advanced
876: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
877: PetscContainerSetPointer()
878: @*/
879: PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr)
880: {
884: *ptr = obj->ptr;
885: return(0);
886: }
889: /*@C
890: PetscContainerSetPointer - Sets the pointer value contained in the container.
892: Logically Collective on PetscContainer
894: Input Parameters:
895: + obj - the object created with PetscContainerCreate()
896: - ptr - the pointer value
898: Level: advanced
900: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
901: PetscContainerGetPointer()
902: @*/
903: PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr)
904: {
908: obj->ptr = ptr;
909: return(0);
910: }
912: /*@C
913: PetscContainerDestroy - Destroys a PETSc container object.
915: Collective on PetscContainer
917: Input Parameter:
918: . obj - an object that was created with PetscContainerCreate()
920: Level: advanced
922: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
923: @*/
924: PetscErrorCode PetscContainerDestroy(PetscContainer *obj)
925: {
929: if (!*obj) return(0);
931: if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; return(0);}
932: if ((*obj)->userdestroy) { (*(*obj)->userdestroy)((*obj)->ptr); }
933: PetscHeaderDestroy(obj);
934: return(0);
935: }
937: /*@C
938: PetscContainerSetUserDestroy - Sets name of the user destroy function.
940: Logically Collective on PetscContainer
942: Input Parameter:
943: + obj - an object that was created with PetscContainerCreate()
944: - des - name of the user destroy function
946: Notes:
947: Use PetscContainerUserDestroyDefault() if the memory was obtained by calling PetscMalloc or one of its variants for single memory allocation.
949: Level: advanced
951: .seealso: PetscContainerDestroy(), PetscContainerUserDestroyDefault(), PetscMalloc(), PetscMalloc1(), PetscCalloc(), PetscCalloc1()
952: @*/
953: PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
954: {
957: obj->userdestroy = des;
958: return(0);
959: }
961: PetscClassId PETSC_CONTAINER_CLASSID;
963: /*@C
964: PetscContainerCreate - Creates a PETSc object that has room to hold
965: a single pointer. This allows one to attach any type of data (accessible
966: through a pointer) with the PetscObjectCompose() function to a PetscObject.
967: The data item itself is attached by a call to PetscContainerSetPointer().
969: Collective
971: Input Parameters:
972: . comm - MPI communicator that shares the object
974: Output Parameters:
975: . container - the container created
977: Level: advanced
979: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
980: @*/
981: PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
982: {
984: PetscContainer contain;
988: PetscSysInitializePackage();
989: PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);
990: *container = contain;
991: return(0);
992: }
994: /*@
995: PetscObjectSetFromOptions - Sets generic parameters from user options.
997: Collective on obj
999: Input Parameter:
1000: . obj - the PetscObjcet
1002: Options Database Keys:
1004: Notes:
1005: We have no generic options at present, so this does nothing
1007: Level: beginner
1009: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
1010: @*/
1011: PetscErrorCode PetscObjectSetFromOptions(PetscObject obj)
1012: {
1015: return(0);
1016: }
1018: /*@
1019: PetscObjectSetUp - Sets up the internal data structures for the later use.
1021: Collective on PetscObject
1023: Input Parameters:
1024: . obj - the PetscObject
1026: Notes:
1027: This does nothing at present.
1029: Level: advanced
1031: .seealso: PetscObjectDestroy()
1032: @*/
1033: PetscErrorCode PetscObjectSetUp(PetscObject obj)
1034: {
1037: return(0);
1038: }