Actual source code: inherit.c
petsc-3.5.0 2014-06-30
2: /*
3: Provides utility routines for manipulating any type of PETSc object.
4: */
5: #include <petsc-private/petscimpl.h> /*I "petscsys.h" I*/
6: #include <petscviewer.h>
8: #if defined(PETSC_USE_LOG)
9: PetscObject *PetscObjects = 0;
10: PetscInt PetscObjectsCounts = 0, PetscObjectsMaxCounts = 0;
11: #endif
13: extern PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm*);
14: extern PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject);
15: extern PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject*);
16: extern PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],void (*)(void));
17: extern PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void));
21: /*
22: PetscHeaderCreate_Private - Creates a base PETSc object header and fills
23: in the default values. Called by the macro PetscHeaderCreate().
24: */
25: PetscErrorCode PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,const char class_name[],const char descr[],const char mansec[],
26: MPI_Comm comm,PetscErrorCode (*des)(PetscObject*),PetscErrorCode (*vie)(PetscObject,PetscViewer))
27: {
28: static PetscInt idcnt = 1;
29: PetscErrorCode ierr;
30: #if defined(PETSC_USE_LOG)
31: PetscObject *newPetscObjects;
32: PetscInt newPetscObjectsMaxCounts,i;
33: #endif
36: h->classid = classid;
37: h->type = 0;
38: h->class_name = (char*)class_name;
39: h->description = (char*)descr;
40: h->mansec = (char*)mansec;
41: h->prefix = 0;
42: h->refct = 1;
43: #if defined(PETSC_HAVE_SAWS)
44: h->amsmem = PETSC_FALSE;
45: #endif
46: h->id = idcnt++;
47: h->parentid = 0;
48: h->qlist = 0;
49: h->olist = 0;
50: h->precision = (PetscPrecision) sizeof(PetscReal);
51: h->bops->destroy = des;
52: h->bops->view = vie;
53: h->bops->getcomm = PetscObjectGetComm_Petsc;
54: h->bops->compose = PetscObjectCompose_Petsc;
55: h->bops->query = PetscObjectQuery_Petsc;
56: h->bops->composefunction = PetscObjectComposeFunction_Petsc;
57: h->bops->queryfunction = PetscObjectQueryFunction_Petsc;
59: PetscCommDuplicate(comm,&h->comm,&h->tag);
61: #if defined(PETSC_USE_LOG)
62: /* Keep a record of object created */
63: PetscObjectsCounts++;
64: for (i=0; i<PetscObjectsMaxCounts; i++) {
65: if (!PetscObjects[i]) {
66: PetscObjects[i] = h;
67: return(0);
68: }
69: }
70: /* Need to increase the space for storing PETSc objects */
71: if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100;
72: else newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts;
73: PetscMalloc1(newPetscObjectsMaxCounts,&newPetscObjects);
74: PetscMemcpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts*sizeof(PetscObject));
75: PetscMemzero(newPetscObjects+PetscObjectsMaxCounts,(newPetscObjectsMaxCounts - PetscObjectsMaxCounts)*sizeof(PetscObject));
76: PetscFree(PetscObjects);
78: PetscObjects = newPetscObjects;
79: PetscObjects[PetscObjectsMaxCounts] = h;
80: PetscObjectsMaxCounts = newPetscObjectsMaxCounts;
81: #endif
82: return(0);
83: }
85: extern PetscBool PetscMemoryCollectMaximumUsage;
86: extern PetscLogDouble PetscMemoryMaximumUsage;
90: /*
91: PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
92: the macro PetscHeaderDestroy().
93: */
94: PetscErrorCode PetscHeaderDestroy_Private(PetscObject h)
95: {
100: PetscLogObjectDestroy(h);
101: PetscComposedQuantitiesDestroy(h);
102: if (PetscMemoryCollectMaximumUsage) {
103: PetscLogDouble usage;
104: PetscMemoryGetCurrentUsage(&usage);
105: if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
106: }
107: /* first destroy things that could execute arbitrary code */
108: if (h->python_destroy) {
109: void *python_context = h->python_context;
110: PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
111: h->python_context = 0;
112: h->python_destroy = 0;
114: (*python_destroy)(python_context);
115: }
116: PetscObjectDestroyOptionsHandlers(h);
117: PetscObjectListDestroy(&h->olist);
118: PetscCommDestroy(&h->comm);
119: /* next destroy other things */
120: h->classid = PETSCFREEDHEADER;
122: PetscFree(h->bops);
123: PetscFunctionListDestroy(&h->qlist);
124: PetscFree(h->type_name);
125: PetscFree(h->name);
126: PetscFree(h->prefix);
127: PetscFree(h->fortran_func_pointers);
128: PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_CLASS]);
129: PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
131: #if defined(PETSC_USE_LOG)
132: {
133: PetscInt i;
134: /* Record object removal from list of all objects */
135: for (i=0; i<PetscObjectsMaxCounts; i++) {
136: if (PetscObjects[i] == h) {
137: PetscObjects[i] = 0;
138: PetscObjectsCounts--;
139: break;
140: }
141: }
142: if (!PetscObjectsCounts) {
143: PetscFree(PetscObjects);
144: PetscObjectsMaxCounts = 0;
145: }
146: }
147: #endif
148: return(0);
149: }
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: }
189: return(0);
190: }
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: }
236: /*@C
237: PetscObjectGetFortranCallback - get fortran callback function pointer and context
239: Logically Collective
241: Input Arguments:
242: + obj - object on which to get callback
243: . cbtype - callback type
244: - cid - address of callback Id
246: Output Arguments:
247: + func - Fortran function (or NULL if not needed)
248: - ctx - Fortran context (or NULL if not needed)
250: Level: developer
252: .seealso: PetscObjectSetFortranCallback()
253: @*/
254: PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx)
255: {
256: PetscFortranCallback *cb;
260: if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid");
261: 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");
262: cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK];
263: if (func) *func = cb->func;
264: if (ctx) *ctx = cb->ctx;
265: return(0);
266: }
268: #if defined(PETSC_USE_LOG)
271: /*@C
272: PetscObjectsDump - Prints the currently existing objects.
274: Logically Collective on PetscViewer
276: Input Parameter:
277: + viewer - must be an PETSCVIEWERASCII viewer
278: - all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects
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)
346: /*@C
347: PetscObjectsView - Prints the currently existing objects.
349: Logically Collective on PetscViewer
351: Input Parameter:
352: . viewer - must be an PETSCVIEWERASCII viewer
354: Level: advanced
356: Concepts: options database^printing
358: @*/
359: PetscErrorCode PetscObjectsView(PetscViewer viewer)
360: {
362: PetscBool isascii;
363: FILE *fd;
366: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
367: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
368: if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
369: PetscViewerASCIIGetPointer(viewer,&fd);
370: PetscObjectsDump(fd,PETSC_TRUE);
371: return(0);
372: }
376: /*@C
377: PetscObjectsGetObject - Get a pointer to a named object
379: Not collective
381: Input Parameter:
382: . name - the name of an object
384: Output Parameter:
385: . obj - the object or null if there is no object
387: Level: advanced
389: Concepts: options database^printing
391: @*/
392: PetscErrorCode PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
393: {
395: PetscInt i;
396: PetscObject h;
397: PetscBool flg;
400: *obj = NULL;
401: for (i=0; i<PetscObjectsMaxCounts; i++) {
402: if ((h = PetscObjects[i])) {
403: PetscObjectName(h);
404: PetscStrcmp(h->name,name,&flg);
405: if (flg) {
406: *obj = h;
407: if (classname) *classname = h->class_name;
408: return(0);
409: }
410: }
411: }
412: return(0);
413: }
417: char *PetscObjectsGetObjectMatlab(const char* name,PetscObject *obj)
418: {
420: PetscInt i;
421: PetscObject h;
422: PetscBool flg;
425: *obj = NULL;
426: for (i=0; i<PetscObjectsMaxCounts; i++) {
427: if ((h = PetscObjects[i])) {
428: PetscObjectName(h);if (ierr) return(0);
429: PetscStrcmp(h->name,name,&flg);if (ierr) return(0);
430: if (flg) {
431: *obj = h;
432: PetscFunctionReturn(h->class_name);
433: }
434: }
435: }
436: return(0);
437: }
438: #endif
442: /*@C
443: PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.
445: Not Collective
447: Input Parameter:
448: + obj - the PETSc object
449: . handle - function that checks for options
450: . destroy - function to destroy context if provided
451: - ctx - optional context for check function
453: Level: developer
456: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()
458: @*/
459: PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
460: {
463: if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
464: obj->optionhandler[obj->noptionhandler] = handle;
465: obj->optiondestroy[obj->noptionhandler] = destroy;
466: obj->optionctx[obj->noptionhandler++] = ctx;
467: return(0);
468: }
472: /*@C
473: PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object
475: Not Collective
477: Input Parameter:
478: . obj - the PETSc object
480: Level: developer
483: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()
485: @*/
486: PetscErrorCode PetscObjectProcessOptionsHandlers(PetscObject obj)
487: {
488: PetscInt i;
493: for (i=0; i<obj->noptionhandler; i++) {
494: (*obj->optionhandler[i])(obj,obj->optionctx[i]);
495: }
496: return(0);
497: }
501: /*@C
502: PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object
504: Not Collective
506: Input Parameter:
507: . obj - the PETSc object
509: Level: developer
512: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()
514: @*/
515: PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj)
516: {
517: PetscInt i;
522: for (i=0; i<obj->noptionhandler; i++) {
523: if (obj->optiondestroy[i]) {
524: (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
525: }
526: }
527: obj->noptionhandler = 0;
528: return(0);
529: }
534: /*@
535: PetscObjectReference - Indicates to any PetscObject that it is being
536: referenced by another PetscObject. This increases the reference
537: count for that object by one.
539: Logically Collective on PetscObject
541: Input Parameter:
542: . obj - the PETSc object. This must be cast with (PetscObject), for example,
543: PetscObjectReference((PetscObject)mat);
545: Level: advanced
547: .seealso: PetscObjectCompose(), PetscObjectDereference()
548: @*/
549: PetscErrorCode PetscObjectReference(PetscObject obj)
550: {
552: if (!obj) return(0);
554: obj->refct++;
555: return(0);
556: }
560: /*@
561: PetscObjectGetReference - Gets the current reference count for
562: any PETSc object.
564: Not Collective
566: Input Parameter:
567: . obj - the PETSc object; this must be cast with (PetscObject), for example,
568: PetscObjectGetReference((PetscObject)mat,&cnt);
570: Output Parameter:
571: . cnt - the reference count
573: Level: advanced
575: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
576: @*/
577: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
578: {
582: *cnt = obj->refct;
583: return(0);
584: }
588: /*@
589: PetscObjectDereference - Indicates to any PetscObject that it is being
590: referenced by one less PetscObject. This decreases the reference
591: count for that object by one.
593: Collective on PetscObject if reference reaches 0 otherwise Logically Collective
595: Input Parameter:
596: . obj - the PETSc object; this must be cast with (PetscObject), for example,
597: PetscObjectDereference((PetscObject)mat);
599: Notes: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not.
601: Level: advanced
603: .seealso: PetscObjectCompose(), PetscObjectReference()
604: @*/
605: PetscErrorCode PetscObjectDereference(PetscObject obj)
606: {
610: if (!obj) return(0);
612: if (obj->bops->destroy) {
613: (*obj->bops->destroy)(&obj);
614: } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
615: return(0);
616: }
618: /* ----------------------------------------------------------------------- */
619: /*
620: The following routines are the versions private to the PETSc object
621: data structures.
622: */
625: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
626: {
629: *comm = obj->comm;
630: return(0);
631: }
635: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
636: {
641: PetscObjectListRemoveReference(&obj->olist,name);
642: return(0);
643: }
647: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
648: {
650: char *tname;
651: PetscBool skipreference;
654: if (ptr) {
655: PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
656: if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
657: }
658: PetscObjectListAdd(&obj->olist,name,ptr);
659: return(0);
660: }
664: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
665: {
670: PetscObjectListFind(obj->olist,name,ptr);
671: return(0);
672: }
676: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
677: {
682: PetscFunctionListAdd(&obj->qlist,name,ptr);
683: return(0);
684: }
688: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
689: {
694: PetscFunctionListFind(obj->qlist,name,ptr);
695: return(0);
696: }
700: /*@C
701: PetscObjectCompose - Associates another PETSc object with a given PETSc object.
703: Not Collective
705: Input Parameters:
706: + obj - the PETSc object; this must be cast with (PetscObject), for example,
707: PetscObjectCompose((PetscObject)mat,...);
708: . name - name associated with the child object
709: - ptr - the other PETSc object to associate with the PETSc object; this must also be
710: cast with (PetscObject)
712: Level: advanced
714: Notes:
715: The second objects reference count is automatically increased by one when it is
716: composed.
718: Replaces any previous object that had the same name.
720: If ptr is null and name has previously been composed using an object, then that
721: entry is removed from the obj.
723: PetscObjectCompose() can be used with any PETSc object (such as
724: Mat, Vec, KSP, SNES, etc.) or any user-provided object. See
725: PetscContainerCreate() for info on how to create an object from a
726: user-provided pointer that may then be composed with PETSc objects.
728: Concepts: objects^composing
729: Concepts: composing objects
731: .seealso: PetscObjectQuery(), PetscContainerCreate()
732: @*/
733: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
734: {
741: (*obj->bops->compose)(obj,name,ptr);
742: return(0);
743: }
747: /*@C
748: PetscObjectSetPrecision - sets the precision used within a given object.
750: Collective on the PetscObject
752: Input Parameters:
753: + obj - the PETSc object; this must be cast with (PetscObject), for example,
754: PetscObjectCompose((PetscObject)mat,...);
755: - precision - the precision
757: Level: advanced
759: .seealso: PetscObjectQuery(), PetscContainerCreate()
760: @*/
761: PetscErrorCode PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
762: {
765: obj->precision = precision;
766: return(0);
767: }
771: /*@C
772: PetscObjectQuery - Gets a PETSc object associated with a given object.
774: Not Collective
776: Input Parameters:
777: + obj - the PETSc object
778: Thus must be cast with a (PetscObject), for example,
779: PetscObjectCompose((PetscObject)mat,...);
780: . name - name associated with child object
781: - ptr - the other PETSc object associated with the PETSc object, this must be
782: cast with (PetscObject*)
784: Level: advanced
786: The reference count of neither object is increased in this call
788: Concepts: objects^composing
789: Concepts: composing objects
790: Concepts: objects^querying
791: Concepts: querying objects
793: .seealso: PetscObjectCompose()
794: @*/
795: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
796: {
803: (*obj->bops->query)(obj,name,ptr);
804: return(0);
805: }
807: /*MC
808: PetscObjectComposeFunction - Associates a function with a given PETSc object.
810: Synopsis:
811: #include <petscsys.h>
812: PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))
814: Logically Collective on PetscObject
816: Input Parameters:
817: + obj - the PETSc object; this must be cast with a (PetscObject), for example,
818: PetscObjectCompose((PetscObject)mat,...);
819: . name - name associated with the child function
820: . fname - name of the function
821: - fptr - function pointer
823: Level: advanced
825: Notes:
826: To remove a registered routine, pass in NULL for fptr().
828: PetscObjectComposeFunction() can be used with any PETSc object (such as
829: Mat, Vec, KSP, SNES, etc.) or any user-provided object.
831: Concepts: objects^composing functions
832: Concepts: composing functions
833: Concepts: functions^querying
834: Concepts: objects^querying
835: Concepts: querying objects
837: .seealso: PetscObjectQueryFunction(), PetscContainerCreate()
838: M*/
842: PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
843: {
849: (*obj->bops->composefunction)(obj,name,fptr);
850: return(0);
851: }
853: /*MC
854: PetscObjectQueryFunction - Gets a function associated with a given object.
856: Synopsis:
857: #include <petscsys.h>
858: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))
860: Logically Collective on PetscObject
862: Input Parameters:
863: + obj - the PETSc object; this must be cast with (PetscObject), for example,
864: PetscObjectQueryFunction((PetscObject)ksp,...);
865: - name - name associated with the child function
867: Output Parameter:
868: . fptr - function pointer
870: Level: advanced
872: Concepts: objects^composing functions
873: Concepts: composing functions
874: Concepts: functions^querying
875: Concepts: objects^querying
876: Concepts: querying objects
878: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind()
879: M*/
882: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
883: {
889: (*obj->bops->queryfunction)(obj,name,ptr);
890: return(0);
891: }
893: struct _p_PetscContainer {
894: PETSCHEADER(int);
895: void *ptr;
896: PetscErrorCode (*userdestroy)(void*);
897: };
901: /*@C
902: PetscContainerGetPointer - Gets the pointer value contained in the container.
904: Not Collective
906: Input Parameter:
907: . obj - the object created with PetscContainerCreate()
909: Output Parameter:
910: . ptr - the pointer value
912: Level: advanced
914: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
915: PetscContainerSetPointer()
916: @*/
917: PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr)
918: {
922: *ptr = obj->ptr;
923: return(0);
924: }
929: /*@C
930: PetscContainerSetPointer - Sets the pointer value contained in the container.
932: Logically Collective on PetscContainer
934: Input Parameters:
935: + obj - the object created with PetscContainerCreate()
936: - ptr - the pointer value
938: Level: advanced
940: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
941: PetscContainerGetPointer()
942: @*/
943: PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr)
944: {
948: obj->ptr = ptr;
949: return(0);
950: }
954: /*@C
955: PetscContainerDestroy - Destroys a PETSc container object.
957: Collective on PetscContainer
959: Input Parameter:
960: . obj - an object that was created with PetscContainerCreate()
962: Level: advanced
964: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
965: @*/
966: PetscErrorCode PetscContainerDestroy(PetscContainer *obj)
967: {
971: if (!*obj) return(0);
973: if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; return(0);}
974: if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
975: PetscHeaderDestroy(obj);
976: return(0);
977: }
981: /*@C
982: PetscContainerSetUserDestroy - Sets name of the user destroy function.
984: Logically Collective on PetscContainer
986: Input Parameter:
987: + obj - an object that was created with PetscContainerCreate()
988: - des - name of the user destroy function
990: Level: advanced
992: .seealso: PetscContainerDestroy()
993: @*/
994: PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
995: {
998: obj->userdestroy = des;
999: return(0);
1000: }
1002: PetscClassId PETSC_CONTAINER_CLASSID;
1006: /*@C
1007: PetscContainerCreate - Creates a PETSc object that has room to hold
1008: a single pointer. This allows one to attach any type of data (accessible
1009: through a pointer) with the PetscObjectCompose() function to a PetscObject.
1010: The data item itself is attached by a call to PetscContainerSetPointer().
1012: Collective on MPI_Comm
1014: Input Parameters:
1015: . comm - MPI communicator that shares the object
1017: Output Parameters:
1018: . container - the container created
1020: Level: advanced
1022: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
1023: @*/
1024: PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
1025: {
1027: PetscContainer contain;
1031: PetscSysInitializePackage();
1032: PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);
1033: *container = contain;
1034: return(0);
1035: }
1039: /*@
1040: PetscObjectSetFromOptions - Sets generic parameters from user options.
1042: Collective on obj
1044: Input Parameter:
1045: . obj - the PetscObjcet
1047: Options Database Keys:
1049: Notes:
1050: We have no generic options at present, so this does nothing
1052: Level: beginner
1054: .keywords: set, options, database
1055: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
1056: @*/
1057: PetscErrorCode PetscObjectSetFromOptions(PetscObject obj)
1058: {
1061: return(0);
1062: }
1066: /*@
1067: PetscObjectSetUp - Sets up the internal data structures for the later use.
1069: Collective on PetscObject
1071: Input Parameters:
1072: . obj - the PetscObject
1074: Notes:
1075: This does nothing at present.
1077: Level: advanced
1079: .keywords: setup
1080: .seealso: PetscObjectDestroy()
1081: @*/
1082: PetscErrorCode PetscObjectSetUp(PetscObject obj)
1083: {
1086: return(0);
1087: }