Actual source code: inherit.c

petsc-master 2015-07-31
Report Typos and Errors
  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: 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));

 22: /*
 23:    PetscHeaderCreate_Private - Creates a base PETSc object header and fills
 24:    in the default values.  Called by the macro PetscHeaderCreate().
 25: */
 26: PetscErrorCode  PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,const char class_name[],const char descr[],const char mansec[],
 27:                                           MPI_Comm comm,PetscObjectDestroyFunction destroy,PetscObjectViewFunction view)
 28: {
 29:   static PetscInt idcnt = 1;
 30:   PetscErrorCode  ierr;
 31: #if defined(PETSC_USE_LOG)
 32:   PetscObject     *newPetscObjects;
 33:   PetscInt         newPetscObjectsMaxCounts,i;
 34: #endif

 37:   h->classid               = classid;
 38:   h->type                  = 0;
 39:   h->class_name            = (char*)class_name;
 40:   h->description           = (char*)descr;
 41:   h->mansec                = (char*)mansec;
 42:   h->prefix                = 0;
 43:   h->refct                 = 1;
 44: #if defined(PETSC_HAVE_SAWS)
 45:   h->amsmem                = PETSC_FALSE;
 46: #endif
 47:   h->id                    = idcnt++;
 48:   h->parentid              = 0;
 49:   h->qlist                 = 0;
 50:   h->olist                 = 0;
 51:   h->precision             = (PetscPrecision) sizeof(PetscReal);
 52:   h->bops->destroy         = destroy;
 53:   h->bops->view            = view;
 54:   h->bops->getcomm         = PetscObjectGetComm_Petsc;
 55:   h->bops->compose         = PetscObjectCompose_Petsc;
 56:   h->bops->query           = PetscObjectQuery_Petsc;
 57:   h->bops->composefunction = PetscObjectComposeFunction_Petsc;
 58:   h->bops->queryfunction   = PetscObjectQueryFunction_Petsc;

 60:   PetscCommDuplicate(comm,&h->comm,&h->tag);

 62: #if defined(PETSC_USE_LOG)
 63:   /* Keep a record of object created */
 64:   if (PetscObjectsLog) {
 65:     PetscObjectsCounts++;
 66:     for (i=0; i<PetscObjectsMaxCounts; i++) {
 67:       if (!PetscObjects[i]) {
 68:         PetscObjects[i] = h;
 69:         return(0);
 70:       }
 71:     }
 72:     /* Need to increase the space for storing PETSc objects */
 73:     if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100;
 74:     else                        newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts;
 75:     PetscMalloc1(newPetscObjectsMaxCounts,&newPetscObjects);
 76:     PetscMemcpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts*sizeof(PetscObject));
 77:     PetscMemzero(newPetscObjects+PetscObjectsMaxCounts,(newPetscObjectsMaxCounts - PetscObjectsMaxCounts)*sizeof(PetscObject));
 78:     PetscFree(PetscObjects);

 80:     PetscObjects                        = newPetscObjects;
 81:     PetscObjects[PetscObjectsMaxCounts] = h;
 82:     PetscObjectsMaxCounts               = newPetscObjectsMaxCounts;
 83:   }
 84: #endif
 85:   return(0);
 86: }

 88: extern PetscBool      PetscMemoryCollectMaximumUsage;
 89: extern 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 = 0;
115:     h->python_destroy = 0;

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] = 0;
140:         PetscObjectsCounts--;
141:         break;
142:       }
143:     }
144:     if (!PetscObjectsCounts) {
145:       PetscFree(PetscObjects);
146:       PetscObjectsMaxCounts = 0;
147:     }
148:   }
149: #endif
150:   return(0);
151: }

155: /*@C
156:    PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object

158:    Logically Collective on PetscObject

160:    Input Parameter:
161: +  src - source object
162: -  dest - destination object

164:    Level: developer

166:    Note:
167:    Both objects must have the same class.
168: @*/
169: PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest)
170: {
172:   PetscInt       cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE];

177:   if (src->classid != dest->classid) SETERRQ(src->comm,PETSC_ERR_ARG_INCOMP,"Objects must be of the same class");

179:   PetscFree(dest->fortran_func_pointers);
180:   PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);
181:   PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));

183:   dest->num_fortran_func_pointers = src->num_fortran_func_pointers;

185:   PetscFortranCallbackGetSizes(src->classid,&numcb[PETSC_FORTRAN_CALLBACK_CLASS],&numcb[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
186:   for (cbtype=PETSC_FORTRAN_CALLBACK_CLASS; cbtype<PETSC_FORTRAN_CALLBACK_MAXTYPE; cbtype++) {
187:     PetscFree(dest->fortrancallback[cbtype]);
188:     PetscCalloc1(numcb[cbtype],&dest->fortrancallback[cbtype]);
189:     PetscMemcpy(dest->fortrancallback[cbtype],src->fortrancallback[cbtype],src->num_fortrancallback[cbtype]*sizeof(PetscFortranCallback));
190:   }
191:   return(0);
192: }

196: /*@C
197:    PetscObjectSetFortranCallback - set fortran callback function pointer and context

199:    Logically Collective

201:    Input Arguments:
202: +  obj - object on which to set callback
203: .  cbtype - callback type (class or subtype)
204: .  cid - address of callback Id, updated if not yet initialized (zero)
205: .  func - Fortran function
206: -  ctx - Fortran context

208:    Level: developer

210: .seealso: PetscObjectGetFortranCallback()
211: @*/
212: PetscErrorCode PetscObjectSetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId *cid,void (*func)(void),void *ctx)
213: {
215:   const char     *subtype = NULL;

219:   if (cbtype == PETSC_FORTRAN_CALLBACK_SUBTYPE) subtype = obj->type_name;
220:   if (!*cid) {PetscFortranCallbackRegister(obj->classid,subtype,cid);}
221:   if (*cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype]) {
222:     PetscInt             oldnum = obj->num_fortrancallback[cbtype],newnum = PetscMax(1,2*oldnum);
223:     PetscFortranCallback *callback;
224:     PetscMalloc1(newnum,&callback);
225:     PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));
226:     PetscFree(obj->fortrancallback[cbtype]);

228:     obj->fortrancallback[cbtype] = callback;
229:     obj->num_fortrancallback[cbtype] = newnum;
230:   }
231:   obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func;
232:   obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx;
233:   return(0);
234: }

238: /*@C
239:    PetscObjectGetFortranCallback - get fortran callback function pointer and context

241:    Logically Collective

243:    Input Arguments:
244: +  obj - object on which to get callback
245: .  cbtype - callback type
246: -  cid - address of callback Id

248:    Output Arguments:
249: +  func - Fortran function (or NULL if not needed)
250: -  ctx - Fortran context (or NULL if not needed)

252:    Level: developer

254: .seealso: PetscObjectSetFortranCallback()
255: @*/
256: PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx)
257: {
258:   PetscFortranCallback *cb;

262:   if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid");
263:   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");
264:   cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK];
265:   if (func) *func = cb->func;
266:   if (ctx) *ctx = cb->ctx;
267:   return(0);
268: }

270: #if defined(PETSC_USE_LOG)
273: /*@C
274:    PetscObjectsDump - Prints the currently existing objects.

276:    Logically Collective on PetscViewer

278:    Input Parameter:
279: +  fd - file pointer
280: -  all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects

282:    Options Database:
283: .  -objects_dump <all>

285:    Level: advanced

287:    Concepts: options database^printing

289: @*/
290: PetscErrorCode  PetscObjectsDump(FILE *fd,PetscBool all)
291: {
293:   PetscInt       i;
294: #if defined(PETSC_USE_DEBUG)
295:   PetscInt       j,k=0;
296: #endif
297:   PetscObject    h;

300:   if (PetscObjectsCounts) {
301:     PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");
302:     PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");
303:     for (i=0; i<PetscObjectsMaxCounts; i++) {
304:       if ((h = PetscObjects[i])) {
305:         PetscObjectName(h);
306:         {
307: #if defined(PETSC_USE_DEBUG)
308:         PetscStack *stack = 0;
309:         char       *create,*rclass;

311:         /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */
312:         PetscMallocGetStack(h,&stack);
313:         if (stack) {
314:           k = stack->currentsize-2;
315:           if (!all) {
316:             k = 0;
317:             while (!stack->petscroutine[k]) k++;
318:             PetscStrstr(stack->function[k],"Create",&create);
319:             if (!create) {
320:               PetscStrstr(stack->function[k],"Get",&create);
321:             }
322:             PetscStrstr(stack->function[k],h->class_name,&rclass);
323:             if (!create) continue;
324:             if (!rclass) continue;
325:           }
326:         }
327: #endif

329:         PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);

331: #if defined(PETSC_USE_DEBUG)
332:         PetscMallocGetStack(h,&stack);
333:         if (stack) {
334:           for (j=k; j>=0; j--) {
335:             fprintf(fd,"      [%d]  %s() in %s\n",PetscGlobalRank,stack->function[j],stack->file[j]);
336:           }
337:         }
338: #endif
339:         }
340:       }
341:     }
342:   }
343:   return(0);
344: }
345: #endif

347: #if defined(PETSC_USE_LOG)

351: /*@C
352:    PetscObjectsView - Prints the currently existing objects.

354:    Logically Collective on PetscViewer

356:    Input Parameter:
357: .  viewer - must be an PETSCVIEWERASCII viewer

359:    Level: advanced

361:    Concepts: options database^printing

363: @*/
364: PetscErrorCode  PetscObjectsView(PetscViewer viewer)
365: {
367:   PetscBool      isascii;
368:   FILE           *fd;

371:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
372:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
373:   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
374:   PetscViewerASCIIGetPointer(viewer,&fd);
375:   PetscObjectsDump(fd,PETSC_TRUE);
376:   return(0);
377: }

381: /*@C
382:    PetscObjectsGetObject - Get a pointer to a named object

384:    Not collective

386:    Input Parameter:
387: .  name - the name of an object

389:    Output Parameter:
390: .   obj - the object or null if there is no object

392:    Level: advanced

394:    Concepts: options database^printing

396: @*/
397: PetscErrorCode  PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
398: {
400:   PetscInt       i;
401:   PetscObject    h;
402:   PetscBool      flg;

405:   *obj = NULL;
406:   for (i=0; i<PetscObjectsMaxCounts; i++) {
407:     if ((h = PetscObjects[i])) {
408:       PetscObjectName(h);
409:       PetscStrcmp(h->name,name,&flg);
410:       if (flg) {
411:         *obj = h;
412:         if (classname) *classname = h->class_name;
413:         return(0);
414:       }
415:     }
416:   }
417:   return(0);
418: }
419: #endif

423: /*@C
424:     PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.

426:     Not Collective

428:     Input Parameter:
429: +   obj - the PETSc object
430: .   handle - function that checks for options
431: .   destroy - function to destroy context if provided
432: -   ctx - optional context for check function

434:     Level: developer


437: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()

439: @*/
440: PetscErrorCode  PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
441: {
444:   if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
445:   obj->optionhandler[obj->noptionhandler] = handle;
446:   obj->optiondestroy[obj->noptionhandler] = destroy;
447:   obj->optionctx[obj->noptionhandler++]   = ctx;
448:   return(0);
449: }

453: /*@C
454:     PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object

456:     Not Collective

458:     Input Parameter:
459: .   obj - the PETSc object

461:     Level: developer


464: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()

466: @*/
467: PetscErrorCode  PetscObjectProcessOptionsHandlers(PetscObject obj)
468: {
469:   PetscInt       i;

474:   for (i=0; i<obj->noptionhandler; i++) {
475:     (*obj->optionhandler[i])(obj,obj->optionctx[i]);
476:   }
477:   return(0);
478: }

482: /*@C
483:     PetscObjectDestroyOptionsHandlers - Destroys all the option 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(), PetscObjectProcessOptionsHandlers()

495: @*/
496: PetscErrorCode  PetscObjectDestroyOptionsHandlers(PetscObject obj)
497: {
498:   PetscInt       i;

503:   for (i=0; i<obj->noptionhandler; i++) {
504:     if (obj->optiondestroy[i]) {
505:       (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
506:     }
507:   }
508:   obj->noptionhandler = 0;
509:   return(0);
510: }


515: /*@
516:    PetscObjectReference - Indicates to any PetscObject that it is being
517:    referenced by another PetscObject. This increases the reference
518:    count for that object by one.

520:    Logically Collective on PetscObject

522:    Input Parameter:
523: .  obj - the PETSc object. This must be cast with (PetscObject), for example,
524:          PetscObjectReference((PetscObject)mat);

526:    Level: advanced

528: .seealso: PetscObjectCompose(), PetscObjectDereference()
529: @*/
530: PetscErrorCode  PetscObjectReference(PetscObject obj)
531: {
533:   if (!obj) return(0);
535:   obj->refct++;
536:   return(0);
537: }

541: /*@
542:    PetscObjectGetReference - Gets the current reference count for
543:    any PETSc object.

545:    Not Collective

547:    Input Parameter:
548: .  obj - the PETSc object; this must be cast with (PetscObject), for example,
549:          PetscObjectGetReference((PetscObject)mat,&cnt);

551:    Output Parameter:
552: .  cnt - the reference count

554:    Level: advanced

556: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
557: @*/
558: PetscErrorCode  PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
559: {
563:   *cnt = obj->refct;
564:   return(0);
565: }

569: /*@
570:    PetscObjectDereference - Indicates to any PetscObject that it is being
571:    referenced by one less PetscObject. This decreases the reference
572:    count for that object by one.

574:    Collective on PetscObject if reference reaches 0 otherwise Logically Collective

576:    Input Parameter:
577: .  obj - the PETSc object; this must be cast with (PetscObject), for example,
578:          PetscObjectDereference((PetscObject)mat);

580:    Notes: PetscObjectDestroy(PetscObject *obj)  sets the obj pointer to null after the call, this routine does not.

582:    Level: advanced

584: .seealso: PetscObjectCompose(), PetscObjectReference()
585: @*/
586: PetscErrorCode  PetscObjectDereference(PetscObject obj)
587: {

591:   if (!obj) return(0);
593:   if (obj->bops->destroy) {
594:     (*obj->bops->destroy)(&obj);
595:   } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
596:   return(0);
597: }

599: /* ----------------------------------------------------------------------- */
600: /*
601:      The following routines are the versions private to the PETSc object
602:      data structures.
603: */
606: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
607: {
610:   *comm = obj->comm;
611:   return(0);
612: }

616: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
617: {

622:   PetscObjectListRemoveReference(&obj->olist,name);
623:   return(0);
624: }

628: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
629: {
631:   char           *tname;
632:   PetscBool      skipreference;

635:   if (ptr) {
636:     PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
637:     if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
638:   }
639:   PetscObjectListAdd(&obj->olist,name,ptr);
640:   return(0);
641: }

645: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
646: {

651:   PetscObjectListFind(obj->olist,name,ptr);
652:   return(0);
653: }

657: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
658: {

663:   PetscFunctionListAdd(&obj->qlist,name,ptr);
664:   return(0);
665: }

669: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
670: {

675:   PetscFunctionListFind(obj->qlist,name,ptr);
676:   return(0);
677: }

681: /*@C
682:    PetscObjectCompose - Associates another PETSc object with a given PETSc object.

684:    Not Collective

686:    Input Parameters:
687: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
688:          PetscObjectCompose((PetscObject)mat,...);
689: .  name - name associated with the child object
690: -  ptr - the other PETSc object to associate with the PETSc object; this must also be
691:          cast with (PetscObject)

693:    Level: advanced

695:    Notes:
696:    The second objects reference count is automatically increased by one when it is
697:    composed.

699:    Replaces any previous object that had the same name.

701:    If ptr is null and name has previously been composed using an object, then that
702:    entry is removed from the obj.

704:    PetscObjectCompose() can be used with any PETSc object (such as
705:    Mat, Vec, KSP, SNES, etc.) or any user-provided object.  See
706:    PetscContainerCreate() for info on how to create an object from a
707:    user-provided pointer that may then be composed with PETSc objects.

709:    Concepts: objects^composing
710:    Concepts: composing objects

712: .seealso: PetscObjectQuery(), PetscContainerCreate()
713: @*/
714: PetscErrorCode  PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
715: {

722:   (*obj->bops->compose)(obj,name,ptr);
723:   return(0);
724: }

728: /*@C
729:    PetscObjectSetPrecision - sets the precision used within a given object.

731:    Collective on the PetscObject

733:    Input Parameters:
734: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
735:          PetscObjectCompose((PetscObject)mat,...);
736: -  precision - the precision

738:    Level: advanced

740: .seealso: PetscObjectQuery(), PetscContainerCreate()
741: @*/
742: PetscErrorCode  PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
743: {
746:   obj->precision = precision;
747:   return(0);
748: }

752: /*@C
753:    PetscObjectQuery  - Gets a PETSc object associated with a given object.

755:    Not Collective

757:    Input Parameters:
758: +  obj - the PETSc object
759:          Thus must be cast with a (PetscObject), for example,
760:          PetscObjectCompose((PetscObject)mat,...);
761: .  name - name associated with child object
762: -  ptr - the other PETSc object associated with the PETSc object, this must be
763:          cast with (PetscObject*)

765:    Level: advanced

767:    The reference count of neither object is increased in this call

769:    Concepts: objects^composing
770:    Concepts: composing objects
771:    Concepts: objects^querying
772:    Concepts: querying objects

774: .seealso: PetscObjectCompose()
775: @*/
776: PetscErrorCode  PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
777: {

784:   (*obj->bops->query)(obj,name,ptr);
785:   return(0);
786: }

788: /*MC
789:    PetscObjectComposeFunction - Associates a function with a given PETSc object.

791:     Synopsis:
792:     #include <petscsys.h>
793:     PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))

795:    Logically Collective on PetscObject

797:    Input Parameters:
798: +  obj - the PETSc object; this must be cast with a (PetscObject), for example,
799:          PetscObjectCompose((PetscObject)mat,...);
800: .  name - name associated with the child function
801: .  fname - name of the function
802: -  fptr - function pointer

804:    Level: advanced

806:    Notes:
807:    To remove a registered routine, pass in NULL for fptr().

809:    PetscObjectComposeFunction() can be used with any PETSc object (such as
810:    Mat, Vec, KSP, SNES, etc.) or any user-provided object.

812:    Concepts: objects^composing functions
813:    Concepts: composing functions
814:    Concepts: functions^querying
815:    Concepts: objects^querying
816:    Concepts: querying objects

818: .seealso: PetscObjectQueryFunction(), PetscContainerCreate()
819: M*/

823: PetscErrorCode  PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
824: {

830:   (*obj->bops->composefunction)(obj,name,fptr);
831:   return(0);
832: }

834: /*MC
835:    PetscObjectQueryFunction - Gets a function associated with a given object.

837:     Synopsis:
838:     #include <petscsys.h>
839:     PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))

841:    Logically Collective on PetscObject

843:    Input Parameters:
844: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
845:          PetscObjectQueryFunction((PetscObject)ksp,...);
846: -  name - name associated with the child function

848:    Output Parameter:
849: .  fptr - function pointer

851:    Level: advanced

853:    Concepts: objects^composing functions
854:    Concepts: composing functions
855:    Concepts: functions^querying
856:    Concepts: objects^querying
857:    Concepts: querying objects

859: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind()
860: M*/
863: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
864: {

870:   (*obj->bops->queryfunction)(obj,name,ptr);
871:   return(0);
872: }

874: struct _p_PetscContainer {
875:   PETSCHEADER(int);
876:   void           *ptr;
877:   PetscErrorCode (*userdestroy)(void*);
878: };

882: /*@C
883:    PetscContainerGetPointer - Gets the pointer value contained in the container.

885:    Not Collective

887:    Input Parameter:
888: .  obj - the object created with PetscContainerCreate()

890:    Output Parameter:
891: .  ptr - the pointer value

893:    Level: advanced

895: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
896:           PetscContainerSetPointer()
897: @*/
898: PetscErrorCode  PetscContainerGetPointer(PetscContainer obj,void **ptr)
899: {
903:   *ptr = obj->ptr;
904:   return(0);
905: }


910: /*@C
911:    PetscContainerSetPointer - Sets the pointer value contained in the container.

913:    Logically Collective on PetscContainer

915:    Input Parameters:
916: +  obj - the object created with PetscContainerCreate()
917: -  ptr - the pointer value

919:    Level: advanced

921: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
922:           PetscContainerGetPointer()
923: @*/
924: PetscErrorCode  PetscContainerSetPointer(PetscContainer obj,void *ptr)
925: {
929:   obj->ptr = ptr;
930:   return(0);
931: }

935: /*@C
936:    PetscContainerDestroy - Destroys a PETSc container object.

938:    Collective on PetscContainer

940:    Input Parameter:
941: .  obj - an object that was created with PetscContainerCreate()

943:    Level: advanced

945: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
946: @*/
947: PetscErrorCode  PetscContainerDestroy(PetscContainer *obj)
948: {

952:   if (!*obj) return(0);
954:   if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; return(0);}
955:   if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
956:   PetscHeaderDestroy(obj);
957:   return(0);
958: }

962: /*@C
963:    PetscContainerSetUserDestroy - Sets name of the user destroy function.

965:    Logically Collective on PetscContainer

967:    Input Parameter:
968: +  obj - an object that was created with PetscContainerCreate()
969: -  des - name of the user destroy function

971:    Level: advanced

973: .seealso: PetscContainerDestroy()
974: @*/
975: PetscErrorCode  PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
976: {
979:   obj->userdestroy = des;
980:   return(0);
981: }

983: PetscClassId PETSC_CONTAINER_CLASSID;

987: /*@C
988:    PetscContainerCreate - Creates a PETSc object that has room to hold
989:    a single pointer. This allows one to attach any type of data (accessible
990:    through a pointer) with the PetscObjectCompose() function to a PetscObject.
991:    The data item itself is attached by a call to PetscContainerSetPointer().

993:    Collective on MPI_Comm

995:    Input Parameters:
996: .  comm - MPI communicator that shares the object

998:    Output Parameters:
999: .  container - the container created

1001:    Level: advanced

1003: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
1004: @*/
1005: PetscErrorCode  PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
1006: {
1008:   PetscContainer contain;

1012:   PetscSysInitializePackage();
1013:   PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);
1014:   *container = contain;
1015:   return(0);
1016: }

1020: /*@
1021:    PetscObjectSetFromOptions - Sets generic parameters from user options.

1023:    Collective on obj

1025:    Input Parameter:
1026: .  obj - the PetscObjcet

1028:    Options Database Keys:

1030:    Notes:
1031:    We have no generic options at present, so this does nothing

1033:    Level: beginner

1035: .keywords: set, options, database
1036: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
1037: @*/
1038: PetscErrorCode  PetscObjectSetFromOptions(PetscObject obj)
1039: {
1042:   return(0);
1043: }

1047: /*@
1048:    PetscObjectSetUp - Sets up the internal data structures for the later use.

1050:    Collective on PetscObject

1052:    Input Parameters:
1053: .  obj - the PetscObject

1055:    Notes:
1056:    This does nothing at present.

1058:    Level: advanced

1060: .keywords: setup
1061: .seealso: PetscObjectDestroy()
1062: @*/
1063: PetscErrorCode  PetscObjectSetUp(PetscObject obj)
1064: {
1067:   return(0);
1068: }