Actual source code: inherit.c

petsc-3.9.4 2018-09-11
Report Typos and Errors

  2: /*
  3:      Provides utility routines for manipulating any type of PETSc object.
  4: */
  5:  #include <petsc/private/petscimpl.h>
  6:  #include <petscviewer.h>

  8: #if defined(PETSC_USE_LOG)
  9: PetscObject *PetscObjects      = 0;
 10: PetscInt    PetscObjectsCounts = 0, PetscObjectsMaxCounts = 0;
 11: PetscBool   PetscObjectsLog    = PETSC_FALSE;
 12: #endif

 14: extern PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm*);
 15: extern PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject);
 16: extern PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject*);
 17: extern PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],void (*)(void));
 18: extern PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void));

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

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

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

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

 77:     PetscObjects                        = newPetscObjects;
 78:     PetscObjects[PetscObjectsMaxCounts] = h;
 79:     PetscObjectsMaxCounts               = newPetscObjectsMaxCounts;
 80:   }
 81: #endif
 82:   return(0);
 83: }

 85: extern PetscBool      PetscMemoryCollectMaximumUsage;
 86: extern PetscLogDouble PetscMemoryMaximumUsage;

 88: /*
 89:     PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
 90:     the macro PetscHeaderDestroy().
 91: */
 92: PetscErrorCode  PetscHeaderDestroy_Private(PetscObject h)
 93: {

 98:   PetscLogObjectDestroy(h);
 99:   PetscComposedQuantitiesDestroy(h);
100:   if (PetscMemoryCollectMaximumUsage) {
101:     PetscLogDouble usage;
102:     PetscMemoryGetCurrentUsage(&usage);
103:     if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
104:   }
105:   /* first destroy things that could execute arbitrary code */
106:   if (h->python_destroy) {
107:     void           *python_context = h->python_context;
108:     PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
109:     h->python_context = 0;
110:     h->python_destroy = 0;

112:     (*python_destroy)(python_context);
113:   }
114:   PetscObjectDestroyOptionsHandlers(h);
115:   PetscObjectListDestroy(&h->olist);
116:   PetscCommDestroy(&h->comm);
117:   /* next destroy other things */
118:   h->classid = PETSCFREEDHEADER;

120:   PetscFunctionListDestroy(&h->qlist);
121:   PetscFree(h->type_name);
122:   PetscFree(h->name);
123:   PetscFree(h->prefix);
124:   PetscFree(h->fortran_func_pointers);
125:   PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_CLASS]);
126:   PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_SUBTYPE]);

128: #if defined(PETSC_USE_LOG)
129:   if (PetscObjectsLog) {
130:     PetscInt i;
131:     /* Record object removal from list of all objects */
132:     for (i=0; i<PetscObjectsMaxCounts; i++) {
133:       if (PetscObjects[i] == h) {
134:         PetscObjects[i] = 0;
135:         PetscObjectsCounts--;
136:         break;
137:       }
138:     }
139:     if (!PetscObjectsCounts) {
140:       PetscFree(PetscObjects);
141:       PetscObjectsMaxCounts = 0;
142:     }
143:   }
144: #endif
145:   return(0);
146: }

148: /*@C
149:    PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object

151:    Logically Collective on PetscObject

153:    Input Parameter:
154: +  src - source object
155: -  dest - destination object

157:    Level: developer

159:    Note:
160:    Both objects must have the same class.
161: @*/
162: PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest)
163: {
165:   PetscInt       cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE];

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

172:   PetscFree(dest->fortran_func_pointers);
173:   PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);
174:   PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));

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

178:   PetscFortranCallbackGetSizes(src->classid,&numcb[PETSC_FORTRAN_CALLBACK_CLASS],&numcb[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
179:   for (cbtype=PETSC_FORTRAN_CALLBACK_CLASS; cbtype<PETSC_FORTRAN_CALLBACK_MAXTYPE; cbtype++) {
180:     PetscFree(dest->fortrancallback[cbtype]);
181:     PetscCalloc1(numcb[cbtype],&dest->fortrancallback[cbtype]);
182:     PetscMemcpy(dest->fortrancallback[cbtype],src->fortrancallback[cbtype],src->num_fortrancallback[cbtype]*sizeof(PetscFortranCallback));
183:     dest->num_fortrancallback[cbtype] = src->num_fortrancallback[cbtype];
184:   }
185:   return(0);
186: }

188: /*@C
189:    PetscObjectSetFortranCallback - set fortran callback function pointer and context

191:    Logically Collective

193:    Input Arguments:
194: +  obj - object on which to set callback
195: .  cbtype - callback type (class or subtype)
196: .  cid - address of callback Id, updated if not yet initialized (zero)
197: .  func - Fortran function
198: -  ctx - Fortran context

200:    Level: developer

202: .seealso: PetscObjectGetFortranCallback()
203: @*/
204: PetscErrorCode PetscObjectSetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId *cid,void (*func)(void),void *ctx)
205: {
207:   const char     *subtype = NULL;

211:   if (cbtype == PETSC_FORTRAN_CALLBACK_SUBTYPE) subtype = obj->type_name;
212:   if (!*cid) {PetscFortranCallbackRegister(obj->classid,subtype,cid);}
213:   if (*cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype]) {
214:     PetscInt             oldnum = obj->num_fortrancallback[cbtype],newnum = PetscMax(1,2*oldnum);
215:     PetscFortranCallback *callback;
216:     PetscMalloc1(newnum,&callback);
217:     PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));
218:     PetscFree(obj->fortrancallback[cbtype]);

220:     obj->fortrancallback[cbtype] = callback;
221:     obj->num_fortrancallback[cbtype] = newnum;
222:   }
223:   obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func;
224:   obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx;
225:   return(0);
226: }

228: /*@C
229:    PetscObjectGetFortranCallback - get fortran callback function pointer and context

231:    Logically Collective

233:    Input Arguments:
234: +  obj - object on which to get callback
235: .  cbtype - callback type
236: -  cid - address of callback Id

238:    Output Arguments:
239: +  func - Fortran function (or NULL if not needed)
240: -  ctx - Fortran context (or NULL if not needed)

242:    Level: developer

244: .seealso: PetscObjectSetFortranCallback()
245: @*/
246: PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx)
247: {
248:   PetscFortranCallback *cb;

252:   if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid");
253:   if (PetscUnlikely(cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype])) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback not set on this object");
254:   cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK];
255:   if (func) *func = cb->func;
256:   if (ctx) *ctx = cb->ctx;
257:   return(0);
258: }

260: #if defined(PETSC_USE_LOG)
261: /*@C
262:    PetscObjectsDump - Prints the currently existing objects.

264:    Logically Collective on PetscViewer

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

270:    Options Database:
271: .  -objects_dump <all>

273:    Level: advanced

275:    Concepts: options database^printing

277: @*/
278: PetscErrorCode  PetscObjectsDump(FILE *fd,PetscBool all)
279: {
281:   PetscInt       i;
282: #if defined(PETSC_USE_DEBUG)
283:   PetscInt       j,k=0;
284: #endif
285:   PetscObject    h;

288:   if (PetscObjectsCounts) {
289:     PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");
290:     PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");
291:     for (i=0; i<PetscObjectsMaxCounts; i++) {
292:       if ((h = PetscObjects[i])) {
293:         PetscObjectName(h);
294:         {
295: #if defined(PETSC_USE_DEBUG)
296:         PetscStack *stack = 0;
297:         char       *create,*rclass;

299:         /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */
300:         PetscMallocGetStack(h,&stack);
301:         if (stack) {
302:           k = stack->currentsize-2;
303:           if (!all) {
304:             k = 0;
305:             while (!stack->petscroutine[k]) k++;
306:             PetscStrstr(stack->function[k],"Create",&create);
307:             if (!create) {
308:               PetscStrstr(stack->function[k],"Get",&create);
309:             }
310:             PetscStrstr(stack->function[k],h->class_name,&rclass);
311:             if (!create) continue;
312:             if (!rclass) continue;
313:           }
314:         }
315: #endif

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

319: #if defined(PETSC_USE_DEBUG)
320:         PetscMallocGetStack(h,&stack);
321:         if (stack) {
322:           for (j=k; j>=0; j--) {
323:             fprintf(fd,"      [%d]  %s() in %s\n",PetscGlobalRank,stack->function[j],stack->file[j]);
324:           }
325:         }
326: #endif
327:         }
328:       }
329:     }
330:   }
331:   return(0);
332: }
333: #endif

335: #if defined(PETSC_USE_LOG)

337: /*@C
338:    PetscObjectsView - Prints the currently existing objects.

340:    Logically Collective on PetscViewer

342:    Input Parameter:
343: .  viewer - must be an PETSCVIEWERASCII viewer

345:    Level: advanced

347:    Concepts: options database^printing

349: @*/
350: PetscErrorCode  PetscObjectsView(PetscViewer viewer)
351: {
353:   PetscBool      isascii;
354:   FILE           *fd;

357:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
358:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
359:   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
360:   PetscViewerASCIIGetPointer(viewer,&fd);
361:   PetscObjectsDump(fd,PETSC_TRUE);
362:   return(0);
363: }

365: /*@C
366:    PetscObjectsGetObject - Get a pointer to a named object

368:    Not collective

370:    Input Parameter:
371: .  name - the name of an object

373:    Output Parameter:
374: .   obj - the object or null if there is no object

376:    Level: advanced

378:    Concepts: options database^printing

380: @*/
381: PetscErrorCode  PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
382: {
384:   PetscInt       i;
385:   PetscObject    h;
386:   PetscBool      flg;

389:   *obj = NULL;
390:   for (i=0; i<PetscObjectsMaxCounts; i++) {
391:     if ((h = PetscObjects[i])) {
392:       PetscObjectName(h);
393:       PetscStrcmp(h->name,name,&flg);
394:       if (flg) {
395:         *obj = h;
396:         if (classname) *classname = h->class_name;
397:         return(0);
398:       }
399:     }
400:   }
401:   return(0);
402: }
403: #endif

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

408:     Not Collective

410:     Input Parameter:
411: +   obj - the PETSc object
412: .   handle - function that checks for options
413: .   destroy - function to destroy context if provided
414: -   ctx - optional context for check function

416:     Level: developer


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

421: @*/
422: PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscOptionItems*,PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
423: {
426:   if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
427:   obj->optionhandler[obj->noptionhandler] = handle;
428:   obj->optiondestroy[obj->noptionhandler] = destroy;
429:   obj->optionctx[obj->noptionhandler++]   = ctx;
430:   return(0);
431: }

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

436:     Not Collective

438:     Input Parameter:
439: .   obj - the PETSc object

441:     Level: developer


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

446: @*/
447: PetscErrorCode  PetscObjectProcessOptionsHandlers(PetscOptionItems *PetscOptionsObject,PetscObject obj)
448: {
449:   PetscInt       i;

454:   for (i=0; i<obj->noptionhandler; i++) {
455:     (*obj->optionhandler[i])(PetscOptionsObject,obj,obj->optionctx[i]);
456:   }
457:   return(0);
458: }

460: /*@C
461:     PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object

463:     Not Collective

465:     Input Parameter:
466: .   obj - the PETSc object

468:     Level: developer


471: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()

473: @*/
474: PetscErrorCode  PetscObjectDestroyOptionsHandlers(PetscObject obj)
475: {
476:   PetscInt       i;

481:   for (i=0; i<obj->noptionhandler; i++) {
482:     if (obj->optiondestroy[i]) {
483:       (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
484:     }
485:   }
486:   obj->noptionhandler = 0;
487:   return(0);
488: }


491: /*@C
492:    PetscObjectReference - Indicates to any PetscObject that it is being
493:    referenced by another PetscObject. This increases the reference
494:    count for that object by one.

496:    Logically Collective on PetscObject

498:    Input Parameter:
499: .  obj - the PETSc object. This must be cast with (PetscObject), for example,
500:          PetscObjectReference((PetscObject)mat);

502:    Level: advanced

504: .seealso: PetscObjectCompose(), PetscObjectDereference()
505: @*/
506: PetscErrorCode  PetscObjectReference(PetscObject obj)
507: {
509:   if (!obj) return(0);
511:   obj->refct++;
512:   return(0);
513: }

515: /*@C
516:    PetscObjectGetReference - Gets the current reference count for
517:    any PETSc object.

519:    Not Collective

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

525:    Output Parameter:
526: .  cnt - the reference count

528:    Level: advanced

530: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
531: @*/
532: PetscErrorCode  PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
533: {
537:   *cnt = obj->refct;
538:   return(0);
539: }

541: /*@C
542:    PetscObjectDereference - Indicates to any PetscObject that it is being
543:    referenced by one less PetscObject. This decreases the reference
544:    count for that object by one.

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

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

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

554:    Level: advanced

556: .seealso: PetscObjectCompose(), PetscObjectReference()
557: @*/
558: PetscErrorCode  PetscObjectDereference(PetscObject obj)
559: {

563:   if (!obj) return(0);
565:   if (obj->bops->destroy) {
566:     (*obj->bops->destroy)(&obj);
567:   } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
568:   return(0);
569: }

571: /* ----------------------------------------------------------------------- */
572: /*
573:      The following routines are the versions private to the PETSc object
574:      data structures.
575: */
576: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
577: {
580:   *comm = obj->comm;
581:   return(0);
582: }

584: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
585: {

590:   PetscObjectListRemoveReference(&obj->olist,name);
591:   return(0);
592: }

594: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
595: {
597:   char           *tname;
598:   PetscBool      skipreference;

601:   if (ptr) {
602:     PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
603:     if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
604:   }
605:   PetscObjectListAdd(&obj->olist,name,ptr);
606:   return(0);
607: }

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

615:   PetscObjectListFind(obj->olist,name,ptr);
616:   return(0);
617: }

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

625:   PetscFunctionListAdd(&obj->qlist,name,ptr);
626:   return(0);
627: }

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

635:   PetscFunctionListFind(obj->qlist,name,ptr);
636:   return(0);
637: }

639: /*@C
640:    PetscObjectCompose - Associates another PETSc object with a given PETSc object.

642:    Not Collective

644:    Input Parameters:
645: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
646:          PetscObjectCompose((PetscObject)mat,...);
647: .  name - name associated with the child object
648: -  ptr - the other PETSc object to associate with the PETSc object; this must also be
649:          cast with (PetscObject)

651:    Level: advanced

653:    Notes:
654:    The second objects reference count is automatically increased by one when it is
655:    composed.

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

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

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

667:    Concepts: objects^composing
668:    Concepts: composing objects

670: .seealso: PetscObjectQuery(), PetscContainerCreate()
671: @*/
672: PetscErrorCode  PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
673: {

680:   if (obj == ptr) SETERRQ(PetscObjectComm((PetscObject)obj),PETSC_ERR_SUP,"Cannot compose object with itself");
681:   (*obj->bops->compose)(obj,name,ptr);
682:   return(0);
683: }

685: /*@C
686:    PetscObjectQuery  - Gets a PETSc object associated with a given object.

688:    Not Collective

690:    Input Parameters:
691: +  obj - the PETSc object
692:          Thus must be cast with a (PetscObject), for example,
693:          PetscObjectCompose((PetscObject)mat,...);
694: .  name - name associated with child object
695: -  ptr - the other PETSc object associated with the PETSc object, this must be
696:          cast with (PetscObject*)

698:    Level: advanced

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

702:    Concepts: objects^composing
703:    Concepts: composing objects
704:    Concepts: objects^querying
705:    Concepts: querying objects

707: .seealso: PetscObjectCompose()
708: @*/
709: PetscErrorCode  PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
710: {

717:   (*obj->bops->query)(obj,name,ptr);
718:   return(0);
719: }

721: /*MC
722:    PetscObjectComposeFunction - Associates a function with a given PETSc object.

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

728:    Logically Collective on PetscObject

730:    Input Parameters:
731: +  obj - the PETSc object; this must be cast with a (PetscObject), for example,
732:          PetscObjectCompose((PetscObject)mat,...);
733: .  name - name associated with the child function
734: .  fname - name of the function
735: -  fptr - function pointer

737:    Level: advanced

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

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

745:    Concepts: objects^composing functions
746:    Concepts: composing functions
747:    Concepts: functions^querying
748:    Concepts: objects^querying
749:    Concepts: querying objects

751: .seealso: PetscObjectQueryFunction(), PetscContainerCreate()
752: M*/

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

761:   (*obj->bops->composefunction)(obj,name,fptr);
762:   return(0);
763: }

765: /*MC
766:    PetscObjectQueryFunction - Gets a function associated with a given object.

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

772:    Logically Collective on PetscObject

774:    Input Parameters:
775: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
776:          PetscObjectQueryFunction((PetscObject)ksp,...);
777: -  name - name associated with the child function

779:    Output Parameter:
780: .  fptr - function pointer

782:    Level: advanced

784:    Concepts: objects^composing functions
785:    Concepts: composing functions
786:    Concepts: functions^querying
787:    Concepts: objects^querying
788:    Concepts: querying objects

790: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind()
791: M*/
792: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
793: {

799:   (*obj->bops->queryfunction)(obj,name,ptr);
800:   return(0);
801: }

803: struct _p_PetscContainer {
804:   PETSCHEADER(int);
805:   void           *ptr;
806:   PetscErrorCode (*userdestroy)(void*);
807: };

809: /*@C
810:    PetscContainerUserDestroyDefault - Default destroy routine for user-provided data that simply calls PetscFree().

812:    Logically Collective on PetscContainer

814:    Input Parameter:
815: .  ctx - pointer to user-provided data

817:    Level: advanced

819: .seealso: PetscContainerDestroy(), PetscContainterSetUserDestroy()
820: @*/
821: PetscErrorCode PetscContainerUserDestroyDefault(void* ctx)
822: {

827:   PetscFree(ctx);
828:   return(0);
829: }

831: /*@C
832:    PetscContainerGetPointer - Gets the pointer value contained in the container.

834:    Not Collective

836:    Input Parameter:
837: .  obj - the object created with PetscContainerCreate()

839:    Output Parameter:
840: .  ptr - the pointer value

842:    Level: advanced

844: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
845:           PetscContainerSetPointer()
846: @*/
847: PetscErrorCode  PetscContainerGetPointer(PetscContainer obj,void **ptr)
848: {
852:   *ptr = obj->ptr;
853:   return(0);
854: }


857: /*@C
858:    PetscContainerSetPointer - Sets the pointer value contained in the container.

860:    Logically Collective on PetscContainer

862:    Input Parameters:
863: +  obj - the object created with PetscContainerCreate()
864: -  ptr - the pointer value

866:    Level: advanced

868: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
869:           PetscContainerGetPointer()
870: @*/
871: PetscErrorCode  PetscContainerSetPointer(PetscContainer obj,void *ptr)
872: {
876:   obj->ptr = ptr;
877:   return(0);
878: }

880: /*@C
881:    PetscContainerDestroy - Destroys a PETSc container object.

883:    Collective on PetscContainer

885:    Input Parameter:
886: .  obj - an object that was created with PetscContainerCreate()

888:    Level: advanced

890: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
891: @*/
892: PetscErrorCode  PetscContainerDestroy(PetscContainer *obj)
893: {

897:   if (!*obj) return(0);
899:   if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; return(0);}
900:   if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
901:   PetscHeaderDestroy(obj);
902:   return(0);
903: }

905: /*@C
906:    PetscContainerSetUserDestroy - Sets name of the user destroy function.

908:    Logically Collective on PetscContainer

910:    Input Parameter:
911: +  obj - an object that was created with PetscContainerCreate()
912: -  des - name of the user destroy function

914:    Notes:
915:    Use PetscContainerUserDestroyDefault() if the memory was obtained by calling PetscMalloc or one of its variants for single memory allocation.

917:    Level: advanced

919: .seealso: PetscContainerDestroy(), PetscContainerUserDestroyDefault(), PetscMalloc(), PetscMalloc1(), PetscCalloc(), PetscCalloc1()
920: @*/
921: PetscErrorCode  PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
922: {
925:   obj->userdestroy = des;
926:   return(0);
927: }

929: PetscClassId PETSC_CONTAINER_CLASSID;

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

937:    Collective on MPI_Comm

939:    Input Parameters:
940: .  comm - MPI communicator that shares the object

942:    Output Parameters:
943: .  container - the container created

945:    Level: advanced

947: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
948: @*/
949: PetscErrorCode  PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
950: {
952:   PetscContainer contain;

956:   PetscSysInitializePackage();
957:   PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);
958:   *container = contain;
959:   return(0);
960: }

962: /*@
963:    PetscObjectSetFromOptions - Sets generic parameters from user options.

965:    Collective on obj

967:    Input Parameter:
968: .  obj - the PetscObjcet

970:    Options Database Keys:

972:    Notes:
973:    We have no generic options at present, so this does nothing

975:    Level: beginner

977: .keywords: set, options, database
978: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
979: @*/
980: PetscErrorCode  PetscObjectSetFromOptions(PetscObject obj)
981: {
984:   return(0);
985: }

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

990:    Collective on PetscObject

992:    Input Parameters:
993: .  obj - the PetscObject

995:    Notes:
996:    This does nothing at present.

998:    Level: advanced

1000: .keywords: setup
1001: .seealso: PetscObjectDestroy()
1002: @*/
1003: PetscErrorCode  PetscObjectSetUp(PetscObject obj)
1004: {
1007:   return(0);
1008: }