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