Actual source code: petschead.h
2: /*
3: Defines the basic header of all PETSc objects.
4: */
6: #if !defined(_PETSCHEAD_H)
7: #define _PETSCHEAD_H
8: #include petsc.h
11: /*
12: All major PETSc data structures have a common core; this is defined
13: below by PETSCHEADER.
15: PetscHeaderCreate() should be used whenever creating a PETSc structure.
16: */
18: /*
19: PetscOps: structure of core operations that all PETSc objects support.
20:
21: getcomm() - Gets the object's communicator.
22: view() - Is the routine for viewing the entire PETSc object; for
23: example, MatView() is the general matrix viewing routine.
24: reference() - Increases the reference count for a PETSc object; when
25: a reference count reaches zero it is destroyed.
26: destroy() - Is the routine for destroying the entire PETSc object;
27: for example,MatDestroy() is the general matrix
28: destruction routine.
29: compose() - Associates a PETSc object with another PETSc object.
30: query() - Returns a different PETSc object that has been associated
31: with the first object.
32: composefunction() - Attaches an additional registered function.
33: queryfunction() - Requests a registered function that has been registered.
34: composelanguage() - associates the object's representation in a different language
35: querylanguage() - obtain the object's representation in a different language
36: */
38: typedef struct {
39: PetscErrorCode (*getcomm)(PetscObject,MPI_Comm *);
40: PetscErrorCode (*view)(PetscObject,PetscViewer);
41: PetscErrorCode (*reference)(PetscObject);
42: PetscErrorCode (*destroy)(PetscObject);
43: PetscErrorCode (*compose)(PetscObject,const char[],PetscObject);
44: PetscErrorCode (*query)(PetscObject,const char[],PetscObject *);
45: PetscErrorCode (*composefunction)(PetscObject,const char[],const char[],void (*)(void));
46: PetscErrorCode (*queryfunction)(PetscObject,const char[],void (**)(void));
47: PetscErrorCode (*composelanguage)(PetscObject,PetscLanguage,void *);
48: PetscErrorCode (*querylanguage)(PetscObject,PetscLanguage,void **);
49: PetscErrorCode (*publish)(PetscObject);
50: } PetscOps;
52: #define PETSCHEADER(ObjectOps) \
53: PetscCookie cookie; \
54: PetscOps *bops; \
55: ObjectOps *ops; \
56: MPI_Comm comm; \
57: PetscInt type; \
58: PetscLogDouble flops,time,mem; \
59: PetscInt id; \
60: PetscInt refct; \
61: PetscMPIInt tag; \
62: PetscFList qlist; \
63: PetscOList olist; \
64: char *class_name; \
65: char *type_name; \
66: PetscObject parent; \
67: PetscInt parentid; \
68: char* name; \
69: char *prefix; \
70: void *cpp; \
71: PetscInt amem; \
72: PetscInt state; \
73: PetscInt int_idmax, intstar_idmax; \
74: PetscInt *intcomposedstate,*intstarcomposedstate; \
75: PetscInt *intcomposeddata, **intstarcomposeddata; \
76: PetscInt real_idmax, realstar_idmax; \
77: PetscInt *realcomposedstate,*realstarcomposedstate; \
78: PetscReal *realcomposeddata, **realstarcomposeddata; \
79: PetscInt scalar_idmax, scalarstar_idmax; \
80: PetscInt *scalarcomposedstate,*scalarstarcomposedstate; \
81: PetscScalar *scalarcomposeddata, **scalarstarcomposeddata; \
82: void (**fortran_func_pointers)(void)
84: /* ... */
86: #define PETSCFREEDHEADER -1
88: EXTERN PetscErrorCode PETSC_DLLEXPORT PetscHeaderCreate_Private(PetscObject,PetscCookie,PetscInt,const char[],MPI_Comm,PetscErrorCode (*)(PetscObject),PetscErrorCode (*)(PetscObject,PetscViewer));
89: EXTERN PetscErrorCode PETSC_DLLEXPORT PetscHeaderDestroy_Private(PetscObject);
92: typedef PetscErrorCode (*PetscObjectViewerFunction)(PetscObject,PetscViewer);
94: /*
95: PetscHeaderCreate - Creates a PETSc object
97: Input Parameters:
98: + tp - the data structure type of the object
99: . pops - the data structure type of the objects operations (for example VecOps)
100: . cook - the cookie associated with this object
101: . t - type (no longer should be used)
102: . class_name - string name of class; should be static
103: . com - the MPI Communicator
104: . des - the destroy routine for this object
105: - vie - the view routine for this object
107: Output Parameter:
108: . h - the newly created object
109: */
110: #define PetscHeaderCreate(h,tp,pops,cook,t,class_name,com,des,vie) \
111: (PetscNew(struct tp,&(h)) || \
112: PetscNew(PetscOps,&((h)->bops)) || \
113: PetscNew(pops,&((h)->ops)) || \
114: PetscHeaderCreate_Private((PetscObject)h,cook,t,class_name,com,(PetscObjectFunction)des,(PetscObjectViewerFunction)vie) || \
115: PetscLogObjectCreate(h))
117: #define PetscHeaderDestroy(h) \
118: (PetscLogObjectDestroy((PetscObject)(h)) || \
119: PetscHeaderDestroy_Private((PetscObject)(h)) || \
120: PetscFree(h))
122: /* ---------------------------------------------------------------------------------------*/
124: #if !defined(PETSC_USE_DEBUG)
133: #elif !defined(PETSC_HAVE_CRAY90_POINTER)
134: /*
135: Macros to test if a PETSc object is valid and if pointers are
136: valid
138: */
140: {if (!h) {SETERRQ1(PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg);} \
141: if ((unsigned long)h & (unsigned long)3) { \
142: SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Invalid Pointer to Object: Parameter # %d",arg); \
143: } \
144: if (((PetscObject)(h))->cookie != ck) { \
145: if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) { \
146: SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
147: } else { \
148: SETERRQ1(PETSC_ERR_ARG_WRONG,"Wrong type of object: Parameter # %d",arg); \
149: } \
150: }}
153: {if (!h) {SETERRQ1(PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg);} \
154: if ((unsigned long)h & (unsigned long)3) { \
155: SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Invalid Pointer to Object: Parameter # %d",arg); \
156: } else if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) { \
157: SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
158: } else if (((PetscObject)(h))->cookie < PETSC_COOKIE || \
159: ((PetscObject)(h))->cookie > PETSC_LARGEST_COOKIE) { \
160: SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Invalid type of object: Parameter # %d",arg); \
161: }}
164: {if (!h) {SETERRQ1(PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);} \
165: if ((unsigned long)h & (unsigned long)3){ \
166: SETERRQ1(PETSC_ERR_ARG_BADPTR,"Invalid Pointer: Parameter # %d",arg); \
167: }}
170: {if (!h) {SETERRQ1(PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);} \
171: }
174: {if (!h) {SETERRQ1(PETSC_ERR_ARG_BADPTR,"Null Pointer: Parameter # %d",arg);} \
175: if ((unsigned long)h & (unsigned long)3){ \
176: SETERRQ1(PETSC_ERR_ARG_BADPTR,"Invalid Pointer to Int: Parameter # %d",arg); \
177: }}
179: #if !defined(PETSC_HAVE_DOUBLES_ALIGNED) || defined (PETSC_HAVE_DOUBLES_ALIGNED)
181: {if (!h) {SETERRQ1(PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);} \
182: if ((unsigned long)h & (unsigned long)3) { \
183: SETERRQ1(PETSC_ERR_ARG_BADPTR,"Invalid Pointer to PetscScalar: Parameter # %d",arg); \
184: }}
185: #else
187: {if (!h) {SETERRQ1(PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);} \
188: if ((unsigned long)h & (unsigned long)7) { \
189: SETERRQ1(PETSC_ERR_ARG_BADPTR,"Invalid Pointer to PetscScalar: Parameter # %d",arg); \
190: }}
191: #endif
193: #else
194: /*
195: Version for Cray 90 that handles pointers differently
196: */
198: {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Object");} \
199: if (((PetscObject)(h))->cookie != ck) { \
200: if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) { \
201: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Object already free"); \
202: } else { \
203: SETERRQ(PETSC_ERR_ARG_WRONG,"Wrong Object"); \
204: } \
205: }}
208: {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Object");} \
209: if (((PetscObject)(h))->cookie == PETSCFREEDHEADER) { \
210: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Object already free"); \
211: } else if (((PetscObject)(h))->cookie < PETSC_COOKIE || \
212: ((PetscObject)(h))->cookie > PETSC_LARGEST_COOKIE) { \
213: SETERRQ(PETSC_ERR_ARG_CORRUPT,"Invalid type of object"); \
214: }}
217: {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Pointer");} \
218: }
221: {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Pointer");} \
222: }
225: {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Pointer");} \
226: }
228: #if !defined(PETSC_HAVE_DOUBLES_ALIGNED)
230: {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Pointer");} \
231: }
232: #else
234: {if (!h) {SETERRQ(PETSC_ERR_ARG_NULL,"Null Pointer");} \
235: }
236: #endif
238: #endif
241: #if !defined(PETSC_USE_DEBUG)
248: #else
250: /*
251: For example, in the dot product between two vectors,
252: both vectors must be either Seq or MPI, not one of each
253: */
255: if ((a)->type != (b)->type) SETERRQ2(PETSC_ERR_ARG_NOTSAMETYPE,"Objects not of same type: Argument # %d and %d",arga,argb);
256: /*
257: Use this macro to check if the type is set
258: */
260: if (!(a)->type_name) SETERRQ1(PETSC_ERR_ARG_WRONGSTATE,"Object Type not set: Argument # %d",arg);
261: /*
262: Sometimes object must live on same communicator to inter-operate
263: */
265: {PetscErrorCode _6_ierr,__flag; _6_MPI_Comm_compare(((PetscObject)a)->comm,((PetscObject)b)->comm,&__flag);\
266: CHKERRQ(_6_ierr); \
267: if (__flag != MPI_CONGRUENT && __flag != MPI_IDENT) \
268: SETERRQ2(PETSC_ERR_ARG_NOTSAMECOMM,"Different communicators in the two objects: Argument # %d and %d",arga,argb);}
274: #endif
276: /*
277: All PETSc objects begin with the fields defined in PETSCHEADER.
278: The PetscObject is a way of examining these fields regardless of
279: the specific object. In C++ this could be a base abstract class
280: from which all objects are derived.
281: */
282: struct _p_PetscObject {
283: PETSCHEADER(int);
284: };
286: EXTERN PetscErrorCode PETSC_DLLEXPORT PetscObjectPublishBaseBegin(PetscObject);
287: EXTERN PetscErrorCode PETSC_DLLEXPORT PetscObjectPublishBaseEnd(PetscObject);
289: EXTERN PetscErrorCode PETSC_DLLEXPORT PetscObjectStateIncrease(PetscObject);
290: EXTERN PetscErrorCode PETSC_DLLEXPORT PetscObjectStateQuery(PetscObject,PetscInt*);
291: EXTERN PetscErrorCode PETSC_DLLEXPORT PetscObjectComposedDataRegister(PetscInt*);
292: EXTERN PetscErrorCode PETSC_DLLEXPORT PetscObjectComposedDataIncreaseInt(PetscObject);
293: EXTERN PetscErrorCode PETSC_DLLEXPORT PetscObjectComposedDataIncreaseIntstar(PetscObject);
294: EXTERN PetscErrorCode PETSC_DLLEXPORT PetscObjectComposedDataIncreaseReal(PetscObject);
295: EXTERN PetscErrorCode PETSC_DLLEXPORT PetscObjectComposedDataIncreaseRealstar(PetscObject);
296: EXTERN PetscErrorCode PETSC_DLLEXPORT PetscObjectComposedDataIncreaseScalar(PetscObject);
297: EXTERN PetscErrorCode PETSC_DLLEXPORT PetscObjectComposedDataIncreaseScalarstar(PetscObject);
298: EXTERN PetscInt PETSC_DLLEXPORT globalcurrentstate;
299: EXTERN PetscInt PETSC_DLLEXPORT globalmaxstate;
300: /*MC
301: PetscObjectComposedDataSetInt - attach integer data to a PetscObject
303: Synopsis:
304: PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)
306: Not collective
308: Input parameters:
309: + obj - the object to which data is to be attached
310: . id - the identifier for the data
311: - data - the data to be attached
313: Level: developer
314: M*/
315: #define PetscObjectComposedDataSetInt(obj,id,data) \
316: ((((obj)->int_idmax < globalmaxstate) ? PetscObjectComposedDataIncreaseInt(obj) : 0), \
317: (obj)->intcomposeddata[id] = data,(obj)->intcomposedstate[id] = (obj)->state, 0)
319: /*MC
320: PetscObjectComposedDataGetInt - retrieve integer data attached to an object
322: Synopsis:
323: PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int *data,PetscTruth *flag)
325: Not collective
327: Input parameters:
328: + obj - the object from which data is to be retrieved
329: - id - the identifier for the data
331: Output parameters
332: + data - the data to be retrieved
333: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
335: The 'data' and 'flag' variables are inlined, so they are not pointers.
337: Level: developer
338: M*/
339: #define PetscObjectComposedDataGetInt(obj,id,data,flag) \
340: ((((obj)->intcomposedstate && ((obj)->intcomposedstate[id] == (obj)->state)) ? \
341: (data = (obj)->intcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
343: /*MC
344: PetscObjectComposedDataSetIntstar - attach integer array data to a PetscObject
346: Synopsis:
347: PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)
349: Not collective
351: Input parameters:
352: + obj - the object to which data is to be attached
353: . id - the identifier for the data
354: - data - the data to be attached
356: Level: developer
357: M*/
358: #define PetscObjectComposedDataSetIntstar(obj,id,data) \
359: ((((obj)->intstar_idmax < globalmaxstate) ? PetscObjectComposedDataIncreaseIntstar(obj) : 0), \
360: (obj)->intstarcomposeddata[id] = data,(obj)->intstarcomposedstate[id] = (obj)->state, 0)
362: /*MC
363: PetscObjectComposedDataGetIntstar - retrieve integer array data
364: attached to an object
366: Synopsis:
367: PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int **data,PetscTruth *flag)
369: Not collective
371: Input parameters:
372: + obj - the object from which data is to be retrieved
373: - id - the identifier for the data
375: Output parameters
376: + data - the data to be retrieved
377: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
379: The 'data' and 'flag' variables are inlined, so they are not pointers.
381: Level: developer
382: M*/
383: #define PetscObjectComposedDataGetIntstar(obj,id,data,flag) \
384: ((((obj)->intstarcomposedstate && ((obj)->intstarcomposedstate[id] == (obj)->state)) ? \
385: (data = (obj)->intstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
387: /*MC
388: PetscObjectComposedDataSetReal - attach real data to a PetscObject
390: Synopsis:
391: PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)
393: Not collective
395: Input parameters:
396: + obj - the object to which data is to be attached
397: . id - the identifier for the data
398: - data - the data to be attached
400: Level: developer
401: M*/
402: #define PetscObjectComposedDataSetReal(obj,id,data) \
403: ((((obj)->real_idmax < globalmaxstate) ? PetscObjectComposedDataIncreaseReal(obj) : 0), \
404: (obj)->realcomposeddata[id] = data,(obj)->realcomposedstate[id] = (obj)->state, 0)
406: /*MC
407: PetscObjectComposedDataGetReal - retrieve real data attached to an object
409: Synopsis:
410: PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal *data,PetscTruth *flag)
412: Not collective
414: Input parameters:
415: + obj - the object from which data is to be retrieved
416: - id - the identifier for the data
418: Output parameters
419: + data - the data to be retrieved
420: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
422: The 'data' and 'flag' variables are inlined, so they are not pointers.
424: Level: developer
425: M*/
426: #define PetscObjectComposedDataGetReal(obj,id,data,flag) \
427: ((((obj)->realcomposedstate && ((obj)->realcomposedstate[id] == (obj)->state)) ? \
428: (data = (obj)->realcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
430: /*MC
431: PetscObjectComposedDataSetRealstar - attach real array data to a PetscObject
433: Synopsis:
434: PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)
436: Not collective
438: Input parameters:
439: + obj - the object to which data is to be attached
440: . id - the identifier for the data
441: - data - the data to be attached
443: Level: developer
444: M*/
445: #define PetscObjectComposedDataSetRealstar(obj,id,data) \
446: ((((obj)->realstar_idmax < globalmaxstate) ? PetscObjectComposedDataIncreaseRealstar(obj) : 0), \
447: (obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0)
449: /*MC
450: PetscObjectComposedDataGetRealstar - retrieve real array data
451: attached to an object
453: Synopsis:
454: PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal **data,PetscTruth *flag)
456: Not collective
458: Input parameters:
459: + obj - the object from which data is to be retrieved
460: - id - the identifier for the data
462: Output parameters
463: + data - the data to be retrieved
464: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
466: The 'data' and 'flag' variables are inlined, so they are not pointers.
468: Level: developer
469: M*/
470: #define PetscObjectComposedDataGetRealstar(obj,id,data,flag) \
471: ((((obj)->realstarcomposedstate && ((obj)->realstarcomposedstate[id] == (obj)->state)) ? \
472: (data = (obj)->realstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
474: /*MC
475: PetscObjectSetScalarComposedData - attach scalar data to a PetscObject
477: Synopsis:
478: PetscErrorCode PetscObjectSetScalarComposedData(PetscObject obj,int id,PetscScalar data)
480: Not collective
482: Input parameters:
483: + obj - the object to which data is to be attached
484: . id - the identifier for the data
485: - data - the data to be attached
487: Level: developer
488: M*/
489: #if defined(PETSC_USE_COMPLEX)
490: #define PetscObjectComposedDataSetScalar(obj,id,data) \
491: ((((obj)->scalar_idmax < globalmaxstate) ? PetscObjectComposedDataIncreaseScalar(obj) : 0) \
492: (obj)->scalarcomposeddata[id] = data,(obj)->scalarcomposedstate[id] = (obj)->state, 0)
493: #else
494: #define PetscObjectComposedDataSetScalar(obj,id,data) \
495: PetscObjectComposedDataSetReal(obj,id,data)
496: #endif
497: /*MC
498: PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object
500: Synopsis:
501: PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar *data,PetscTruth *flag)
503: Not collective
505: Input parameters:
506: + obj - the object from which data is to be retrieved
507: - id - the identifier for the data
509: Output parameters
510: + data - the data to be retrieved
511: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
513: The 'data' and 'flag' variables are inlined, so they are not pointers.
515: Level: developer
516: M*/
517: #if defined(PETSC_USE_COMPLEX)
518: #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
519: ((((obj)->scalarcomposedstate && ((obj)->scalarcomposedstate[id] == (obj)->state) ) ? \
520: (data = (obj)->scalarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
521: #else
522: #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
523: PetscObjectComposedDataGetReal(obj,id,data,flag)
524: #endif
526: /*MC
527: PetscObjectComposedDataSetScalarstar - attach scalar array data to a PetscObject
529: Synopsis:
530: PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)
532: Not collective
534: Input parameters:
535: + obj - the object to which data is to be attached
536: . id - the identifier for the data
537: - data - the data to be attached
539: Level: developer
540: M*/
541: #if defined(PETSC_USE_COMPLEX)
542: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
543: ((((obj)->scalarstar_idmax < globalmaxstate) ? PetscObjectComposedDataIncreaseScalarstar(obj) : 0), \
544: (obj)->scalarstarcomposeddata[id] = data,(obj)->scalarstarcomposedstate[id] = (obj)->state, 0)
545: #else
546: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
547: PetscObjectComposedDataSetRealstar(obj,id,data)
548: #endif
549: /*MC
550: PetscObjectComposedDataGetScalarstar - retrieve scalar array data
551: attached to an object
553: Synopsis:
554: PetscErrorCode PetscObjectComposedDataGetScalarstar(PetscObject obj,int id,PetscScalar **data,PetscTruth *flag)
556: Not collective
558: Input parameters:
559: + obj - the object from which data is to be retrieved
560: - id - the identifier for the data
562: Output parameters
563: + data - the data to be retrieved
564: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
566: The 'data' and 'flag' variables are inlined, so they are not pointers.
568: Level: developer
569: M*/
570: #if defined(PETSC_USE_COMPLEX)
571: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
572: ((((obj)->scalarstarcomposedstate && ((obj)->scalarstarcomposedstate[id] == (obj)->state)) ? \
573: (data = (obj)->scalarstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
574: #else
575: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
576: PetscObjectComposedDataGetRealstar(obj,id,data,flag)
577: #endif
580: #endif /* _PETSCHEAD_H */