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