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