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 <petscsys.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: #define PETSC_MAX_OPTIONS_HANDLER 5
 53: typedef struct _p_PetscObject {
 54:   PetscClassId   classid;
 55:   PetscOps       *bops;
 56:   MPI_Comm       comm;
 57:   PetscInt       type;
 58:   PetscLogDouble flops,time,mem;
 59:   PetscInt       id;
 60:   PetscInt       refct;
 61:   PetscMPIInt    tag;
 62:   PetscFList     qlist;
 63:   PetscOList     olist;
 64:   char           *class_name;
 65:   char           *description;
 66:   char           *mansec;
 67:   char           *type_name;
 68:   PetscObject    parent;
 69:   PetscInt       parentid;
 70:   char*          name;
 71:   char           *prefix;
 72:   PetscInt       tablevel;
 73:   void           *cpp;
 74:   PetscInt       amem;
 75:   PetscInt       state;
 76:   PetscInt       int_idmax,        intstar_idmax;
 77:   PetscInt       *intcomposedstate,*intstarcomposedstate;
 78:   PetscInt       *intcomposeddata, **intstarcomposeddata;
 79:   PetscInt       real_idmax,        realstar_idmax;
 80:   PetscInt       *realcomposedstate,*realstarcomposedstate;
 81:   PetscReal      *realcomposeddata, **realstarcomposeddata;
 82:   PetscInt       scalar_idmax,        scalarstar_idmax;
 83:   PetscInt       *scalarcomposedstate,*scalarstarcomposedstate;
 84:   PetscScalar    *scalarcomposeddata, **scalarstarcomposeddata;
 85:   void           (**fortran_func_pointers)(void);                  /* used by Fortran interface functions to stash user provided Fortran functions */
 86:   PetscInt       num_fortran_func_pointers;                        /* number of Fortran function pointers allocated */
 87:   void           *python_context;
 88:   PetscErrorCode (*python_destroy)(void*);

 90:   PetscInt       noptionhandler;
 91:   PetscErrorCode (*optionhandler[PETSC_MAX_OPTIONS_HANDLER])(PetscObject,void*);
 92:   PetscErrorCode (*optiondestroy[PETSC_MAX_OPTIONS_HANDLER])(PetscObject,void*);
 93:   void           *optionctx[PETSC_MAX_OPTIONS_HANDLER];
 94:   PetscPrecision precision;
 95:   PetscBool      optionsprinted;
 96: } _p_PetscObject;

 98: #define PETSCHEADER(ObjectOps) \
 99:   _p_PetscObject hdr;               \
100:   ObjectOps      *ops

102: #define  PETSCFREEDHEADER -1

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

107: /*@C
108:     PetscHeaderCreate - Creates a PETSc object

110:     Input Parameters:
111: +   tp - the data structure type of the object
112: .   pops - the data structure type of the objects operations (for example VecOps)
113: .   cook - the classid associated with this object
114: .   t - type (no longer should be used)
115: .   class_name - string name of class; should be static
116: .   com - the MPI Communicator
117: .   des - the destroy routine for this object
118: -   vie - the view routine for this object

120:     Output Parameter:
121: .   h - the newly created object

123:     Level: developer

125: .seealso: PetscHeaderDestroy(), PetscClassIdRegister()

127: @*/
128: #define PetscHeaderCreate(h,tp,pops,cook,t,class_name,descr,mansec,com,des,vie) \
129:   (PetscNew(struct tp,&(h)) ||                                                \
130:    PetscNew(PetscOps,&(((PetscObject)(h))->bops)) ||                        \
131:    PetscNew(pops,&((h)->ops)) ||                                        \
132:    PetscHeaderCreate_Private((PetscObject)h,cook,t,class_name,descr,mansec,com,(PetscObjectFunction)des,(PetscObjectViewerFunction)vie) || \
133:    PetscLogObjectCreate(h) ||                                                \
134:    PetscLogObjectMemory(h, sizeof(struct tp) + sizeof(PetscOps) + sizeof(pops)))


139: /*@C
140:     PetscHeaderDestroy - Final step in destroying a PetscObject

142:     Input Parameters:
143: .   h - the header created with PetscHeaderCreate()

145:     Level: developer

147: .seealso: PetscHeaderCreate()
148: @*/
149: #define PetscHeaderDestroy(h)                           \
150:   (PetscLogObjectDestroy((PetscObject)(*h)) ||           \
151:    PetscComposedQuantitiesDestroy((PetscObject)*h) || \
152:    PetscHeaderDestroy_Private((PetscObject)(*h)) || \
153:    PetscFree((*h)->ops) ||                           \
154:    PetscFree(*h))


159: /* ---------------------------------------------------------------------------------------*/

161: #if !defined(PETSC_USE_DEBUG)


170: #elif !defined(PETSC_HAVE_UNALIGNED_POINTERS)
171: /* 
172:     Macros to test if a PETSc object is valid and if pointers are
173: valid

175: */
177:   do {                                                                  \
178:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
179:     if ((unsigned long)(h) & (unsigned long)3) {                        \
180:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Invalid Pointer to Object: Parameter # %d",arg); \
181:     }                                                                   \
182:     if (((PetscObject)(h))->classid != ck) {                            \
183:       if (((PetscObject)(h))->classid == PETSCFREEDHEADER) {            \
184:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
185:       } else {                                                          \
186:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong type of object: Parameter # %d",arg); \
187:       }                                                                 \
188:     }                                                                   \
189:   } while (0)

192:   do {                                                                  \
193:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
194:     if ((unsigned long)(h) & (unsigned long)3) {                        \
195:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Invalid Pointer to Object: Parameter # %d",arg); \
196:     } else if (((PetscObject)(h))->classid == PETSCFREEDHEADER) {       \
197:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
198:     } else if (((PetscObject)(h))->classid < PETSC_SMALLEST_CLASSID ||  \
199:                ((PetscObject)(h))->classid > PETSC_LARGEST_CLASSID) {   \
200:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Invalid type of object: Parameter # %d",arg); \
201:     }                                                                   \
202:   } while (0)

205:   do {                                                                  \
206:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
207:     if ((unsigned long)(h) & (unsigned long)3){                                \
208:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Invalid Pointer: Parameter # %d",arg); \
209:     }                                                                   \
210:   } while (0)

213:   do {if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);} while (0)

216:   do {                                                                  \
217:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Null Pointer: Parameter # %d",arg); \
218:     if ((unsigned long)(h) & (unsigned long)3){                                \
219:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Invalid Pointer to Int: Parameter # %d",arg); \
220:     }                                                                   \
221:   } while (0)

223: #if !defined(PETSC_HAVE_DOUBLES_ALIGNED)
225:   do {                                                                  \
226:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
227:     if ((unsigned long)(h) & (unsigned long)3) {                        \
228:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Invalid Pointer to PetscScalar: Parameter # %d",arg); \
229:     }                                                                   \
230:   } while (0)
231: #else
233:   do {                                                                  \
234:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
235:     if ((unsigned long)(h) & (unsigned long)7) {                        \
236:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Invalid Pointer to PetscScalar: Parameter # %d",arg); \
237:     }                                                                   \
238:   } while (0)
239: #endif

241: #else
242: /*
243:      Version where pointers don't have any particular alignment
244: */
246:   do {                                                                  \
247:     if (!h) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object");  \
248:     if (((PetscObject)(h))->classid != ck) {                            \
249:       if (((PetscObject)(h))->classid == PETSCFREEDHEADER) {            \
250:         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free"); \
251:       } else {                                                          \
252:         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong Object");    \
253:       }                                                                 \
254:     }                                                                   \
255:   } while (0)

258:   do {                                                                  \
259:     if (!h) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object");  \
260:     if (((PetscObject)(h))->classid == PETSCFREEDHEADER) {              \
261:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free"); \
262:     } else if (((PetscObject)(h))->classid < PETSC_SMALLEST_CLASSID ||  \
263:                ((PetscObject)(h))->classid > PETSC_LARGEST_CLASSID) {   \
264:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Invalid type of object"); \
265:     }                                                                   \
266:   } while (0)

269:   do {if (!h) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer");} while (0)

272:   do {if (!h) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer");} while (0)

275:   do {if (!h) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer");} while (0)

277: #if !defined(PETSC_HAVE_DOUBLES_ALIGNED)
279:   do {if (!h) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer");} while (0)
280: #else
282:   do {if (!h) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer");} while (0)
283: #endif

285: #endif

288: #if !defined(PETSC_USE_DEBUG)


300: #else

302: /*
303:     For example, in the dot product between two vectors,
304:   both vectors must be either Seq or MPI, not one of each 
305: */
307:   if (((PetscObject)a)->type != ((PetscObject)b)->type) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"Objects not of same type: Argument # %d and %d",arga,argb);
308: /* 
309:    Use this macro to check if the type is set
310: */
312:   if (!((PetscObject)a)->type_name) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"%s object's type is not set: Argument # %d",((PetscObject)a)->class_name,arg);
313: /*
314:    Sometimes object must live on same communicator to inter-operate
315: */
317:   do {                                                                  \
318:     PetscErrorCode _6_ierr,__flag;                                      \
319:     _6_MPI_Comm_compare(((PetscObject)a)->comm,((PetscObject)b)->comm,&__flag); \
320:     CHKERRQ(_6_ierr);                                                   \
321:     if (__flag != MPI_CONGRUENT && __flag != MPI_IDENT)                 \
322:       SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"Different communicators in the two objects: Argument # %d and %d flag %d",arga,argb,__flag); \
323:   } while (0)

326:   do {                                                  \
329:   } while (0)

332:   do {                                                                  \
333:     PetscErrorCode _7_ierr;                                             \
334:     PetscReal b1[2] = {-PetscRealPart(b),PetscRealPart(b)},b2[2];       \
335:     _7_MPI_Allreduce(b1,b2,2,MPIU_REAL,MPIU_MAX,((PetscObject)a)->comm);CHKERRQ(_7_ierr); \
336:     if (-b2[0] != b2[1]) SETERRQ1(((PetscObject)a)->comm,PETSC_ERR_ARG_WRONG,"Scalar value must be same on all processes, argument # %d",c); \
337:   } while (0)

340:   do {                                                                  \
341:     PetscErrorCode _7_ierr;                                             \
342:     PetscReal b1[2] = {-b,b},b2[2];                                     \
343:     _7_MPI_Allreduce(b1,b2,2,MPIU_REAL,MPIU_MAX,((PetscObject)a)->comm);CHKERRQ(_7_ierr); \
344:     if (-b2[0] != b2[1]) SETERRQ1(((PetscObject)a)->comm,PETSC_ERR_ARG_WRONG,"Real value must be same on all processes, argument # %d",c); \
345:   } while (0)

348:   do {                                                                  \
349:     PetscErrorCode _7_ierr;                                             \
350:     PetscInt b1[2] = {-b,b},b2[2];                                      \
351:     _7_MPI_Allreduce(b1,b2,2,MPIU_INT,MPI_MAX,((PetscObject)a)->comm);CHKERRQ(_7_ierr); \
352:     if (-b2[0] != b2[1]) SETERRQ1(((PetscObject)a)->comm,PETSC_ERR_ARG_WRONG,"Int value must be same on all processes, argument # %d",c); \
353:   } while (0)

356:   do {                                                                  \
357:     PetscErrorCode _7_ierr;                                             \
358:     PetscMPIInt b1[2] = {-(PetscMPIInt)b,(PetscMPIInt)b},b2[2];         \
359:     _7_MPI_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,((PetscObject)a)->comm);CHKERRQ(_7_ierr); \
360:     if (-b2[0] != b2[1]) SETERRQ1(((PetscObject)a)->comm,PETSC_ERR_ARG_WRONG,"Bool value must be same on all processes, argument # %d",c); \
361:   } while (0)

364:   do {                                                                  \
365:     PetscErrorCode _7_ierr;                                             \
366:     PetscMPIInt b1[2] = {-(PetscMPIInt)b,(PetscMPIInt)b},b2[2];         \
367:     _7_MPI_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,((PetscObject)a)->comm);CHKERRQ(_7_ierr); \
368:     if (-b2[0] != b2[1]) SETERRQ1(((PetscObject)a)->comm,PETSC_ERR_ARG_WRONG,"Enum value must be same on all processes, argument # %d",c); \
369:   } while (0)

371: #endif

373: /*MC
374:    PetscObjectStateIncrease - Increases the state of any PetscObject, 
375:    regardless of the type.

377:    Synopsis:
378:    PetscErrorCode PetscObjectStateIncrease(PetscObject obj)

380:    Not Collective

382:    Input Parameter:
383: .  obj - any PETSc object, for example a Vec, Mat or KSP. This must be
384:          cast with a (PetscObject), for example, 
385:          PetscObjectStateIncrease((PetscObject)mat);

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

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

397:    Level: developer

399:    seealso: PetscObjectStateQuery(), PetscObjectStateDecrease()

401:    Concepts: state

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

406: /*MC
407:    PetscObjectStateDecrease - Decreases the state of any PetscObject, 
408:    regardless of the type.

410:    Synopsis:
411:    PetscErrorCode PetscObjectStateDecrease(PetscObject obj)

413:    Not Collective

415:    Input Parameter:
416: .  obj - any PETSc object, for example a Vec, Mat or KSP. This must be
417:          cast with a (PetscObject), for example, 
418:          PetscObjectStateIncrease((PetscObject)mat);

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

425:    Level: developer

427:    seealso: PetscObjectStateQuery(), PetscObjectStateIncrease()

429:    Concepts: state

431: M*/
432: #define PetscObjectStateDecrease(obj) ((obj)->state--,0)

445: /*MC
446:    PetscObjectComposedDataSetInt - attach integer data to a PetscObject

448:    Synopsis:
449:    PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)

451:    Not collective

453:    Input parameters:
454: +  obj - the object to which data is to be attached
455: .  id - the identifier for the data
456: -  data - the data to  be attached

458:    Notes
459:    The data identifier can best be determined through a call to
460:    PetscObjectComposedDataRegister()

462:    Level: developer
463: M*/
464: #define PetscObjectComposedDataSetInt(obj,id,data)                                      \
465:   ((((obj)->int_idmax < globalmaxstate) && PetscObjectComposedDataIncreaseInt(obj)) ||  \
466:    ((obj)->intcomposeddata[id] = data,(obj)->intcomposedstate[id] = (obj)->state, 0))

468: /*MC
469:    PetscObjectComposedDataGetInt - retrieve integer data attached to an object

471:    Synopsis:
472:    PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool  flag)

474:    Not collective

476:    Input parameters:
477: +  obj - the object from which data is to be retrieved
478: -  id - the identifier for the data

480:    Output parameters
481: +  data - the data to be retrieved
482: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

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

486:    Level: developer
487: M*/
488: #define PetscObjectComposedDataGetInt(obj,id,data,flag)                            \
489:   ((((obj)->intcomposedstate && ((obj)->intcomposedstate[id] == (obj)->state)) ?   \
490:    (data = (obj)->intcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

492: /*MC
493:    PetscObjectComposedDataSetIntstar - attach integer array data to a PetscObject

495:    Synopsis:
496:    PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)

498:    Not collective

500:    Input parameters:
501: +  obj - the object to which data is to be attached
502: .  id - the identifier for the data
503: -  data - the data to  be attached

505:    Notes
506:    The data identifier can best be determined through a call to
507:    PetscObjectComposedDataRegister()

509:    Level: developer
510: M*/
511: #define PetscObjectComposedDataSetIntstar(obj,id,data)                                          \
512:   ((((obj)->intstar_idmax < globalmaxstate) && PetscObjectComposedDataIncreaseIntstar(obj)) ||  \
513:    ((obj)->intstarcomposeddata[id] = data,(obj)->intstarcomposedstate[id] = (obj)->state, 0))

515: /*MC
516:    PetscObjectComposedDataGetIntstar - retrieve integer array data 
517:    attached to an object

519:    Synopsis:
520:    PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int *data,PetscBool  flag)

522:    Not collective

524:    Input parameters:
525: +  obj - the object from which data is to be retrieved
526: -  id - the identifier for the data

528:    Output parameters
529: +  data - the data to be retrieved
530: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

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

534:    Level: developer
535: M*/
536: #define PetscObjectComposedDataGetIntstar(obj,id,data,flag)                               \
537:   ((((obj)->intstarcomposedstate && ((obj)->intstarcomposedstate[id] == (obj)->state)) ?  \
538:    (data = (obj)->intstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

540: /*MC
541:    PetscObjectComposedDataSetReal - attach real data to a PetscObject

543:    Synopsis:
544:    PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)

546:    Not collective

548:    Input parameters:
549: +  obj - the object to which data is to be attached
550: .  id - the identifier for the data
551: -  data - the data to  be attached

553:    Notes
554:    The data identifier can best be determined through a call to
555:    PetscObjectComposedDataRegister()

557:    Level: developer
558: M*/
559: #define PetscObjectComposedDataSetReal(obj,id,data)                                       \
560:   ((((obj)->real_idmax < globalmaxstate) && PetscObjectComposedDataIncreaseReal(obj)) ||  \
561:    ((obj)->realcomposeddata[id] = data,(obj)->realcomposedstate[id] = (obj)->state, 0))

563: /*MC
564:    PetscObjectComposedDataGetReal - retrieve real data attached to an object

566:    Synopsis:
567:    PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal data,PetscBool  flag)

569:    Not collective

571:    Input parameters:
572: +  obj - the object from which data is to be retrieved
573: -  id - the identifier for the data

575:    Output parameters
576: +  data - the data to be retrieved
577: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

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

581:    Level: developer
582: M*/
583: #define PetscObjectComposedDataGetReal(obj,id,data,flag)                            \
584:   ((((obj)->realcomposedstate && ((obj)->realcomposedstate[id] == (obj)->state)) ?  \
585:    (data = (obj)->realcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

587: /*MC
588:    PetscObjectComposedDataSetRealstar - attach real array data to a PetscObject

590:    Synopsis:
591:    PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)

593:    Not collective

595:    Input parameters:
596: +  obj - the object to which data is to be attached
597: .  id - the identifier for the data
598: -  data - the data to  be attached

600:    Notes
601:    The data identifier can best be determined through a call to
602:    PetscObjectComposedDataRegister()

604:    Level: developer
605: M*/
606: #define PetscObjectComposedDataSetRealstar(obj,id,data)                                           \
607:   ((((obj)->realstar_idmax < globalmaxstate) && PetscObjectComposedDataIncreaseRealstar(obj)) ||  \
608:    ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))

610: /*MC
611:    PetscObjectComposedDataGetRealstar - retrieve real array data
612:    attached to an object

614:    Synopsis:
615:    PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal *data,PetscBool  flag)

617:    Not collective

619:    Input parameters:
620: +  obj - the object from which data is to be retrieved
621: -  id - the identifier for the data

623:    Output parameters
624: +  data - the data to be retrieved
625: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

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

629:    Level: developer
630: M*/
631: #define PetscObjectComposedDataGetRealstar(obj,id,data,flag)                                \
632:   ((((obj)->realstarcomposedstate && ((obj)->realstarcomposedstate[id] == (obj)->state)) ?  \
633:    (data = (obj)->realstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

635: /*MC
636:    PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject

638:    Synopsis:
639:    PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)

641:    Not collective

643:    Input parameters:
644: +  obj - the object to which data is to be attached
645: .  id - the identifier for the data
646: -  data - the data to  be attached

648:    Notes
649:    The data identifier can best be determined through a call to
650:    PetscObjectComposedDataRegister()

652:    Level: developer
653: M*/
654: #if defined(PETSC_USE_COMPLEX)
655: #define PetscObjectComposedDataSetScalar(obj,id,data)                                        \
656:   ((((obj)->scalar_idmax < globalmaxstate) && PetscObjectComposedDataIncreaseScalar(obj)) || \
657:    ((obj)->scalarcomposeddata[id] = data,(obj)->scalarcomposedstate[id] = (obj)->state, 0))
658: #else
659: #define PetscObjectComposedDataSetScalar(obj,id,data) \
660:         PetscObjectComposedDataSetReal(obj,id,data)
661: #endif
662: /*MC
663:    PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object

665:    Synopsis:
666:    PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar data,PetscBool  flag)

668:    Not collective

670:    Input parameters:
671: +  obj - the object from which data is to be retrieved
672: -  id - the identifier for the data

674:    Output parameters
675: +  data - the data to be retrieved
676: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

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

680:    Level: developer
681: M*/
682: #if defined(PETSC_USE_COMPLEX)
683: #define PetscObjectComposedDataGetScalar(obj,id,data,flag)                              \
684:   ((((obj)->scalarcomposedstate && ((obj)->scalarcomposedstate[id] == (obj)->state) ) ? \
685:    (data = (obj)->scalarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
686: #else
687: #define PetscObjectComposedDataGetScalar(obj,id,data,flag)                             \
688:         PetscObjectComposedDataGetReal(obj,id,data,flag)
689: #endif

691: /*MC
692:    PetscObjectComposedDataSetScalarstar - attach scalar array data to a PetscObject 

694:    Synopsis:
695:    PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)

697:    Not collective

699:    Input parameters:
700: +  obj - the object to which data is to be attached
701: .  id - the identifier for the data
702: -  data - the data to  be attached

704:    Notes
705:    The data identifier can best be determined through a call to
706:    PetscObjectComposedDataRegister()

708:    Level: developer
709: M*/
710: #if defined(PETSC_USE_COMPLEX)
711: #define PetscObjectComposedDataSetScalarstar(obj,id,data)                                             \
712:   ((((obj)->scalarstar_idmax < globalmaxstate) && PetscObjectComposedDataIncreaseScalarstar(obj)) ||  \
713:    ((obj)->scalarstarcomposeddata[id] = data,(obj)->scalarstarcomposedstate[id] = (obj)->state, 0))
714: #else
715: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
716:         PetscObjectComposedDataSetRealstar(obj,id,data)
717: #endif
718: /*MC
719:    PetscObjectComposedDataGetScalarstar - retrieve scalar array data
720:    attached to an object

722:    Synopsis:
723:    PetscErrorCode PetscObjectComposedDataGetScalarstar(PetscObject obj,int id,PetscScalar *data,PetscBool  flag)

725:    Not collective

727:    Input parameters:
728: +  obj - the object from which data is to be retrieved
729: -  id - the identifier for the data

731:    Output parameters
732: +  data - the data to be retrieved
733: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

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

737:    Level: developer
738: M*/
739: #if defined(PETSC_USE_COMPLEX)
740: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag)                                 \
741:   ((((obj)->scalarstarcomposedstate && ((obj)->scalarstarcomposedstate[id] == (obj)->state)) ? \
742:        (data = (obj)->scalarstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
743: #else
744: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag)                 \
745:         PetscObjectComposedDataGetRealstar(obj,id,data,flag)
746: #endif

748: /* some vars for logging */


756: /*
757:   PETSc communicators have this attribute, see
758:   PetscCommDuplicate(), PetscCommDestroy(), PetscCommGetNewTag(), PetscObjectGetName()
759: */
760: typedef struct {
761:   PetscMPIInt tag;              /* next free tag value */
762:   PetscInt    refcount;         /* number of references, communicator can be freed when this reaches 0 */
763:   PetscInt    namecount;        /* used to generate the next name, as in Vec_0, Mat_1, ... */
764: } PetscCommCounter;


768: #endif /* _PETSCHEAD_H */