Actual source code: inherit.c

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

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

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

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

 53: /*
 54:     PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by 
 55:     the macro PetscHeaderDestroy().
 56: */
 57: PetscErrorCode PetscHeaderDestroy_Private(PetscObject h)
 58: {

 62:   PetscCommDestroy(&h->comm);
 63:   PetscFree(h->bops);
 64:   PetscFree(h->ops);
 65:   PetscOListDestroy(&h->olist);
 66:   PetscFListDestroy(&h->qlist);
 67:   PetscStrfree(h->type_name);
 68:   PetscStrfree(h->name);
 69:   h->cookie = PETSCFREEDHEADER;
 70:   PetscStrfree(h->prefix);
 71:   if (h->fortran_func_pointers) {
 72:     PetscFree(h->fortran_func_pointers);
 73:   }
 74:   if (h->intcomposeddata) {
 75:     PetscFree(h->intcomposeddata);
 76:   }
 77:   if (h->intcomposedstate) {
 78:     PetscFree(h->intcomposedstate);
 79:   }
 80:   if (h->realcomposeddata) {
 81:     PetscFree(h->realcomposeddata);
 82:   }
 83:   if (h->realcomposedstate) {
 84:     PetscFree(h->realcomposedstate);
 85:   }
 86:   if (h->scalarcomposeddata) {
 87:     PetscFree(h->scalarcomposeddata);
 88:   }
 89:   if (h->scalarcomposedstate) {
 90:     PetscFree(h->scalarcomposedstate);
 91:   }
 92:   PetscFree(h);
 93:   return(0);
 94: }

 98: /*@C
 99:    PetscObjectReference - Indicates to any PetscObject that it is being
100:    referenced by another PetscObject. This increases the reference
101:    count for that object by one.

103:    Collective on PetscObject

105:    Input Parameter:
106: .  obj - the PETSc object. This must be cast with (PetscObject), for example, 
107:          PetscObjectReference((PetscObject)mat);

109:    Level: advanced

111: .seealso: PetscObjectCompose(), PetscObjectDereference()
112: @*/
113: PetscErrorCode PetscObjectReference(PetscObject obj)
114: {
117:   obj->refct++;
118:   return(0);
119: }

123: /*@C
124:    PetscObjectGetReference - Gets the current reference count for 
125:    any PETSc object.

127:    Not Collective

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

133:    Output Parameter:
134: .  cnt - the reference count

136:    Level: advanced

138: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
139: @*/
140: PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
141: {
145:   *cnt = obj->refct;
146:   return(0);
147: }

151: /*@
152:    PetscObjectDereference - Indicates to any PetscObject that it is being
153:    referenced by one less PetscObject. This decreases the reference
154:    count for that object by one.

156:    Collective on PetscObject

158:    Input Parameter:
159: .  obj - the PETSc object; this must be cast with (PetscObject), for example, 
160:          PetscObjectDereference((PetscObject)mat);

162:    Level: advanced

164: .seealso: PetscObjectCompose(), PetscObjectReference()
165: @*/
166: PetscErrorCode PetscObjectDereference(PetscObject obj)
167: {

172:   if (obj->bops->destroy) {
173:     (*obj->bops->destroy)(obj);
174:   } else if (!--obj->refct) {
175:     SETERRQ(PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
176:   }
177:   return(0);
178: }

180: /* ----------------------------------------------------------------------- */
181: /*
182:      The following routines are the versions private to the PETSc object
183:      data structures.
184: */
187: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
188: {
190:   *comm = obj->comm;
191:   return(0);
192: }

196: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
197: {
199:   char *tname;

202:   if (ptr) {
203:     PetscOListReverseFind(ptr->olist,obj,&tname);
204:     if (tname){
205:       SETERRQ(PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was compose with it");
206:     }
207:   }
208:   PetscOListAdd(&obj->olist,name,ptr);
209:   return(0);
210: }

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

219:   PetscOListFind(obj->olist,name,ptr);
220:   return(0);
221: }

225: PetscErrorCode PetscObjectComposeLanguage_Petsc(PetscObject obj,PetscLanguage lang,void *vob)
226: {
228:   if (lang == PETSC_LANGUAGE_CPP) {
229:     obj->cpp = vob;
230:   } else {
231:     SETERRQ(PETSC_ERR_SUP,"No support for this language yet");
232:   }
233:   return(0);
234: }

238: PetscErrorCode PetscObjectQueryLanguage_Petsc(PetscObject obj,PetscLanguage lang,void **vob)
239: {
241:   if (lang == PETSC_LANGUAGE_C) {
242:     *vob = (void*)obj;
243:   } else if (lang == PETSC_LANGUAGE_CPP) {
244:     if (obj->cpp) {
245:       *vob = obj->cpp;
246:     } else {
247:       SETERRQ(PETSC_ERR_SUP,"No C++ wrapper generated");
248:     }
249:   } else {
250:     SETERRQ(PETSC_ERR_SUP,"No support for this language yet");
251:   }
252:   return(0);
253: }

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

262:   PetscFListAdd(&obj->qlist,name,fname,ptr);
263:   return(0);
264: }

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

273:   PetscFListFind(obj->comm,obj->qlist,name,ptr);
274:   return(0);
275: }

277: /*
278:         These are the versions that are usable to any CCA compliant objects
279: */
282: /*@C
283:    PetscObjectCompose - Associates another PETSc object with a given PETSc object. 
284:                        
285:    Not Collective

287:    Input Parameters:
288: +  obj - the PETSc object; this must be cast with (PetscObject), for example, 
289:          PetscObjectCompose((PetscObject)mat,...);
290: .  name - name associated with the child object 
291: -  ptr - the other PETSc object to associate with the PETSc object; this must also be 
292:          cast with (PetscObject)

294:    Level: advanced

296:    Notes:
297:    The second objects reference count is automatically increased by one when it is
298:    composed.

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

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

305:    PetscObjectCompose() can be used with any PETSc object (such as
306:    Mat, Vec, KSP, SNES, etc.) or any user-provided object.  See 
307:    PetscObjectContainerCreate() for info on how to create an object from a 
308:    user-provided pointer that may then be composed with PETSc objects.
309:    
310:    Concepts: objects^composing
311:    Concepts: composing objects

313: .seealso: PetscObjectQuery(), PetscObjectContainerCreate()
314: @*/
315: PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
316: {

320:   (*obj->bops->compose)(obj,name,ptr);
321:   return(0);
322: }

326: /*@C
327:    PetscObjectQuery  - Gets a PETSc object associated with a given object.
328:                        
329:    Not Collective

331:    Input Parameters:
332: +  obj - the PETSc object
333:          Thus must be cast with a (PetscObject), for example, 
334:          PetscObjectCompose((PetscObject)mat,...);
335: .  name - name associated with child object 
336: -  ptr - the other PETSc object associated with the PETSc object, this must also be 
337:          cast with (PetscObject)

339:    Level: advanced

341:    Concepts: objects^composing
342:    Concepts: composing objects
343:    Concepts: objects^querying
344:    Concepts: querying objects

346: .seealso: PetscObjectQuery()
347: @*/
348: PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
349: {

353:   (*obj->bops->query)(obj,name,ptr);
354:   return(0);
355: }

359: /*@C
360:    PetscObjectQueryLanguage - Returns a language specific interface to the given object
361:                        
362:    Not Collective

364:    Input Parameters:
365: +  obj - the PETSc object
366:          Thus must be cast with a (PetscObject), for example, 
367:          PetscObjectCompose((PetscObject)mat,...);
368: -  lang - one of PETSC_LANGUAGE_C, PETSC_LANGUAGE_F77, PETSC_LANGUAGE_CPP

370:    Output Parameter:
371: .  ptr - the language specific interface

373:    Level: developer

375: .seealso: PetscObjectQuery()
376: @*/
377: PetscErrorCode PetscObjectQueryLanguage(PetscObject obj,PetscLanguage lang,void **ptr)
378: {

382:   (*obj->bops->querylanguage)(obj,lang,ptr);
383:   return(0);
384: }

388: /*@C
389:    PetscObjectComposeLanguage - Sets a language specific interface to the given object
390:                        
391:    Not Collective

393:    Input Parameters:
394: +  obj - the PETSc object
395:          Thus must be cast with a (PetscObject), for example, 
396:          PetscObjectCompose((PetscObject)mat,...);
397: .  lang - one of PETSC_LANGUAGE_C, PETSC_LANGUAGE_F77, PETSC_LANGUAGE_CPP
398: -  ptr - the language specific interface

400:    Level: developer

402: .seealso: PetscObjectQuery()
403: @*/
404: PetscErrorCode PetscObjectComposeLanguage(PetscObject obj,PetscLanguage lang,void *ptr)
405: {

409:   (*obj->bops->composelanguage)(obj,lang,ptr);
410:   return(0);
411: }


416: PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
417: {

421:   (*obj->bops->composefunction)(obj,name,fname,ptr);
422:   return(0);
423: }

427: /*@C
428:    PetscObjectQueryFunction - Gets a function associated with a given object.
429:                        
430:    Collective on PetscObject

432:    Input Parameters:
433: +  obj - the PETSc object; this must be cast with (PetscObject), for example, 
434:          PetscObjectQueryFunction((PetscObject)ksp,...);
435: -  name - name associated with the child function

437:    Output Parameter:
438: .  ptr - function pointer

440:    Level: advanced

442:    Concepts: objects^composing functions
443:    Concepts: composing functions
444:    Concepts: functions^querying
445:    Concepts: objects^querying
446:    Concepts: querying objects

448: .seealso: PetscObjectComposeFunctionDynamic()
449: @*/
450: PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void))
451: {

455:   (*obj->bops->queryfunction)(obj,name,ptr);
456:   return(0);
457: }

459: struct _p_PetscObjectContainer {
460:   PETSCHEADER(int)
461:   void   *ptr;
462: };

466: /*@C
467:    PetscObjectContainerGetPointer - Gets the pointer value contained in the container.

469:    Collective on PetscObjectContainer

471:    Input Parameter:
472: .  obj - the object created with PetscObjectContainerCreate()

474:    Output Parameter:
475: .  ptr - the pointer value

477:    Level: advanced

479: .seealso: PetscObjectContainerCreate(), PetscObjectContainerDestroy(), 
480:           PetscObjectContainerSetPointer()
481: @*/
482: PetscErrorCode PetscObjectContainerGetPointer(PetscObjectContainer obj,void **ptr)
483: {
485:   *ptr = obj->ptr;
486:   return(0);
487: }


492: /*@C
493:    PetscObjectContainerSetPointer - Sets the pointer value contained in the container.

495:    Collective on PetscObjectContainer

497:    Input Parameters:
498: +  obj - the object created with PetscObjectContainerCreate()
499: -  ptr - the pointer value

501:    Level: advanced

503: .seealso: PetscObjectContainerCreate(), PetscObjectContainerDestroy(), 
504:           PetscObjectContainerGetPointer()
505: @*/
506: PetscErrorCode PetscObjectContainerSetPointer(PetscObjectContainer obj,void *ptr)
507: {
509:   obj->ptr = ptr;
510:   return(0);
511: }

515: /*@C
516:    PetscObjectContainerDestroy - Destroys a PETSc container object.

518:    Collective on PetscObjectContainer

520:    Input Parameter:
521: .  obj - an object that was created with PetscObjectContainerCreate()

523:    Level: advanced

525: .seealso: PetscObjectContainerCreate()
526: @*/
527: PetscErrorCode PetscObjectContainerDestroy(PetscObjectContainer obj)
528: {
530:   if (--obj->refct > 0) return(0);
531:   PetscHeaderDestroy(obj);
532:   return(0);
533: }

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

543:    Collective on MPI_Comm

545:    Input Parameters:
546: .  comm - MPI communicator that shares the object

548:    Output Parameters:
549: .  container - the container created

551:    Level: advanced

553: .seealso: PetscObjectContainerDestroy(), PetscObjectContainerSetPointer(), PetscObjectContainerSetPointer()
554: @*/
555: PetscErrorCode PetscObjectContainerCreate(MPI_Comm comm,PetscObjectContainer *container)
556: {
557:   PetscObjectContainer contain;

560:   PetscHeaderCreate(contain,_p_PetscObjectContainer,PetscInt,PETSC_COOKIE,0,"container",comm,PetscObjectContainerDestroy,0);
561:   *container = contain;
562:   return(0);
563: }