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
11: EXTERN int PetscCommDuplicate_Private(MPI_Comm,MPI_Comm*,int*);
12: EXTERN int PetscCommDestroy_Private(MPI_Comm*);
14: EXTERN int PetscRegisterCookie(int *);
16: /*
17: All major PETSc data structures have a common core; this is defined
18: below by PETSCHEADER.
20: PetscHeaderCreate() should be used whenever creating a PETSc structure.
21: */
23: /*
24: PetscOps: structure of core operations that all PETSc objects support.
25:
26: getcomm() - Gets the object's communicator.
27: view() - Is the routine for viewing the entire PETSc object; for
28: example, MatView() is the general matrix viewing routine.
29: reference() - Increases the reference count for a PETSc object; when
30: a reference count reaches zero it is destroyed.
31: destroy() - Is the routine for destroying the entire PETSc object;
32: for example,MatDestroy() is the general matrix
33: destruction routine.
34: compose() - Associates a PETSc object with another PETSc object.
35: query() - Returns a different PETSc object that has been associated
36: with the first object.
37: composefunction() - Attaches an additional registered function.
38: queryfunction() - Requests a registered function that has been registered.
39: composelanguage() - associates the object's representation in a different language
40: querylanguage() - obtain the object's representation in a different language
41: */
43: typedef struct {
44: int (*getcomm)(PetscObject,MPI_Comm *);
45: int (*view)(PetscObject,PetscViewer);
46: int (*reference)(PetscObject);
47: int (*destroy)(PetscObject);
48: int (*compose)(PetscObject,const char[],PetscObject);
49: int (*query)(PetscObject,const char[],PetscObject *);
50: int (*composefunction)(PetscObject,const char[],const char[],void (*)(void));
51: int (*queryfunction)(PetscObject,const char[],void (**)(void));
52: int (*composelanguage)(PetscObject,PetscLanguage,void *);
53: int (*querylanguage)(PetscObject,PetscLanguage,void **);
54: int (*publish)(PetscObject);
55: } PetscOps;
57: #define PETSCHEADER(ObjectOps) \
58: int cookie; \
59: PetscOps *bops; \
60: ObjectOps *ops; \
61: MPI_Comm comm; \
62: int type; \
63: PetscLogDouble flops,time,mem; \
64: int id; \
65: int refct; \
66: int tag; \
67: PetscFList qlist; \
68: PetscOList olist; \
69: char *class_name; \
70: char *type_name; \
71: char *serialize_name; \
72: ParameterDict dict; \
73: PetscObject parent; \
74: int parentid; \
75: char* name; \
76: char *prefix; \
77: void *cpp; \
78: int amem; \
79: void (**fortran_func_pointers)(void);
81: /* ... */
83: #define PETSCFREEDHEADER -1
85: EXTERN int PetscHeaderCreate_Private(PetscObject,int,int,char *,MPI_Comm,int (*)(PetscObject),int (*)(PetscObject,PetscViewer));
86: EXTERN int PetscHeaderDestroy_Private(PetscObject);
88: /*
89: PetscHeaderCreate - Creates a PETSc object
91: Input Parameters:
92: + tp - the data structure type of the object
93: . pops - the data structure type of the objects operations (for example VecOps)
94: . cook - the cookie associated with this object
95: . t - type (no longer should be used)
96: . class_name - string name of class; should be static
97: . com - the MPI Communicator
98: . des - the destroy routine for this object
99: - vie - the view routine for this object
101: Output Parameter:
102: . h - the newly created object
103: */
104: #define PetscHeaderCreate(h,tp,pops,cook,t,class_name,com,des,vie) \
105: { int _ierr; \
106: _PetscNew(struct tp,&(h));CHKERRQ(_ierr); \
107: _PetscMemzero(h,sizeof(struct tp));CHKERRQ(_ierr); \
108: _PetscNew(PetscOps,&((h)->bops));CHKERRQ(_ierr); \
109: _PetscMemzero((h)->bops,sizeof(PetscOps));CHKERRQ(_ierr); \
110: _PetscNew(pops,&((h)->ops));CHKERRQ(_ierr); \
111: _PetscMemzero((h)->ops,sizeof(pops));CHKERRQ(_ierr); \
112: _PetscHeaderCreate_Private((PetscObject)h,cook,t,class_name,com, \
113: (int (*)(PetscObject))des, \
114: (int (*)(PetscObject,PetscViewer))vie);CHKERRQ(_ierr); \
115: }
117: #define PetscHeaderDestroy(h) \
118: { int _ierr; \
119: _PetscHeaderDestroy_Private((PetscObject)(h));CHKERRQ(_ierr);\
120: }
122: /* ---------------------------------------------------------------------------------------*/
124: #if !defined(PETSC_HAVE_CRAY90_POINTER)
125: /*
126: Macros to test if a PETSc object is valid and if pointers are
127: valid
129: */
131: {if (!h) {SETERRQ(PETSC_ERR_ARG_CORRUPT,"Null Object");} \
132: if ((unsigned long)h & (unsigned long)3) { \
133: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Invalid Pointer to Object"); \
134: } \
135: if (((PetscObject)(h))->cookie != ck) { \
136: if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) { \
137: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Object already free"); \
138: } else { \
139: SETERRQ(PETSC_ERR_ARG_WRONG,"Wrong Object"); \
140: } \
141: }}
144: {if (!h) {SETERRQ(PETSC_ERR_ARG_CORRUPT,"Null Object");} \
145: if ((unsigned long)h & (unsigned long)3) { \
146: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Invalid Pointer to Object"); \
147: } else if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) { \
148: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Object already free"); \
149: } else if (((PetscObject)(h))->cookie < PETSC_COOKIE || \
150: ((PetscObject)(h))->cookie > PETSC_LARGEST_COOKIE) { \
151: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Invalid Object"); \
152: }}
155: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");} \
156: if ((unsigned long)h & (unsigned long)3){ \
157: SETERRQ(PETSC_ERR_ARG_BADPTR,"Invalid Pointer"); \
158: }}
161: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");} \
162: }
165: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");} \
166: if ((unsigned long)h & (unsigned long)3){ \
167: SETERRQ(PETSC_ERR_ARG_BADPTR,"Invalid Pointer to Int"); \
168: }}
170: #if !defined(PETSC_HAVE_DOUBLES_ALIGNED) || defined (PETSC_HAVE_DOUBLES_ALIGNED)
172: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");} \
173: if ((unsigned long)h & (unsigned long)3) { \
174: SETERRQ(PETSC_ERR_ARG_BADPTR,"Invalid Pointer to PetscScalar"); \
175: }}
176: #else
178: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");} \
179: if ((unsigned long)h & (unsigned long)7) { \
180: SETERRQ(PETSC_ERR_ARG_BADPTR,"Invalid Pointer to PetscScalar"); \
181: }}
182: #endif
184: #else
185: /*
186: Version for Cray 90 that handles pointers differently
187: */
189: {if (!h) {SETERRQ(PETSC_ERR_ARG_CORRUPT,"Null Object");} \
190: if (((PetscObject)(h))->cookie != ck) { \
191: if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) { \
192: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Object already free"); \
193: } else { \
194: SETERRQ(PETSC_ERR_ARG_WRONG,"Wrong Object"); \
195: } \
196: }}
199: {if (!h) {SETERRQ(PETSC_ERR_ARG_CORRUPT,"Null Object");} \
200: if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) { \
201: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Object already free"); \
202: } else if (((PetscObject)(h))->cookie < PETSC_COOKIE || \
203: ((PetscObject)(h))->cookie > PETSC_LARGEST_COOKIE) { \
204: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Invalid Object"); \
205: }}
208: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");} \
209: }
212: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");} \
213: }
216: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");} \
217: }
219: #if !defined(PETSC_HAVE_DOUBLES_ALIGNED)
221: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");} \
222: }
223: #else
225: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");} \
226: }
227: #endif
229: #endif
232: /*
233: For example, in the dot product between two vectors,
234: both vectors must be either Seq or MPI, not one of each
235: */
237: if ((a)->type != (b)->type) SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Objects not of same type");
238: /*
239: Use this macro to check if the type is set
240: */
242: if (!(a)->type_name) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Object Type not set");
243: /*
244: Sometimes object must live on same communicator to inter-operate
245: */
247: {int _6_ierr,__flag; _6_MPI_Comm_compare(((PetscObject)a)->comm,((PetscObject)b)->comm,&__flag);\
248: CHKERRQ(_6_ierr); \
249: if (__flag != MPI_CONGRUENT && __flag != MPI_IDENT) \
250: SETERRQ(PETSC_ERR_ARG_NOTSAMECOMM,"Different communicators in the two objects");}
252: /*
253: All PETSc objects begin with the fields defined in PETSCHEADER.
254: The PetscObject is a way of examining these fields regardless of
255: the specific object. In C++ this could be a base abstract class
256: from which all objects are derived.
257: */
258: struct _p_PetscObject {
259: PETSCHEADER(int)
260: };
262: EXTERN int PetscObjectPublishBaseBegin(PetscObject);
263: EXTERN int PetscObjectPublishBaseEnd(PetscObject);
265: #endif /* _PETSCHEAD_H */