Actual source code: petschead.h
1: /* $Id: petschead.h,v 1.84 2001/04/10 19:37:48 bsmith Exp $ */
3: /*
4: Defines the basic header of all PETSc objects.
5: */
7: #if !defined(_PHEAD_H)
8: #define _PHEAD_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 (*)());
51: int (*queryfunction)(PetscObject,const char[],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: PetscObject parent;
72: int parentid;
73: char* name;
74: char *prefix;
75: void *cpp;
76: int amem;
77: void (**fortran_func_pointers)();
79: /* ... */
81: #define PETSCFREEDHEADER -1
83: EXTERN int PetscHeaderCreate_Private(PetscObject,int,int,char *,MPI_Comm,int (*)(PetscObject),int (*)(PetscObject,PetscViewer));
84: EXTERN int PetscHeaderDestroy_Private(PetscObject);
86: /*
87: PetscHeaderCreate - Creates a PETSc object
89: Input Parameters:
90: + tp - the data structure type of the object
91: . pops - the data structure type of the objects operations (for example VecOps)
92: . cook - the cookie associated with this object
93: . t - type (no longer should be used)
94: . class_name - string name of class; should be static
95: . com - the MPI Communicator
96: . des - the destroy routine for this object
97: - vie - the view routine for this object
99: Output Parameter:
100: . h - the newly created object
101: */
102: #define PetscHeaderCreate(h,tp,pops,cook,t,class_name,com,des,vie)
103: { int _ierr;
104: _PetscNew(struct tp,&(h));CHKERRQ(_ierr);
105: _PetscMemzero(h,sizeof(struct tp));CHKERRQ(_ierr);
106: _PetscNew(PetscOps,&((h)->bops));CHKERRQ(_ierr);
107: _PetscMemzero((h)->bops,sizeof(PetscOps));CHKERRQ(_ierr);
108: _PetscNew(pops,&((h)->ops));CHKERRQ(_ierr);
109: _PetscMemzero((h)->ops,sizeof(pops));CHKERRQ(_ierr);
110: _PetscHeaderCreate_Private((PetscObject)h,cook,t,class_name,com,
111: (int (*)(PetscObject))des,
112: (int (*)(PetscObject,PetscViewer))vie);CHKERRQ(_ierr);
113: }
115: #define PetscHeaderDestroy(h)
116: { int _ierr;
117: _PetscHeaderDestroy_Private((PetscObject)(h));CHKERRQ(_ierr);
118: }
120: /* ---------------------------------------------------------------------------------------*/
122: #if !defined(PETSC_HAVE_CRAY90_POINTER)
123: /*
124: Macros to test if a PETSc object is valid and if pointers are
125: valid
127: */
129: {if (!h) {SETERRQ(PETSC_ERR_ARG_CORRUPT,"Null Object");}
130: if ((unsigned long)h & (unsigned long)3) {
131: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Invalid Pointer to Object");
132: }
133: if (((PetscObject)(h))->cookie != ck) {
134: if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) {
135: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Object already free");
136: } else {
137: SETERRQ(PETSC_ERR_ARG_WRONG,"Wrong Object");
138: }
139: }}
142: {if (!h) {SETERRQ(PETSC_ERR_ARG_CORRUPT,"Null Object");}
143: if ((unsigned long)h & (unsigned long)3) {
144: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Invalid Pointer to Object");
145: } else if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) {
146: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Object already free");
147: } else if (((PetscObject)(h))->cookie < PETSC_COOKIE ||
148: ((PetscObject)(h))->cookie > PETSC_LARGEST_COOKIE) {
149: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Invalid Object");
150: }}
153: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");}
154: if ((unsigned long)h & (unsigned long)3){
155: SETERRQ(PETSC_ERR_ARG_BADPTR,"Invalid Pointer");
156: }}
159: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");}
160: }
163: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");}
164: if ((unsigned long)h & (unsigned long)3){
165: SETERRQ(PETSC_ERR_ARG_BADPTR,"Invalid Pointer to Int");
166: }}
168: #if !defined(PETSC_HAVE_DOUBLE_ALIGN)
170: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");}
171: if ((unsigned long)h & (unsigned long)3) {
172: SETERRQ(PETSC_ERR_ARG_BADPTR,"Invalid Pointer to Scalar");
173: }}
174: #else
176: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");}
177: if ((unsigned long)h & (unsigned long)7) {
178: SETERRQ(PETSC_ERR_ARG_BADPTR,"Invalid Pointer to Scalar");
179: }}
180: #endif
182: #else
183: /*
184: Version for Cray 90 that handles pointers differently
185: */
187: {if (!h) {SETERRQ(PETSC_ERR_ARG_CORRUPT,"Null Object");}
188: if (((PetscObject)(h))->cookie != ck) {
189: if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) {
190: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Object already free");
191: } else {
192: SETERRQ(PETSC_ERR_ARG_WRONG,"Wrong Object");
193: }
194: }}
197: {if (!h) {SETERRQ(PETSC_ERR_ARG_CORRUPT,"Null Object");}
198: if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) {
199: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Object already free");
200: } else if (((PetscObject)(h))->cookie < PETSC_COOKIE ||
201: ((PetscObject)(h))->cookie > PETSC_LARGEST_COOKIE) {
202: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Invalid Object");
203: }}
206: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");}
207: }
210: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");}
211: }
214: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");}
215: }
217: #if !defined(PETSC_HAVE_DOUBLE_ALIGN)
219: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");}
220: }
221: #else
223: {if (!h) {SETERRQ(PETSC_ERR_ARG_BADPTR,"Null Pointer");}
224: }
225: #endif
227: #endif
230: /*
231: For example, in the dot product between two vectors,
232: both vectors must be either Seq or MPI, not one of each
233: */
235: if ((a)->type != (b)->type) SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Objects not of same type");
236: /*
237: Use this macro to check if the type is set
238: */
240: if (!(a)->type_name) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Object Type not set");
241: /*
242: Sometimes object must live on same communicator to inter-operate
243: */
245: {int __ierr,__flag; __MPI_Comm_compare(((PetscObject)a)->comm,((PetscObject)b)->comm,&__flag);
246: CHKERRQ(__ierr);
247: if (__flag != MPI_CONGRUENT && __flag != MPI_IDENT)
248: SETERRQ(PETSC_ERR_ARG_NOTSAMECOMM,"Different communicators in the two objects");}
250: /*
251: All PETSc objects begin with the fields defined in PETSCHEADER.
252: The PetscObject is a way of examining these fields regardless of
253: the specific object. In C++ this could be a base abstract class
254: from which all objects are derived.
255: */
256: struct _p_PetscObject {
257: PETSCHEADER(int)
258: };
260: EXTERN int PetscObjectPublishBaseBegin(PetscObject);
261: EXTERN int PetscObjectPublishBaseEnd(PetscObject);
263: #endif