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:   void           *python_context;
 87:   PetscErrorCode (*python_destroy)(void*);

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

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

101: #define  PETSCFREEDHEADER -1

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

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

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

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

122:     Level: developer

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

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


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

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

144:     Level: developer

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


157: /* ---------------------------------------------------------------------------------------*/

159: #if !defined(PETSC_USE_DEBUG)


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

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

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

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

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

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

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

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

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

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

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

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

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

283: #endif

286: #if !defined(PETSC_USE_DEBUG)


298: #else

300: /*
301:     For example, in the dot product between two vectors,
302:   both vectors must be either Seq or MPI, not one of each 
303: */
305:   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);
306: /* 
307:    Use this macro to check if the type is set
308: */
310:   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);
311: /*
312:    Sometimes object must live on same communicator to inter-operate
313: */
315:   do {                                                                  \
316:     PetscErrorCode _6_ierr,__flag;                                      \
317:     _6_MPI_Comm_compare(((PetscObject)a)->comm,((PetscObject)b)->comm,&__flag); \
318:     CHKERRQ(_6_ierr);                                                   \
319:     if (__flag != MPI_CONGRUENT && __flag != MPI_IDENT)                 \
320:       SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"Different communicators in the two objects: Argument # %d and %d flag %d",arga,argb,__flag); \
321:   } while (0)

324:   do {                                                  \
327:   } while (0)

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

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

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

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

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

369: #endif

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

375:    Synopsis:
376:    PetscErrorCode PetscObjectStateIncrease(PetscObject obj)

378:    Not Collective

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

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

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

395:    Level: developer

397:    seealso: PetscObjectStateQuery(), PetscObjectStateDecrease()

399:    Concepts: state

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

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

408:    Synopsis:
409:    PetscErrorCode PetscObjectStateDecrease(PetscObject obj)

411:    Not Collective

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

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

423:    Level: developer

425:    seealso: PetscObjectStateQuery(), PetscObjectStateIncrease()

427:    Concepts: state

429: M*/
430: #define PetscObjectStateDecrease(obj) ((obj)->state--,0)

443: /*MC
444:    PetscObjectComposedDataSetInt - attach integer data to a PetscObject

446:    Synopsis:
447:    PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)

449:    Not collective

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

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

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

466: /*MC
467:    PetscObjectComposedDataGetInt - retrieve integer data attached to an object

469:    Synopsis:
470:    PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool  flag)

472:    Not collective

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

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

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

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

490: /*MC
491:    PetscObjectComposedDataSetIntstar - attach integer array data to a PetscObject

493:    Synopsis:
494:    PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)

496:    Not collective

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

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

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

513: /*MC
514:    PetscObjectComposedDataGetIntstar - retrieve integer array data 
515:    attached to an object

517:    Synopsis:
518:    PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int *data,PetscBool  flag)

520:    Not collective

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

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

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

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

538: /*MC
539:    PetscObjectComposedDataSetReal - attach real data to a PetscObject

541:    Synopsis:
542:    PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)

544:    Not collective

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

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

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

561: /*MC
562:    PetscObjectComposedDataGetReal - retrieve real data attached to an object

564:    Synopsis:
565:    PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal data,PetscBool  flag)

567:    Not collective

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

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

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

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

585: /*MC
586:    PetscObjectComposedDataSetRealstar - attach real array data to a PetscObject

588:    Synopsis:
589:    PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)

591:    Not collective

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

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

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

608: /*MC
609:    PetscObjectComposedDataGetRealstar - retrieve real array data
610:    attached to an object

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

615:    Not collective

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

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

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

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

633: /*MC
634:    PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject

636:    Synopsis:
637:    PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)

639:    Not collective

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

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

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

663:    Synopsis:
664:    PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar data,PetscBool  flag)

666:    Not collective

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

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

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

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

689: /*MC
690:    PetscObjectComposedDataSetScalarstar - attach scalar array data to a PetscObject 

692:    Synopsis:
693:    PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)

695:    Not collective

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

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

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

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

723:    Not collective

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

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

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

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

746: /* some vars for logging */


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


766: #endif /* _PETSCHEAD_H */