Actual source code: petscimpl.h

  2: /*
  3:     Defines the basic header of all PETSc objects.
  4: */

  6: #if !defined(_PETSCHEAD_H)
  7: #define _PETSCHEAD_H
  8: #include "petsc.h"  

 11: /*
 12:    All major PETSc data structures have a common core; this is defined 
 13:    below by PETSCHEADER. 

 15:    PetscHeaderCreate() should be used whenever creating a PETSc structure.
 16: */

 18: /*
 19:    PetscOps: structure of core operations that all PETSc objects support.
 20:    
 21:       getcomm()         - Gets the object's communicator.
 22:       view()            - Is the routine for viewing the entire PETSc object; for
 23:                           example, MatView() is the general matrix viewing routine.
 24:       destroy()         - Is the routine for destroying the entire PETSc object; 
 25:                           for example,MatDestroy() is the general matrix 
 26:                           destruction routine.
 27:       compose()         - Associates a PETSc object with another PETSc object.
 28:       query()           - Returns a different PETSc object that has been associated
 29:                           with the first object.
 30:       composefunction() - Attaches an additional registered function.
 31:       queryfunction()   - Requests a registered function that has been registered.
 32:       publish()         - Not currently used
 33: */

 35: typedef struct {
 36:    PetscErrorCode (*getcomm)(PetscObject,MPI_Comm *);
 37:    PetscErrorCode (*view)(PetscObject,PetscViewer);
 38:    PetscErrorCode (*destroy)(PetscObject);
 39:    PetscErrorCode (*compose)(PetscObject,const char[],PetscObject);
 40:    PetscErrorCode (*query)(PetscObject,const char[],PetscObject *);
 41:    PetscErrorCode (*composefunction)(PetscObject,const char[],const char[],void (*)(void));
 42:    PetscErrorCode (*queryfunction)(PetscObject,const char[],void (**)(void));
 43:    PetscErrorCode (*publish)(PetscObject);
 44: } PetscOps;

 46: /*
 47:    All PETSc objects begin with the fields defined in PETSCHEADER.
 48:    The PetscObject is a way of examining these fields regardless of 
 49:    the specific object. In C++ this could be a base abstract class
 50:    from which all objects are derived.
 51: */
 52: typedef struct _p_PetscObject {
 53:   PetscCookie    cookie;
 54:   PetscOps       *bops;
 55:   MPI_Comm       comm;
 56:   PetscInt       type;
 57:   PetscLogDouble flops,time,mem;
 58:   PetscInt       id;
 59:   PetscInt       refct;
 60:   PetscMPIInt    tag;
 61:   PetscFList     qlist;
 62:   PetscOList     olist;
 63:   char           *class_name;
 64:   char           *type_name;
 65:   PetscObject    parent;
 66:   PetscInt       parentid;
 67:   char*          name;
 68:   char           *prefix;
 69:   PetscInt       tablevel;
 70:   void           *cpp;
 71:   PetscInt       amem;
 72:   PetscInt       state;
 73:   PetscInt       int_idmax,        intstar_idmax;
 74:   PetscInt       *intcomposedstate,*intstarcomposedstate;
 75:   PetscInt       *intcomposeddata, **intstarcomposeddata;
 76:   PetscInt       real_idmax,        realstar_idmax;
 77:   PetscInt       *realcomposedstate,*realstarcomposedstate;
 78:   PetscReal      *realcomposeddata, **realstarcomposeddata;
 79:   PetscInt       scalar_idmax,        scalarstar_idmax;
 80:   PetscInt       *scalarcomposedstate,*scalarstarcomposedstate;
 81:   PetscScalar    *scalarcomposeddata, **scalarstarcomposeddata;
 82:   void           (**fortran_func_pointers)(void);                  /* used by Fortran interface functions to stash user provided Fortran functions */
 83:   void           *python_context;
 84:   PetscErrorCode (*python_destroy)(void*);
 85: } _p_PetscObject;

 87: #define PETSCHEADER(ObjectOps) \
 88:   _p_PetscObject hdr;               \
 89:   ObjectOps      *ops

 91: #define  PETSCFREEDHEADER -1

 94: typedef PetscErrorCode (*PetscObjectViewerFunction)(PetscObject,PetscViewer);

 96: /*@C
 97:     PetscHeaderCreate - Creates a PETSc object

 99:     Input Parameters:
100: +   tp - the data structure type of the object
101: .   pops - the data structure type of the objects operations (for example VecOps)
102: .   cook - the cookie associated with this object
103: .   t - type (no longer should be used)
104: .   class_name - string name of class; should be static
105: .   com - the MPI Communicator
106: .   des - the destroy routine for this object
107: -   vie - the view routine for this object

109:     Output Parameter:
110: .   h - the newly created object

112:     Level: developer

114: .seealso: PetscHeaderDestroy(), PetscCookieRegister()

116: @*/
117: #define PetscHeaderCreate(h,tp,pops,cook,t,class_name,com,des,vie)        \
118:   (PetscNew(struct tp,&(h)) ||                                                \
119:    PetscNew(PetscOps,&(((PetscObject)(h))->bops)) ||                        \
120:    PetscNew(pops,&((h)->ops)) ||                                        \
121:    PetscHeaderCreate_Private((PetscObject)h,cook,t,class_name,com,(PetscObjectFunction)des,(PetscObjectViewerFunction)vie) || \
122:    PetscLogObjectCreate(h) ||                                                \
123:    PetscLogObjectMemory(h, sizeof(struct tp) + sizeof(PetscOps) + sizeof(pops)))

125: EXTERN PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj);
126: EXTERN PetscErrorCode  PetscHeaderCreate_Private(PetscObject,PetscCookie,PetscInt,const char[],MPI_Comm,PetscErrorCode (*)(PetscObject),PetscErrorCode (*)(PetscObject,PetscViewer));

128: /*@C
129:     PetscHeaderDestroy - Final step in destroying a PetscObject

131:     Input Parameters:
132: .   h - the header created with PetscHeaderCreate()

134:     Level: developer

136: .seealso: PetscHeaderCreate()
137: @*/
138: #define PetscHeaderDestroy(h)                           \
139:   (PetscLogObjectDestroy((PetscObject)(h)) ||           \
140:    PetscComposedQuantitiesDestroy((PetscObject)h) || \
141:    PetscHeaderDestroy_Private((PetscObject)(h)) || \
142:    PetscFree((h)->ops) ||                           \
143:    PetscFree(h))

145: EXTERN PetscErrorCode  PetscHeaderDestroy_Private(PetscObject);

147: /* ---------------------------------------------------------------------------------------*/

149: #if !defined(PETSC_USE_DEBUG)


158: #elif !defined(PETSC_HAVE_UNALIGNED_POINTERS)
159: /* 
160:     Macros to test if a PETSc object is valid and if pointers are
161: valid

163: */
165:   {if (!h) {SETERRQ1(PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg);}          \
166:   if ((unsigned long)h & (unsigned long)3) {                                          \
167:     SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Invalid Pointer to Object: Parameter # %d",arg);   \
168:   }                                                                                   \
169:   if (((PetscObject)(h))->cookie != ck) {                                             \
170:     if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) {                             \
171:       SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg);       \
172:     } else {                                                                          \
173:       SETERRQ1(PETSC_ERR_ARG_WRONG,"Wrong type of object: Parameter # %d",arg);       \
174:     }                                                                                 \
175:   }} 

178:   {if (!h) {SETERRQ1(PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg);}             \
179:   if ((unsigned long)h & (unsigned long)3) {                                             \
180:     SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Invalid Pointer to Object: Parameter # %d",arg);     \
181:   } else if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) {                           \
182:       SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg);         \
183:   } else if (((PetscObject)(h))->cookie < PETSC_SMALLEST_COOKIE ||                                \
184:       ((PetscObject)(h))->cookie > PETSC_LARGEST_COOKIE) {                               \
185:       SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Invalid type of object: Parameter # %d",arg);      \
186:   }}

189:   {if (!h) {SETERRQ1(PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);}             \
190:   if ((unsigned long)h & (unsigned long)3){                                               \
191:     SETERRQ1(PETSC_ERR_ARG_BADPTR,"Invalid Pointer: Parameter # %d",arg);                 \
192:   }}

195:   {if (!h) {SETERRQ1(PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);}              \
196:   }

199:   {if (!h) {SETERRQ1(PETSC_ERR_ARG_BADPTR,"Null Pointer: Parameter # %d",arg);}            \
200:   if ((unsigned long)h & (unsigned long)3){                                                \
201:     SETERRQ1(PETSC_ERR_ARG_BADPTR,"Invalid Pointer to Int: Parameter # %d",arg);           \
202:   }}

204: #if !defined(PETSC_HAVE_DOUBLES_ALIGNED) || defined (PETSC_HAVE_DOUBLES_ALIGNED)
206:   {if (!h) {SETERRQ1(PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);}               \
207:   if ((unsigned long)h & (unsigned long)3) {                                                \
208:     SETERRQ1(PETSC_ERR_ARG_BADPTR,"Invalid Pointer to PetscScalar: Parameter # %d",arg);    \
209:   }}
210: #else
212:   {if (!h) {SETERRQ1(PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);}               \
213:   if ((unsigned long)h & (unsigned long)7) {                                                \
214:     SETERRQ1(PETSC_ERR_ARG_BADPTR,"Invalid Pointer to PetscScalar: Parameter # %d",arg);    \
215:   }}
216: #endif

218: #else
219: /*
220:      Version for Cray 90 that handles pointers differently
221: */
223:   {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Object");}        \
224:   if (((PetscObject)(h))->cookie != ck) {                           \
225:     if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) {           \
226:       SETERRQ(PETSC_ERR_ARG_CORRUPT,"Object already free");       \
227:     } else {                                                        \
228:       SETERRQ(PETSC_ERR_ARG_WRONG,"Wrong Object");                \
229:     }                                                               \
230:   }} 

233:   {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Object");}        \
234:   if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) {      \
235:       SETERRQ(PETSC_ERR_ARG_CORRUPT,"Object already free");       \
236:   } else if (((PetscObject)(h))->cookie < PETSC_SMALLEST_COOKIE ||           \
237:       ((PetscObject)(h))->cookie > PETSC_LARGEST_COOKIE) {          \
238:       SETERRQ(PETSC_ERR_ARG_CORRUPT,"Invalid type of object");            \
239:   }}

242:   {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Pointer");}        \
243:   }

246:   {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Pointer");}        \
247:   }

250:   {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Pointer");}        \
251:   }

253: #if !defined(PETSC_HAVE_DOUBLES_ALIGNED)
255:   {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Pointer");}        \
256:   }
257: #else
259:   {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Pointer");}        \
260:   }
261: #endif

263: #endif

266: #if !defined(PETSC_USE_DEBUG)


273: #else

275: /*
276:     For example, in the dot product between two vectors,
277:   both vectors must be either Seq or MPI, not one of each 
278: */
280:   if (((PetscObject)a)->type != ((PetscObject)b)->type) SETERRQ2(PETSC_ERR_ARG_NOTSAMETYPE,"Objects not of same type: Argument # %d and %d",arga,argb);
281: /* 
282:    Use this macro to check if the type is set
283: */
285:   if (!((PetscObject)a)->type_name) SETERRQ2(PETSC_ERR_ARG_WRONGSTATE,"%s object's type is not set: Argument # %d",((PetscObject)a)->class_name,arg);
286: /*
287:    Sometimes object must live on same communicator to inter-operate
288: */
290:   {PetscErrorCode _6_ierr,__flag; _6_MPI_Comm_compare(((PetscObject)a)->comm,((PetscObject)b)->comm,&__flag);\
291:   CHKERRQ(_6_ierr); \
292:   if (__flag != MPI_CONGRUENT && __flag != MPI_IDENT) \
293:   SETERRQ2(PETSC_ERR_ARG_NOTSAMECOMM,"Different communicators in the two objects: Argument # %d and %d",arga,argb);}


299: #endif

301: EXTERN PetscErrorCode  PetscObjectPublishBaseBegin(PetscObject);
302: EXTERN PetscErrorCode  PetscObjectPublishBaseEnd(PetscObject);

304: /*MC
305:    PetscObjectStateIncrease - Increases the state of any PetscObject, 
306:    regardless of the type.

308:    Synopsis:
309:    PetscErrorCode PetscObjectStateIncrease(PetscObject obj)

311:    Not Collective

313:    Input Parameter:
314: .  obj - any PETSc object, for example a Vec, Mat or KSP. This must be
315:          cast with a (PetscObject), for example, 
316:          PetscObjectStateIncrease((PetscObject)mat);

318:    Notes: object state is an integer which gets increased every time
319:    the object is changed. By saving and later querying the object state
320:    one can determine whether information about the object is still current.
321:    Currently, state is maintained for Vec and Mat objects.

323:    This routine is mostly for internal use by PETSc; a developer need only
324:    call it after explicit access to an object's internals. Routines such
325:    as VecSet or MatScale already call this routine. It is also called, as a 
326:    precaution, in VecRestoreArray, MatRestoreRow, MatRestoreArray.

328:    Level: developer

330:    seealso: PetscObjectStateQuery(), PetscObjectStateDecrease()

332:    Concepts: state

334: M*/
335: #define PetscObjectStateIncrease(obj) ((obj)->state++,0)

337: /*MC
338:    PetscObjectStateDecrease - Decreases the state of any PetscObject, 
339:    regardless of the type.

341:    Synopsis:
342:    PetscErrorCode PetscObjectStateDecrease(PetscObject obj)

344:    Not Collective

346:    Input Parameter:
347: .  obj - any PETSc object, for example a Vec, Mat or KSP. This must be
348:          cast with a (PetscObject), for example, 
349:          PetscObjectStateIncrease((PetscObject)mat);

351:    Notes: object state is an integer which gets increased every time
352:    the object is changed. By saving and later querying the object state
353:    one can determine whether information about the object is still current.
354:    Currently, state is maintained for Vec and Mat objects.

356:    Level: developer

358:    seealso: PetscObjectStateQuery(), PetscObjectStateIncrease()

360:    Concepts: state

362: M*/
363: #define PetscObjectStateDecrease(obj) ((obj)->state--,0)

365: EXTERN PetscErrorCode  PetscObjectStateQuery(PetscObject,PetscInt*);
366: EXTERN PetscErrorCode  PetscObjectSetState(PetscObject,PetscInt);
367: EXTERN PetscErrorCode  PetscObjectComposedDataRegister(PetscInt*);
368: EXTERN PetscErrorCode  PetscObjectComposedDataIncreaseInt(PetscObject);
369: EXTERN PetscErrorCode  PetscObjectComposedDataIncreaseIntstar(PetscObject);
370: EXTERN PetscErrorCode  PetscObjectComposedDataIncreaseReal(PetscObject);
371: EXTERN PetscErrorCode  PetscObjectComposedDataIncreaseRealstar(PetscObject);
372: EXTERN PetscErrorCode  PetscObjectComposedDataIncreaseScalar(PetscObject);
373: EXTERN PetscErrorCode  PetscObjectComposedDataIncreaseScalarstar(PetscObject);
374: EXTERN PetscInt        globalcurrentstate;
375: EXTERN PetscInt        globalmaxstate;
376: /*MC
377:    PetscObjectComposedDataSetInt - attach integer data to a PetscObject

379:    Synopsis:
380:    PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)

382:    Not collective

384:    Input parameters:
385: +  obj - the object to which data is to be attached
386: .  id - the identifier for the data
387: -  data - the data to  be attached

389:    Notes
390:    The data identifier can best be determined through a call to
391:    PetscObjectComposedDataRegister()

393:    Level: developer
394: M*/
395: #define PetscObjectComposedDataSetInt(obj,id,data)                                      \
396:   ((((obj)->int_idmax < globalmaxstate) ? PetscObjectComposedDataIncreaseInt(obj) : 0), \
397:    (obj)->intcomposeddata[id] = data,(obj)->intcomposedstate[id] = (obj)->state, 0)

399: /*MC
400:    PetscObjectComposedDataGetInt - retrieve integer data attached to an object

402:    Synopsis:
403:    PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int *data,PetscTruth *flag)

405:    Not collective

407:    Input parameters:
408: +  obj - the object from which data is to be retrieved
409: -  id - the identifier for the data

411:    Output parameters
412: +  data - the data to be retrieved
413: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

415:    The 'data' and 'flag' variables are inlined, so they are not pointers.

417:    Level: developer
418: M*/
419: #define PetscObjectComposedDataGetInt(obj,id,data,flag)                            \
420:   ((((obj)->intcomposedstate && ((obj)->intcomposedstate[id] == (obj)->state)) ?   \
421:    (data = (obj)->intcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

423: /*MC
424:    PetscObjectComposedDataSetIntstar - attach integer array data to a PetscObject

426:    Synopsis:
427:    PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)

429:    Not collective

431:    Input parameters:
432: +  obj - the object to which data is to be attached
433: .  id - the identifier for the data
434: -  data - the data to  be attached

436:    Notes
437:    The data identifier can best be determined through a call to
438:    PetscObjectComposedDataRegister()

440:    Level: developer
441: M*/
442: #define PetscObjectComposedDataSetIntstar(obj,id,data)                                          \
443:   ((((obj)->intstar_idmax < globalmaxstate) ? PetscObjectComposedDataIncreaseIntstar(obj) : 0), \
444:   (obj)->intstarcomposeddata[id] = data,(obj)->intstarcomposedstate[id] = (obj)->state, 0)

446: /*MC
447:    PetscObjectComposedDataGetIntstar - retrieve integer array data 
448:    attached to an object

450:    Synopsis:
451:    PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int **data,PetscTruth *flag)

453:    Not collective

455:    Input parameters:
456: +  obj - the object from which data is to be retrieved
457: -  id - the identifier for the data

459:    Output parameters
460: +  data - the data to be retrieved
461: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

463:    The 'data' and 'flag' variables are inlined, so they are not pointers.

465:    Level: developer
466: M*/
467: #define PetscObjectComposedDataGetIntstar(obj,id,data,flag)                               \
468:   ((((obj)->intstarcomposedstate && ((obj)->intstarcomposedstate[id] == (obj)->state)) ?  \
469:    (data = (obj)->intstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

471: /*MC
472:    PetscObjectComposedDataSetReal - attach real data to a PetscObject

474:    Synopsis:
475:    PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)

477:    Not collective

479:    Input parameters:
480: +  obj - the object to which data is to be attached
481: .  id - the identifier for the data
482: -  data - the data to  be attached

484:    Notes
485:    The data identifier can best be determined through a call to
486:    PetscObjectComposedDataRegister()

488:    Level: developer
489: M*/
490: #define PetscObjectComposedDataSetReal(obj,id,data)                                       \
491:   ((((obj)->real_idmax < globalmaxstate) ? PetscObjectComposedDataIncreaseReal(obj) : 0), \
492:    (obj)->realcomposeddata[id] = data,(obj)->realcomposedstate[id] = (obj)->state, 0)

494: /*MC
495:    PetscObjectComposedDataGetReal - retrieve real data attached to an object

497:    Synopsis:
498:    PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal *data,PetscTruth *flag)

500:    Not collective

502:    Input parameters:
503: +  obj - the object from which data is to be retrieved
504: -  id - the identifier for the data

506:    Output parameters
507: +  data - the data to be retrieved
508: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

510:    The 'data' and 'flag' variables are inlined, so they are not pointers.

512:    Level: developer
513: M*/
514: #define PetscObjectComposedDataGetReal(obj,id,data,flag)                            \
515:   ((((obj)->realcomposedstate && ((obj)->realcomposedstate[id] == (obj)->state)) ?  \
516:    (data = (obj)->realcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

518: /*MC
519:    PetscObjectComposedDataSetRealstar - attach real array data to a PetscObject

521:    Synopsis:
522:    PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)

524:    Not collective

526:    Input parameters:
527: +  obj - the object to which data is to be attached
528: .  id - the identifier for the data
529: -  data - the data to  be attached

531:    Notes
532:    The data identifier can best be determined through a call to
533:    PetscObjectComposedDataRegister()

535:    Level: developer
536: M*/
537: #define PetscObjectComposedDataSetRealstar(obj,id,data)                                           \
538:   ((((obj)->realstar_idmax < globalmaxstate) ? PetscObjectComposedDataIncreaseRealstar(obj) : 0), \
539:   (obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0)

541: /*MC
542:    PetscObjectComposedDataGetRealstar - retrieve real array data
543:    attached to an object

545:    Synopsis:
546:    PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal **data,PetscTruth *flag)

548:    Not collective

550:    Input parameters:
551: +  obj - the object from which data is to be retrieved
552: -  id - the identifier for the data

554:    Output parameters
555: +  data - the data to be retrieved
556: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

558:    The 'data' and 'flag' variables are inlined, so they are not pointers.

560:    Level: developer
561: M*/
562: #define PetscObjectComposedDataGetRealstar(obj,id,data,flag)                                \
563:   ((((obj)->realstarcomposedstate && ((obj)->realstarcomposedstate[id] == (obj)->state)) ?  \
564:    (data = (obj)->realstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

566: /*MC
567:    PetscObjectSetScalarComposedData - attach scalar data to a PetscObject 

569:    Synopsis:
570:    PetscErrorCode PetscObjectSetScalarComposedData(PetscObject obj,int id,PetscScalar data)

572:    Not collective

574:    Input parameters:
575: +  obj - the object to which data is to be attached
576: .  id - the identifier for the data
577: -  data - the data to  be attached

579:    Notes
580:    The data identifier can best be determined through a call to
581:    PetscObjectComposedDataRegister()

583:    Level: developer
584: M*/
585: #if defined(PETSC_USE_COMPLEX)
586: #define PetscObjectComposedDataSetScalar(obj,id,data)                                        \
587:   ((((obj)->scalar_idmax < globalmaxstate) ? PetscObjectComposedDataIncreaseScalar(obj) : 0) \
588:   (obj)->scalarcomposeddata[id] = data,(obj)->scalarcomposedstate[id] = (obj)->state, 0)
589: #else
590: #define PetscObjectComposedDataSetScalar(obj,id,data) \
591:         PetscObjectComposedDataSetReal(obj,id,data)
592: #endif
593: /*MC
594:    PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object

596:    Synopsis:
597:    PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar *data,PetscTruth *flag)

599:    Not collective

601:    Input parameters:
602: +  obj - the object from which data is to be retrieved
603: -  id - the identifier for the data

605:    Output parameters
606: +  data - the data to be retrieved
607: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

609:    The 'data' and 'flag' variables are inlined, so they are not pointers.

611:    Level: developer
612: M*/
613: #if defined(PETSC_USE_COMPLEX)
614: #define PetscObjectComposedDataGetScalar(obj,id,data,flag)                              \
615:   ((((obj)->scalarcomposedstate && ((obj)->scalarcomposedstate[id] == (obj)->state) ) ? \
616:    (data = (obj)->scalarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
617: #else
618: #define PetscObjectComposedDataGetScalar(obj,id,data,flag)                             \
619:         PetscObjectComposedDataGetReal(obj,id,data,flag)
620: #endif

622: /*MC
623:    PetscObjectComposedDataSetScalarstar - attach scalar array data to a PetscObject 

625:    Synopsis:
626:    PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)

628:    Not collective

630:    Input parameters:
631: +  obj - the object to which data is to be attached
632: .  id - the identifier for the data
633: -  data - the data to  be attached

635:    Notes
636:    The data identifier can best be determined through a call to
637:    PetscObjectComposedDataRegister()

639:    Level: developer
640: M*/
641: #if defined(PETSC_USE_COMPLEX)
642: #define PetscObjectComposedDataSetScalarstar(obj,id,data)                                             \
643:   ((((obj)->scalarstar_idmax < globalmaxstate) ? PetscObjectComposedDataIncreaseScalarstar(obj) : 0), \
644:    (obj)->scalarstarcomposeddata[id] = data,(obj)->scalarstarcomposedstate[id] = (obj)->state, 0)
645: #else
646: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
647:         PetscObjectComposedDataSetRealstar(obj,id,data)
648: #endif
649: /*MC
650:    PetscObjectComposedDataGetScalarstar - retrieve scalar array data
651:    attached to an object

653:    Synopsis:
654:    PetscErrorCode PetscObjectComposedDataGetScalarstar(PetscObject obj,int id,PetscScalar **data,PetscTruth *flag)

656:    Not collective

658:    Input parameters:
659: +  obj - the object from which data is to be retrieved
660: -  id - the identifier for the data

662:    Output parameters
663: +  data - the data to be retrieved
664: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

666:    The 'data' and 'flag' variables are inlined, so they are not pointers.

668:    Level: developer
669: M*/
670: #if defined(PETSC_USE_COMPLEX)
671: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag)                                 \
672:   ((((obj)->scalarstarcomposedstate && ((obj)->scalarstarcomposedstate[id] == (obj)->state)) ? \
673:        (data = (obj)->scalarstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
674: #else
675: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag)                 \
676:         PetscObjectComposedDataGetRealstar(obj,id,data,flag)
677: #endif

679: /* some vars for logging */

684: #endif /* _PETSCHEAD_H */