Actual source code: petschead.h

  1: /* $Id: petschead.h,v 1.86 2001/09/07 20:13:16 bsmith Exp $ */

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

  7: #if !defined(_PETSCHEAD_H)
  8: #define _PETSCHEAD_H
 9:  #include petsc.h
 10: PETSC_EXTERN_CXX_BEGIN


 13: EXTERN int PetscRegisterCookie(int *);

 15: /*
 16:    All major PETSc data structures have a common core; this is defined 
 17:    below by PETSCHEADER. 

 19:    PetscHeaderCreate() should be used whenever creating a PETSc structure.
 20: */

 22: /*
 23:    PetscOps: structure of core operations that all PETSc objects support.
 24:    
 25:       getcomm()         - Gets the object's communicator.
 26:       view()            - Is the routine for viewing the entire PETSc object; for
 27:                           example, MatView() is the general matrix viewing routine.
 28:       reference()       - Increases the reference count for a PETSc object; when
 29:                           a reference count reaches zero it is destroyed.
 30:       destroy()         - Is the routine for destroying the entire PETSc object; 
 31:                           for example,MatDestroy() is the general matrix 
 32:                           destruction routine.
 33:       compose()         - Associates a PETSc object with another PETSc object.
 34:       query()           - Returns a different PETSc object that has been associated
 35:                           with the first object.
 36:       composefunction() - Attaches an additional registered function.
 37:       queryfunction()   - Requests a registered function that has been registered.
 38:       composelanguage() - associates the object's representation in a different language
 39:       querylanguage()   - obtain the object's representation in a different language
 40: */

 42: typedef struct {
 43:    int (*getcomm)(PetscObject,MPI_Comm *);
 44:    int (*view)(PetscObject,PetscViewer);
 45:    int (*reference)(PetscObject);
 46:    int (*destroy)(PetscObject);
 47:    int (*compose)(PetscObject,const char[],PetscObject);
 48:    int (*query)(PetscObject,const char[],PetscObject *);
 49:    int (*composefunction)(PetscObject,const char[],const char[],void (*)(void));
 50:    int (*queryfunction)(PetscObject,const char[],void (**)(void));
 51:    int (*composelanguage)(PetscObject,PetscLanguage,void *);
 52:    int (*querylanguage)(PetscObject,PetscLanguage,void **);
 53:    int (*publish)(PetscObject);
 54: } PetscOps;

 56: #define PETSCHEADER(ObjectOps)                            \
 57:   int            cookie;                                  \
 58:   PetscOps       *bops;                                   \
 59:   ObjectOps      *ops;                                    \
 60:   MPI_Comm       comm;                                    \
 61:   int            type;                                    \
 62:   PetscLogDouble flops,time,mem;                          \
 63:   int            id;                                      \
 64:   int            refct;                                   \
 65:   int            tag;                                     \
 66:   PetscFList     qlist;                                   \
 67:   PetscOList     olist;                                   \
 68:   char           *class_name;                             \
 69:   char           *type_name;                              \
 70:   ParameterDict  dict;                                    \
 71:   PetscObject    parent;                                  \
 72:   int            parentid;                                \
 73:   char*          name;                                    \
 74:   char           *prefix;                                 \
 75:   void           *cpp;                                    \
 76:   int            amem;                                    \
 77:   int            state;                                   \
 78:   int            int_idmax,real_idmax,scalar_idmax;       \
 79:   int            *intcomposeddata,*intcomposedstate,      \
 80:                  *realcomposedstate,*scalarcomposedstate; \
 81:   PetscReal      *realcomposeddata;                       \
 82:   PetscScalar    *scalarcomposeddata;                     \
 83:   void           (**fortran_func_pointers)(void);       

 85:   /*  ... */

 87: #define  PETSCFREEDHEADER -1

 89: EXTERN int PetscHeaderCreate_Private(PetscObject,int,int,const char[],MPI_Comm,int (*)(PetscObject),int (*)(PetscObject,PetscViewer));
 90: EXTERN int PetscHeaderDestroy_Private(PetscObject);

 92: typedef int (*PetscObjectFunction)(PetscObject); /* force cast in next macro to NEVER use extern "C" style */
 93: typedef int (*PetscObjectViewerFunction)(PetscObject,PetscViewer);

 95: /*
 96:     PetscHeaderCreate - Creates a PETSc object

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

108:     Output Parameter:
109: .   h - the newly created object
110: */
111: #define PetscHeaderCreate(h,tp,pops,cook,t,class_name,com,des,vie)                      \
112:   { int _ierr;                                                                          \
113:     _PetscNew(struct tp,&(h));CHKERRQ(_ierr);                                      \
114:     _PetscMemzero(h,sizeof(struct tp));CHKERRQ(_ierr);                           \
115:     _PetscNew(PetscOps,&((h)->bops));CHKERRQ(_ierr);                               \
116:     _PetscMemzero((h)->bops,sizeof(PetscOps));CHKERRQ(_ierr);                    \
117:     _PetscNew(pops,&((h)->ops));CHKERRQ(_ierr);                                    \
118:     _PetscMemzero((h)->ops,sizeof(pops));CHKERRQ(_ierr);                         \
119:     _PetscHeaderCreate_Private((PetscObject)h,cook,t,class_name,com,             \
120:                                  (PetscObjectFunction)des,                             \
121:                                  (PetscObjectViewerFunction)vie);CHKERRQ(_ierr);       \
122:   }

124: #define PetscHeaderDestroy(h)                                             \
125:   { int _ierr;                                                            \
126:     _PetscHeaderDestroy_Private((PetscObject)(h));CHKERRQ(_ierr);\
127:   }                 

129: /* ---------------------------------------------------------------------------------------*/

131: #if !defined(PETSC_HAVE_CRAY90_POINTER)
132: /* 
133:     Macros to test if a PETSc object is valid and if pointers are
134: valid

136: */
138:   {if (!h) {SETERRQ1(PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg);}          \
139:   if ((unsigned long)h & (unsigned long)3) {                                          \
140:     SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Invalid Pointer to Object: Parameter # %d",arg);   \
141:   }                                                                                   \
142:   if (((PetscObject)(h))->cookie != ck) {                                             \
143:     if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) {                             \
144:       SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg);       \
145:     } else {                                                                          \
146:       SETERRQ1(PETSC_ERR_ARG_WRONG,"Wrong type of object: Parameter # %d",arg);       \
147:     }                                                                                 \
148:   }} 

151:   {if (!h) {SETERRQ1(PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg);}             \
152:   if ((unsigned long)h & (unsigned long)3) {                                             \
153:     SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Invalid Pointer to Object: Parameter # %d",arg);     \
154:   } else if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) {                           \
155:       SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg);         \
156:   } else if (((PetscObject)(h))->cookie < PETSC_COOKIE ||                                \
157:       ((PetscObject)(h))->cookie > PETSC_LARGEST_COOKIE) {                               \
158:       SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Invalid type of object: Parameter # %d",arg);      \
159:   }}

162:   {if (!h) {SETERRQ1(PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);}             \
163:   if ((unsigned long)h & (unsigned long)3){                                               \
164:     SETERRQ1(PETSC_ERR_ARG_BADPTR,"Invalid Pointer: Parameter # %d",arg);                 \
165:   }}

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

172:   {if (!h) {SETERRQ1(PETSC_ERR_ARG_BADPTR,"Null Pointer: Parameter # %d",arg);}            \
173:   if ((unsigned long)h & (unsigned long)3){                                                \
174:     SETERRQ1(PETSC_ERR_ARG_BADPTR,"Invalid Pointer to Int: Parameter # %d",arg);           \
175:   }}

177: #if !defined(PETSC_HAVE_DOUBLES_ALIGNED) || defined (PETSC_HAVE_DOUBLES_ALIGNED)
179:   {if (!h) {SETERRQ1(PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);}               \
180:   if ((unsigned long)h & (unsigned long)3) {                                                \
181:     SETERRQ1(PETSC_ERR_ARG_BADPTR,"Invalid Pointer to PetscScalar: Parameter # %d",arg);    \
182:   }}
183: #else
185:   {if (!h) {SETERRQ1(PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);}               \
186:   if ((unsigned long)h & (unsigned long)7) {                                                \
187:     SETERRQ1(PETSC_ERR_ARG_BADPTR,"Invalid Pointer to PetscScalar: Parameter # %d",arg);    \
188:   }}
189: #endif

191: #else
192: /*
193:      Version for Cray 90 that handles pointers differently
194: */
196:   {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Object");}        \
197:   if (((PetscObject)(h))->cookie != ck) {                           \
198:     if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) {           \
199:       SETERRQ(PETSC_ERR_ARG_CORRUPT,"Object already free");       \
200:     } else {                                                        \
201:       SETERRQ(PETSC_ERR_ARG_WRONG,"Wrong Object");                \
202:     }                                                               \
203:   }} 

206:   {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Object");}        \
207:   if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) {      \
208:       SETERRQ(PETSC_ERR_ARG_CORRUPT,"Object already free");       \
209:   } else if (((PetscObject)(h))->cookie < PETSC_COOKIE ||           \
210:       ((PetscObject)(h))->cookie > PETSC_LARGEST_COOKIE) {          \
211:       SETERRQ(PETSC_ERR_ARG_CORRUPT,"Invalid type of object");            \
212:   }}

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

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

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

226: #if !defined(PETSC_HAVE_DOUBLES_ALIGNED)
228:   {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Pointer");}        \
229:   }
230: #else
232:   {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Pointer");}        \
233:   }
234: #endif

236: #endif

239: /*
240:     For example, in the dot product between two vectors,
241:   both vectors must be either Seq or MPI, not one of each 
242: */
244:   if ((a)->type != (b)->type) SETERRQ2(PETSC_ERR_ARG_NOTSAMETYPE,"Objects not of same type: Argument # %d and %d",arga,argb);
245: /* 
246:    Use this macro to check if the type is set
247: */
249:   if (!(a)->type_name) SETERRQ1(PETSC_ERR_ARG_WRONGSTATE,"Object Type not set: Argument # %d",arg);
250: /*
251:    Sometimes object must live on same communicator to inter-operate
252: */
254:   {int _6_ierr,__flag; _6_MPI_Comm_compare(((PetscObject)a)->comm,((PetscObject)b)->comm,&__flag);\
255:   CHKERRQ(_6_ierr); \
256:   if (__flag != MPI_CONGRUENT && __flag != MPI_IDENT) \
257:   SETERRQ2(PETSC_ERR_ARG_NOTSAMECOMM,"Different communicators in the two objects: Argument # %d and %d",arga,argb);}


263: /*
264:    All PETSc objects begin with the fields defined in PETSCHEADER.
265:    The PetscObject is a way of examining these fields regardless of 
266:    the specific object. In C++ this could be a base abstract class
267:    from which all objects are derived.
268: */
269: struct _p_PetscObject {
270:   PETSCHEADER(int)
271: };

273: EXTERN int PetscObjectPublishBaseBegin(PetscObject);
274: EXTERN int PetscObjectPublishBaseEnd(PetscObject);

276: EXTERN int PetscObjectIncreaseState(PetscObject);
277: EXTERN int PetscObjectGetState(PetscObject obj,int*);
278: EXTERN int PetscRegisterComposedData(int *id);
279: EXTERN int PetscObjectIncreaseIntComposedData(PetscObject obj);
280: EXTERN int PetscObjectIncreaseRealComposedData(PetscObject obj);
281: EXTERN int PetscObjectIncreaseScalarComposedData(PetscObject obj);
282: EXTERN int globalcurrentstate,globalmaxstate;
283: /*MC
284:    PetscObjectSetIntComposedData - attach integer data to a PetscObject

286:    Synopsis:
287:    PetscObjectSetIntComposedData(PetscObject obj,int id,int data)

289:    Not collective

291:    Input parameters:
292: +  obj - the object to which data is to be attached
293: .  id - the identifier for the data
294: -  data - the data to  be attached

296:    Notes:

298:    This routine does not return an error code; any errors are handled
299:    internally.

301:    Level: developer
302: M*/
303: #define PetscObjectSetIntComposedData(obj,id,data)                   \
304: 0; {int ierr_;                                                       \
305:   if ((obj)->int_idmax < globalmaxstate) {                           \
306:     ierr_ = PetscObjectIncreaseIntComposedData(obj); CHKERRQ(ierr_);  \
307:   }                                                                  \
308:   (obj)->intcomposeddata[id] = data;                                 \
309:   (obj)->intcomposedstate[id] = (obj)->state;                        \
310: }
311: /*MC
312:    PetscObjectGetIntComposedData - retrieve integer data attached to an object

314:    Synopsis:
315:    PetscObjectGetIntComposedData(PetscObject obj,int id,int *data,PetscTruth *flag)

317:    Not collective

319:    Input parameters:
320: +  obj - the object from which data is to be retrieved
321: -  id - the identifier for the data

323:    Output parameters
324: +  data - the data to be retrieved
325: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

327:    Notes:

329:    This routine does not return an error code; any errors are handled
330:    internally.

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

334:    Level: developer
335: M*/
336: #define PetscObjectGetIntComposedData(obj,id,data,flag)              \
337: 0; {                                                                 \
338:   if ((int)((obj)->intcomposedstate)) {                              \
339:     if ((obj)->intcomposedstate[id] == (obj)->state) {               \
340:       data = (obj)->intcomposeddata[id];                             \
341:       flag = PETSC_TRUE;                                             \
342:     } else {                                                         \
343:       flag = PETSC_FALSE;                                            \
344:     }                                                                \
345:   } else flag = PETSC_FALSE;                                         \
346: }
347: /*MC
348:    PetscObjectSetRealComposedData - attach real data to a PetscObject

350:    Synopsis:
351:    PetscObjectSetRealComposedData(PetscObject obj,int id,PetscReal data)

353:    Not collective

355:    Input parameters:
356: +  obj - the object to which data is to be attached
357: .  id - the identifier for the data
358: -  data - the data to  be attached

360:    Notes:

362:    This routine does not return an error code; any errors are handled
363:    internally.

365:    Level: developer
366: M*/
367: #define PetscObjectSetRealComposedData(obj,id,data)                  \
368: 0; {int ierr_;                                                       \
369:   if ((obj)->real_idmax < globalmaxstate) {                          \
370:     ierr_ = PetscObjectIncreaseRealComposedData(obj); CHKERRQ(ierr_); \
371:   }                                                                  \
372:   (obj)->realcomposeddata[id] = data;                                \
373:   (obj)->realcomposedstate[id] = (obj)->state;                       \
374: }
375: /*MC
376:    PetscObjectGetRealComposedData - retrieve real data attached to an object

378:    Synopsis:
379:    PetscObjectGetRealComposedData(PetscObject obj,int id,PetscReal *data,PetscTruth *flag)

381:    Not collective

383:    Input parameters:
384: +  obj - the object from which data is to be retrieved
385: -  id - the identifier for the data

387:    Output parameters
388: +  data - the data to be retrieved
389: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

391:    Notes:

393:    This routine does not return an error code; any errors are handled
394:    internally.

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

398:    Level: developer
399: M*/
400: #define PetscObjectGetRealComposedData(obj,id,data,flag)             \
401: 0; {                                                                 \
402:   if (((obj)->realcomposedstate)) {                                  \
403:     if ((obj)->realcomposedstate[id] == (obj)->state) {              \
404:       data = (obj)->realcomposeddata[id];                            \
405:       flag = PETSC_TRUE;                                             \
406:     } else {                                                         \
407:       flag = PETSC_FALSE;                                            \
408:     }                                                                \
409:   } else {                                                           \
410:     flag = PETSC_FALSE;                                              \
411:   }                                                                  \
412: }
413: /*MC
414:    PetscObjectSetScalarComposedData - attach scalar data to a PetscObject 

416:    Synopsis:
417:    PetscObjectSetScalarComposedData(PetscObject obj,int id,PetscScalar data)

419:    Not collective

421:    Input parameters:
422: +  obj - the object to which data is to be attached
423: .  id - the identifier for the data
424: -  data - the data to  be attached

426:    Notes:

428:    This routine does not return an error code; any errors are handled
429:    internally.

431:    Level: developer
432: M*/
433: #define PetscObjectSetScalarComposedData(obj,id,data)                 \
434: 0; {int ierr_;                                                        \
435:   if ((obj)->scalar_idmax < globalmaxstate) {                         \
436:     ierr_ = PetscObjectIncreaseScalarComposedData(obj); CHKERRQ(ierr_);\
437:   }                                                                   \
438:   (obj)->scalarcomposeddata[id] = data;                               \
439:   (obj)->scalarcomposedstate[id] = (obj)->state;                      \
440: }
441: /*MC
442:    PetscObjectGetScalarComposedData - retrieve scalar data attached to an object

444:    Synopsis:
445:    PetscObjectGetScalarComposedData(PetscObject obj,int id,PetscScalar *data,PetscTruth *flag)

447:    Not collective

449:    Input parameters:
450: +  obj - the object from which data is to be retrieved
451: -  id - the identifier for the data

453:    Output parameters
454: +  data - the data to be retrieved
455: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

457:    Notes:

459:    This routine does not return an error code; any errors are handled
460:    internally.

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

464:    Level: developer
465: M*/
466: #define PetscObjectGetScalarComposedData(obj,id,data,flag)           \
467: 0; {                                                                 \
468:   if ((int)((obj)->scalarcomposedstate)) {                           \
469:     if ((obj)->scalarcomposedstate[id] == (obj)->state) {            \
470:       data = (obj)->scalarcomposeddata[id];                          \
471:       flag = PETSC_TRUE;                                             \
472:     } else {                                                         \
473:       flag = PETSC_FALSE;                                            \
474:     }                                                                \
475:   } else flag = PETSC_FALSE;                                         \
476: }

478: PETSC_EXTERN_CXX_END
479: #endif /* _PETSCHEAD_H */