Actual source code: inherit.c

  1: #define PETSC_DLL
  2: /*
  3:      Provides utility routines for manipulating any type of PETSc object.
  4: */
 5:  #include petsc.h
 6:  #include petscsys.h

  8: EXTERN PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm *);
  9: EXTERN PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject);
 10: EXTERN PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject *);
 11: EXTERN PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],const char[],void (*)(void));
 12: EXTERN PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void));
 13: EXTERN PetscErrorCode PetscObjectComposeLanguage_Petsc(PetscObject,PetscLanguage,void *);
 14: EXTERN PetscErrorCode PetscObjectQueryLanguage_Petsc(PetscObject,PetscLanguage,void **);

 18: /*
 19:    PetscHeaderCreate_Private - Creates a base PETSc object header and fills
 20:    in the default values.  Called by the macro PetscHeaderCreate().
 21: */
 22: PetscErrorCode PETSC_DLLEXPORT PetscHeaderCreate_Private(PetscObject h,PetscCookie cookie,PetscInt type,const char class_name[],MPI_Comm comm,
 23:                                          PetscErrorCode (*des)(PetscObject),PetscErrorCode (*vie)(PetscObject,PetscViewer))
 24: {
 25:   static PetscInt idcnt = 1;
 26:   PetscErrorCode  ierr;

 29:   h->cookie                 = cookie;
 30:   h->type                   = type;
 31:   h->class_name             = (char*)class_name;
 32:   h->prefix                 = 0;
 33:   h->refct                  = 1;
 34:   h->amem                   = -1;
 35:   h->id                     = idcnt++;
 36:   h->parentid               = 0;
 37:   h->qlist                  = 0;
 38:   h->olist                  = 0;
 39:   h->bops->destroy          = des;
 40:   h->bops->view             = vie;
 41:   h->bops->getcomm          = PetscObjectGetComm_Petsc;
 42:   h->bops->compose          = PetscObjectCompose_Petsc;
 43:   h->bops->query            = PetscObjectQuery_Petsc;
 44:   h->bops->composefunction  = PetscObjectComposeFunction_Petsc;
 45:   h->bops->queryfunction    = PetscObjectQueryFunction_Petsc;
 46:   h->bops->querylanguage    = PetscObjectQueryLanguage_Petsc;
 47:   h->bops->composelanguage  = PetscObjectComposeLanguage_Petsc;
 48:   PetscCommDuplicate(comm,&h->comm,&h->tag);
 49:   return(0);
 50: }


 57: /*
 58:     PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by 
 59:     the macro PetscHeaderDestroy().
 60: */
 61: PetscErrorCode PETSC_DLLEXPORT PetscHeaderDestroy_Private(PetscObject h)
 62: {

 66:   if (PetscMemoryCollectMaximumUsage) {
 67:     PetscLogDouble usage;
 68:     PetscMemoryGetCurrentUsage(&usage);
 69:     if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
 70:   }
 71:   PetscCommDestroy(&h->comm);
 72:   PetscFree(h->bops);
 73:   PetscFree(h->ops);
 74:   PetscOListDestroy(&h->olist);
 75:   PetscFListDestroy(&h->qlist);
 76:   PetscStrfree(h->type_name);
 77:   PetscStrfree(h->name);
 78:   h->cookie = PETSCFREEDHEADER;
 79:   PetscStrfree(h->prefix);
 80:   if (h->fortran_func_pointers) {
 81:     PetscFree(h->fortran_func_pointers);
 82:   }
 83:   if (h->intcomposeddata) {
 84:     PetscFree(h->intcomposeddata);
 85:   }
 86:   if (h->intcomposedstate) {
 87:     PetscFree(h->intcomposedstate);
 88:   }
 89:   if (h->realcomposeddata) {
 90:     PetscFree(h->realcomposeddata);
 91:   }
 92:   if (h->realcomposedstate) {
 93:     PetscFree(h->realcomposedstate);
 94:   }
 95:   if (h->scalarcomposeddata) {
 96:     PetscFree(h->scalarcomposeddata);
 97:   }
 98:   if (h->scalarcomposedstate) {
 99:     PetscFree(h->scalarcomposedstate);
100:   }
101:   return(0);
102: }

106: /*@C
107:    PetscObjectReference - Indicates to any PetscObject that it is being
108:    referenced by another PetscObject. This increases the reference
109:    count for that object by one.

111:    Collective on PetscObject

113:    Input Parameter:
114: .  obj - the PETSc object. This must be cast with (PetscObject), for example, 
115:          PetscObjectReference((PetscObject)mat);

117:    Level: advanced

119: .seealso: PetscObjectCompose(), PetscObjectDereference()
120: @*/
121: PetscErrorCode PETSC_DLLEXPORT PetscObjectReference(PetscObject obj)
122: {
125:   obj->refct++;
126:   return(0);
127: }

131: /*@C
132:    PetscObjectGetReference - Gets the current reference count for 
133:    any PETSc object.

135:    Not Collective

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

141:    Output Parameter:
142: .  cnt - the reference count

144:    Level: advanced

146: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
147: @*/
148: PetscErrorCode PETSC_DLLEXPORT PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
149: {
153:   *cnt = obj->refct;
154:   return(0);
155: }

159: /*@
160:    PetscObjectDereference - Indicates to any PetscObject that it is being
161:    referenced by one less PetscObject. This decreases the reference
162:    count for that object by one.

164:    Collective on PetscObject

166:    Input Parameter:
167: .  obj - the PETSc object; this must be cast with (PetscObject), for example, 
168:          PetscObjectDereference((PetscObject)mat);

170:    Level: advanced

172: .seealso: PetscObjectCompose(), PetscObjectReference()
173: @*/
174: PetscErrorCode PETSC_DLLEXPORT PetscObjectDereference(PetscObject obj)
175: {

180:   if (obj->bops->destroy) {
181:     (*obj->bops->destroy)(obj);
182:   } else if (!--obj->refct) {
183:     SETERRQ(PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
184:   }
185:   return(0);
186: }

188: /* ----------------------------------------------------------------------- */
189: /*
190:      The following routines are the versions private to the PETSc object
191:      data structures.
192: */
195: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
196: {
198:   *comm = obj->comm;
199:   return(0);
200: }

204: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
205: {
207:   char *tname;

210:   if (ptr) {
211:     PetscOListReverseFind(ptr->olist,obj,&tname);
212:     if (tname){
213:       SETERRQ(PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was compose with it");
214:     }
215:   }
216:   PetscOListAdd(&obj->olist,name,ptr);
217:   return(0);
218: }

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

227:   PetscOListFind(obj->olist,name,ptr);
228:   return(0);
229: }

233: PetscErrorCode PetscObjectComposeLanguage_Petsc(PetscObject obj,PetscLanguage lang,void *vob)
234: {
236:   if (lang == PETSC_LANGUAGE_CXX) {
237:     obj->cpp = vob;
238:   } else {
239:     SETERRQ(PETSC_ERR_SUP,"No support for this language yet");
240:   }
241:   return(0);
242: }

246: PetscErrorCode PetscObjectQueryLanguage_Petsc(PetscObject obj,PetscLanguage lang,void **vob)
247: {
249:   if (lang == PETSC_LANGUAGE_C) {
250:     *vob = (void*)obj;
251:   } else if (lang == PETSC_LANGUAGE_CXX) {
252:     if (obj->cpp) {
253:       *vob = obj->cpp;
254:     } else {
255:       SETERRQ(PETSC_ERR_SUP,"No C++ wrapper generated");
256:     }
257:   } else {
258:     SETERRQ(PETSC_ERR_SUP,"No support for this language yet");
259:   }
260:   return(0);
261: }

265: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
266: {

270:   PetscFListAdd(&obj->qlist,name,fname,ptr);
271:   return(0);
272: }

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

281:   PetscFListFind(obj->comm,obj->qlist,name,ptr);
282:   return(0);
283: }

285: /*
286:         These are the versions that are usable to any CCA compliant objects
287: */
290: /*@C
291:    PetscObjectCompose - Associates another PETSc object with a given PETSc object. 
292:                        
293:    Not Collective

295:    Input Parameters:
296: +  obj - the PETSc object; this must be cast with (PetscObject), for example, 
297:          PetscObjectCompose((PetscObject)mat,...);
298: .  name - name associated with the child object 
299: -  ptr - the other PETSc object to associate with the PETSc object; this must also be 
300:          cast with (PetscObject)

302:    Level: advanced

304:    Notes:
305:    The second objects reference count is automatically increased by one when it is
306:    composed.

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

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

313:    PetscObjectCompose() can be used with any PETSc object (such as
314:    Mat, Vec, KSP, SNES, etc.) or any user-provided object.  See 
315:    PetscObjectContainerCreate() for info on how to create an object from a 
316:    user-provided pointer that may then be composed with PETSc objects.
317:    
318:    Concepts: objects^composing
319:    Concepts: composing objects

321: .seealso: PetscObjectQuery(), PetscObjectContainerCreate()
322: @*/
323: PetscErrorCode PETSC_DLLEXPORT PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
324: {

328:   (*obj->bops->compose)(obj,name,ptr);
329:   return(0);
330: }

334: /*@C
335:    PetscObjectQuery  - Gets a PETSc object associated with a given object.
336:                        
337:    Not Collective

339:    Input Parameters:
340: +  obj - the PETSc object
341:          Thus must be cast with a (PetscObject), for example, 
342:          PetscObjectCompose((PetscObject)mat,...);
343: .  name - name associated with child object 
344: -  ptr - the other PETSc object associated with the PETSc object, this must also be 
345:          cast with (PetscObject)

347:    Level: advanced

349:    Concepts: objects^composing
350:    Concepts: composing objects
351:    Concepts: objects^querying
352:    Concepts: querying objects

354: .seealso: PetscObjectQuery()
355: @*/
356: PetscErrorCode PETSC_DLLEXPORT PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
357: {

361:   (*obj->bops->query)(obj,name,ptr);
362:   return(0);
363: }

367: /*@C
368:    PetscObjectQueryLanguage - Returns a language specific interface to the given object
369:                        
370:    Not Collective

372:    Input Parameters:
373: +  obj - the PETSc object
374:          Thus must be cast with a (PetscObject), for example, 
375:          PetscObjectCompose((PetscObject)mat,...);
376: -  lang - one of PETSC_LANGUAGE_C, PETSC_LANGUAGE_F77, PETSC_LANGUAGE_CXX

378:    Output Parameter:
379: .  ptr - the language specific interface

381:    Level: developer

383: .seealso: PetscObjectQuery()
384: @*/
385: PetscErrorCode PETSC_DLLEXPORT PetscObjectQueryLanguage(PetscObject obj,PetscLanguage lang,void **ptr)
386: {

390:   (*obj->bops->querylanguage)(obj,lang,ptr);
391:   return(0);
392: }

396: /*@C
397:    PetscObjectComposeLanguage - Sets a language specific interface to the given object
398:                        
399:    Not Collective

401:    Input Parameters:
402: +  obj - the PETSc object
403:          Thus must be cast with a (PetscObject), for example, 
404:          PetscObjectCompose((PetscObject)mat,...);
405: .  lang - one of PETSC_LANGUAGE_C, PETSC_LANGUAGE_F77, PETSC_LANGUAGE_CXX
406: -  ptr - the language specific interface

408:    Level: developer

410: .seealso: PetscObjectQuery()
411: @*/
412: PetscErrorCode PETSC_DLLEXPORT PetscObjectComposeLanguage(PetscObject obj,PetscLanguage lang,void *ptr)
413: {

417:   (*obj->bops->composelanguage)(obj,lang,ptr);
418:   return(0);
419: }


424: PetscErrorCode PETSC_DLLEXPORT PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
425: {

429:   (*obj->bops->composefunction)(obj,name,fname,ptr);
430:   return(0);
431: }

435: /*@C
436:    PetscObjectQueryFunction - Gets a function associated with a given object.
437:                        
438:    Collective on PetscObject

440:    Input Parameters:
441: +  obj - the PETSc object; this must be cast with (PetscObject), for example, 
442:          PetscObjectQueryFunction((PetscObject)ksp,...);
443: -  name - name associated with the child function

445:    Output Parameter:
446: .  ptr - function pointer

448:    Level: advanced

450:    Concepts: objects^composing functions
451:    Concepts: composing functions
452:    Concepts: functions^querying
453:    Concepts: objects^querying
454:    Concepts: querying objects

456: .seealso: PetscObjectComposeFunctionDynamic()
457: @*/
458: PetscErrorCode PETSC_DLLEXPORT PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void))
459: {

463:   (*obj->bops->queryfunction)(obj,name,ptr);
464:   return(0);
465: }

467: struct _p_PetscObjectContainer {
468:   PETSCHEADER(int);
469:   void   *ptr;
470:   PetscErrorCode (*userdestroy)(void*);
471: };

475: /*@C
476:    PetscObjectContainerGetPointer - Gets the pointer value contained in the container.

478:    Collective on PetscObjectContainer

480:    Input Parameter:
481: .  obj - the object created with PetscObjectContainerCreate()

483:    Output Parameter:
484: .  ptr - the pointer value

486:    Level: advanced

488: .seealso: PetscObjectContainerCreate(), PetscObjectContainerDestroy(), 
489:           PetscObjectContainerSetPointer()
490: @*/
491: PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerGetPointer(PetscObjectContainer obj,void **ptr)
492: {
494:   *ptr = obj->ptr;
495:   return(0);
496: }


501: /*@C
502:    PetscObjectContainerSetPointer - Sets the pointer value contained in the container.

504:    Collective on PetscObjectContainer

506:    Input Parameters:
507: +  obj - the object created with PetscObjectContainerCreate()
508: -  ptr - the pointer value

510:    Level: advanced

512: .seealso: PetscObjectContainerCreate(), PetscObjectContainerDestroy(), 
513:           PetscObjectContainerGetPointer()
514: @*/
515: PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerSetPointer(PetscObjectContainer obj,void *ptr)
516: {
518:   obj->ptr = ptr;
519:   return(0);
520: }

524: /*@C
525:    PetscObjectContainerDestroy - Destroys a PETSc container object.

527:    Collective on PetscObjectContainer

529:    Input Parameter:
530: .  obj - an object that was created with PetscObjectContainerCreate()

532:    Level: advanced

534: .seealso: PetscObjectContainerCreate()
535: @*/
536: PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerDestroy(PetscObjectContainer obj)
537: {
540:   if (--obj->refct > 0) return(0);
541:   if (obj->userdestroy) (*obj->userdestroy)(obj->ptr);
542:   PetscHeaderDestroy(obj);
543:   return(0);
544: }

548: /*@C
549:    PetscObjectContainerSetUserDestroy - Sets name of the user destroy function.

551:    Collective on PetscObjectContainer

553:    Input Parameter:
554: +  obj - an object that was created with PetscObjectContainerCreate()
555: -  des - name of the user destroy function

557:    Level: advanced

559: .seealso: PetscObjectContainerDestroy()
560: @*/
561: PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerSetUserDestroy(PetscObjectContainer obj, PetscErrorCode (*des)(void*))
562: {
564:   obj->userdestroy = des;
565:   return(0);
566: }

568: PetscCookie PETSC_DLLEXPORT CONTAINER_COOKIE = 0;

572: /*@C
573:    PetscObjectContainerCreate - Creates a PETSc object that has room to hold
574:    a single pointer. This allows one to attach any type of data (accessible
575:    through a pointer) with the PetscObjectCompose() function to a PetscObject.
576:    The data item itself is attached by a call to PetscObjectContainerSetPointer.

578:    Collective on MPI_Comm

580:    Input Parameters:
581: .  comm - MPI communicator that shares the object

583:    Output Parameters:
584: .  container - the container created

586:    Level: advanced

588: .seealso: PetscObjectContainerDestroy(), PetscObjectContainerSetPointer(), PetscObjectContainerSetPointer()
589: @*/
590: PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerCreate(MPI_Comm comm,PetscObjectContainer *container)
591: {
592:   PetscErrorCode       ierr;
593:   PetscObjectContainer contain;

596:   if (!CONTAINER_COOKIE) {
597:     PetscLogClassRegister(&CONTAINER_COOKIE,          "Container");
598:   }
599:   PetscHeaderCreate(contain,_p_PetscObjectContainer,PetscInt,CONTAINER_COOKIE,0,"container",comm,PetscObjectContainerDestroy,0);
600:   *container = contain;
601:   return(0);
602: }

606: /*@
607:    PetscObjectSetFromOptions - Sets generic parameters from user options.

609:    Collective on obj

611:    Input Parameter:
612: .  obj - the PetscObjcet

614:    Options Database Keys:

616:    Notes:
617:    We have no generic options at present, so this does nothing

619:    Level: beginner

621: .keywords: set, options, database
622: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
623: @*/
624: PetscErrorCode PETSC_DLLEXPORT PetscObjectSetFromOptions(PetscObject obj)
625: {
627:   if (!obj) SETERRQ(PETSC_ERR_ARG_CORRUPT, "Null object");
628:   return(0);
629: }

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

636:    Collective on PetscObject

638:    Input Parameters:
639: .  obj - the PetscObject

641:    Notes:
642:    This does nothing at present.

644:    Level: advanced

646: .keywords: setup
647: .seealso: PetscObjectDestroy()
648: @*/
649: PetscErrorCode PETSC_DLLEXPORT PetscObjectSetUp(PetscObject obj)
650: {
652:   if (!obj) SETERRQ(PETSC_ERR_ARG_CORRUPT, "Null object");
653:   return(0);
654: }