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));

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

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


 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:   if (PetscMemoryCollectMaximumUsage) {
 63:     PetscLogDouble usage;
 64:     PetscMemoryGetCurrentUsage(&usage);
 65:     if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
 66:   }
 67:   PetscCommDestroy(&h->comm);
 68:   PetscFree(h->bops);
 69:   PetscFree(h->ops);
 70:   PetscOListDestroy(&h->olist);
 71:   PetscFListDestroy(&h->qlist);
 72:   PetscStrfree(h->type_name);
 73:   PetscStrfree(h->name);
 74:   h->cookie = PETSCFREEDHEADER;
 75:   PetscStrfree(h->prefix);
 76:   PetscFree(h->fortran_func_pointers);
 77:   PetscFree(h->intcomposeddata);
 78:   PetscFree(h->intcomposedstate);
 79:   PetscFree(h->realcomposeddata);
 80:   PetscFree(h->realcomposedstate);
 81:   PetscFree(h->scalarcomposeddata);
 82:   PetscFree(h->scalarcomposedstate);
 83:   return(0);
 84: }

 88: /*@C
 89:    PetscObjectReference - Indicates to any PetscObject that it is being
 90:    referenced by another PetscObject. This increases the reference
 91:    count for that object by one.

 93:    Collective on PetscObject

 95:    Input Parameter:
 96: .  obj - the PETSc object. This must be cast with (PetscObject), for example, 
 97:          PetscObjectReference((PetscObject)mat);

 99:    Level: advanced

101: .seealso: PetscObjectCompose(), PetscObjectDereference()
102: @*/
103: PetscErrorCode  PetscObjectReference(PetscObject obj)
104: {
107:   obj->refct++;
108:   return(0);
109: }

113: /*@C
114:    PetscObjectGetReference - Gets the current reference count for 
115:    any PETSc object.

117:    Not Collective

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

123:    Output Parameter:
124: .  cnt - the reference count

126:    Level: advanced

128: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
129: @*/
130: PetscErrorCode  PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
131: {
135:   *cnt = obj->refct;
136:   return(0);
137: }

141: /*@
142:    PetscObjectDereference - Indicates to any PetscObject that it is being
143:    referenced by one less PetscObject. This decreases the reference
144:    count for that object by one.

146:    Collective on PetscObject

148:    Input Parameter:
149: .  obj - the PETSc object; this must be cast with (PetscObject), for example, 
150:          PetscObjectDereference((PetscObject)mat);

152:    Level: advanced

154: .seealso: PetscObjectCompose(), PetscObjectReference()
155: @*/
156: PetscErrorCode  PetscObjectDereference(PetscObject obj)
157: {

162:   if (obj->bops->destroy) {
163:     (*obj->bops->destroy)(obj);
164:   } else if (!--obj->refct) {
165:     SETERRQ(PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
166:   }
167:   return(0);
168: }

170: /* ----------------------------------------------------------------------- */
171: /*
172:      The following routines are the versions private to the PETSc object
173:      data structures.
174: */
177: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
178: {
180:   *comm = obj->comm;
181:   return(0);
182: }

186: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
187: {
189:   char *tname;

192:   if (ptr) {
193:     PetscOListReverseFind(ptr->olist,obj,&tname);
194:     if (tname){
195:       SETERRQ(PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was compose with it");
196:     }
197:   }
198:   PetscOListAdd(&obj->olist,name,ptr);
199:   return(0);
200: }

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

209:   PetscOListFind(obj->olist,name,ptr);
210:   return(0);
211: }

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

220:   PetscFListAdd(&obj->qlist,name,fname,ptr);
221:   return(0);
222: }

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

231:   PetscFListFind(obj->comm,obj->qlist,name,ptr);
232:   return(0);
233: }

235: /*
236:         These are the versions that are usable to any CCA compliant objects
237: */
240: /*@C
241:    PetscObjectCompose - Associates another PETSc object with a given PETSc object. 
242:                        
243:    Not Collective

245:    Input Parameters:
246: +  obj - the PETSc object; this must be cast with (PetscObject), for example, 
247:          PetscObjectCompose((PetscObject)mat,...);
248: .  name - name associated with the child object 
249: -  ptr - the other PETSc object to associate with the PETSc object; this must also be 
250:          cast with (PetscObject)

252:    Level: advanced

254:    Notes:
255:    The second objects reference count is automatically increased by one when it is
256:    composed.

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

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

263:    PetscObjectCompose() can be used with any PETSc object (such as
264:    Mat, Vec, KSP, SNES, etc.) or any user-provided object.  See 
265:    PetscContainerCreate() for info on how to create an object from a 
266:    user-provided pointer that may then be composed with PETSc objects.
267:    
268:    Concepts: objects^composing
269:    Concepts: composing objects

271: .seealso: PetscObjectQuery(), PetscContainerCreate()
272: @*/
273: PetscErrorCode  PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
274: {

278:   (*obj->bops->compose)(obj,name,ptr);
279:   return(0);
280: }

284: /*@C
285:    PetscObjectQuery  - Gets a PETSc object associated with a given object.
286:                        
287:    Not Collective

289:    Input Parameters:
290: +  obj - the PETSc object
291:          Thus must be cast with a (PetscObject), for example, 
292:          PetscObjectCompose((PetscObject)mat,...);
293: .  name - name associated with child object 
294: -  ptr - the other PETSc object associated with the PETSc object, this must also be 
295:          cast with (PetscObject)

297:    Level: advanced

299:    Concepts: objects^composing
300:    Concepts: composing objects
301:    Concepts: objects^querying
302:    Concepts: querying objects

304: .seealso: PetscObjectQuery()
305: @*/
306: PetscErrorCode  PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
307: {

311:   (*obj->bops->query)(obj,name,ptr);
312:   return(0);
313: }

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

322:   (*obj->bops->composefunction)(obj,name,fname,ptr);
323:   return(0);
324: }

328: /*@C
329:    PetscObjectQueryFunction - Gets a function associated with a given object.
330:                        
331:    Collective on PetscObject

333:    Input Parameters:
334: +  obj - the PETSc object; this must be cast with (PetscObject), for example, 
335:          PetscObjectQueryFunction((PetscObject)ksp,...);
336: -  name - name associated with the child function

338:    Output Parameter:
339: .  ptr - function pointer

341:    Level: advanced

343:    Concepts: objects^composing functions
344:    Concepts: composing functions
345:    Concepts: functions^querying
346:    Concepts: objects^querying
347:    Concepts: querying objects

349: .seealso: PetscObjectComposeFunctionDynamic()
350: @*/
351: PetscErrorCode  PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void))
352: {

356:   (*obj->bops->queryfunction)(obj,name,ptr);
357:   return(0);
358: }

360: struct _p_PetscContainer {
361:   PETSCHEADER(int);
362:   void   *ptr;
363:   PetscErrorCode (*userdestroy)(void*);
364: };

368: /*@C
369:    PetscContainerGetPointer - Gets the pointer value contained in the container.

371:    Collective on PetscContainer

373:    Input Parameter:
374: .  obj - the object created with PetscContainerCreate()

376:    Output Parameter:
377: .  ptr - the pointer value

379:    Level: advanced

381: .seealso: PetscContainerCreate(), PetscContainerDestroy(), 
382:           PetscContainerSetPointer()
383: @*/
384: PetscErrorCode  PetscContainerGetPointer(PetscContainer obj,void **ptr)
385: {
387:   *ptr = obj->ptr;
388:   return(0);
389: }


394: /*@C
395:    PetscContainerSetPointer - Sets the pointer value contained in the container.

397:    Collective on PetscContainer

399:    Input Parameters:
400: +  obj - the object created with PetscContainerCreate()
401: -  ptr - the pointer value

403:    Level: advanced

405: .seealso: PetscContainerCreate(), PetscContainerDestroy(), 
406:           PetscContainerGetPointer()
407: @*/
408: PetscErrorCode  PetscContainerSetPointer(PetscContainer obj,void *ptr)
409: {
411:   obj->ptr = ptr;
412:   return(0);
413: }

417: /*@C
418:    PetscContainerDestroy - Destroys a PETSc container object.

420:    Collective on PetscContainer

422:    Input Parameter:
423: .  obj - an object that was created with PetscContainerCreate()

425:    Level: advanced

427: .seealso: PetscContainerCreate()
428: @*/
429: PetscErrorCode  PetscContainerDestroy(PetscContainer obj)
430: {
433:   if (--obj->refct > 0) return(0);
434:   if (obj->userdestroy) (*obj->userdestroy)(obj->ptr);
435:   PetscHeaderDestroy(obj);
436:   return(0);
437: }

441: /*@C
442:    PetscContainerSetUserDestroy - Sets name of the user destroy function.

444:    Collective on PetscContainer

446:    Input Parameter:
447: +  obj - an object that was created with PetscContainerCreate()
448: -  des - name of the user destroy function

450:    Level: advanced

452: .seealso: PetscContainerDestroy()
453: @*/
454: PetscErrorCode  PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
455: {
457:   obj->userdestroy = des;
458:   return(0);
459: }

461: PetscCookie  PETSC_CONTAINER_COOKIE = 0;

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

471:    Collective on MPI_Comm

473:    Input Parameters:
474: .  comm - MPI communicator that shares the object

476:    Output Parameters:
477: .  container - the container created

479:    Level: advanced

481: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
482: @*/
483: PetscErrorCode  PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
484: {
485:   PetscErrorCode       ierr;
486:   PetscContainer contain;

489:   if (!PETSC_CONTAINER_COOKIE) {
490:     PetscLogClassRegister(&PETSC_CONTAINER_COOKIE, "Container");
491:   }
492:   PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_COOKIE,0,"PetscContainer",comm,PetscContainerDestroy,0);
493:   *container = contain;
494:   return(0);
495: }

499: /*@
500:    PetscObjectSetFromOptions - Sets generic parameters from user options.

502:    Collective on obj

504:    Input Parameter:
505: .  obj - the PetscObjcet

507:    Options Database Keys:

509:    Notes:
510:    We have no generic options at present, so this does nothing

512:    Level: beginner

514: .keywords: set, options, database
515: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
516: @*/
517: PetscErrorCode  PetscObjectSetFromOptions(PetscObject obj)
518: {
520:   if (!obj) SETERRQ(PETSC_ERR_ARG_CORRUPT, "Null object");
521:   return(0);
522: }

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

529:    Collective on PetscObject

531:    Input Parameters:
532: .  obj - the PetscObject

534:    Notes:
535:    This does nothing at present.

537:    Level: advanced

539: .keywords: setup
540: .seealso: PetscObjectDestroy()
541: @*/
542: PetscErrorCode  PetscObjectSetUp(PetscObject obj)
543: {
545:   if (!obj) SETERRQ(PETSC_ERR_ARG_CORRUPT, "Null object");
546:   return(0);
547: }