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 */