xref: /petsc/src/dm/impls/swarm/data_bucket.c (revision 4be7464c47d97fbf9e870fd487bbf6c66fe08eeb)
152849c42SDave May 
252849c42SDave May #include "data_bucket.h"
352849c42SDave May 
452849c42SDave May /* string helpers */
52635f519SDave May #undef __FUNCT__
62635f519SDave May #define __FUNCT__ "StringInList"
72eac95f8SDave May PetscErrorCode StringInList(const char name[],const PetscInt N,const DataField gfield[],PetscBool *val)
852849c42SDave May {
95c18a9d6SDave May   PetscInt       i;
10521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
1152849c42SDave May 
12521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1352849c42SDave May   *val = PETSC_FALSE;
14521f74f9SMatthew G. Knepley   for (i = 0; i < N; ++i) {
15521f74f9SMatthew G. Knepley     PetscBool flg;
16521f74f9SMatthew G. Knepley     ierr = PetscStrcmp(name, gfield[i]->name, &flg);CHKERRQ(ierr);
17521f74f9SMatthew G. Knepley     if (flg) {
1852849c42SDave May       *val = PETSC_TRUE;
192eac95f8SDave May       PetscFunctionReturn(0);
2052849c42SDave May     }
2152849c42SDave May   }
222eac95f8SDave May   PetscFunctionReturn(0);
2352849c42SDave May }
2452849c42SDave May 
252635f519SDave May #undef __FUNCT__
262635f519SDave May #define __FUNCT__ "StringFindInList"
272eac95f8SDave May PetscErrorCode StringFindInList(const char name[],const PetscInt N,const DataField gfield[],PetscInt *index)
2852849c42SDave May {
295c18a9d6SDave May   PetscInt       i;
30521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
3152849c42SDave May 
32521f74f9SMatthew G. Knepley   PetscFunctionBegin;
3352849c42SDave May   *index = -1;
34521f74f9SMatthew G. Knepley   for (i = 0; i < N; ++i) {
35521f74f9SMatthew G. Knepley     PetscBool flg;
36521f74f9SMatthew G. Knepley     ierr = PetscStrcmp(name, gfield[i]->name, &flg);CHKERRQ(ierr);
37521f74f9SMatthew G. Knepley     if (flg) {
3852849c42SDave May       *index = i;
392eac95f8SDave May       PetscFunctionReturn(0);
4052849c42SDave May     }
4152849c42SDave May   }
422eac95f8SDave May   PetscFunctionReturn(0);
4352849c42SDave May }
4452849c42SDave May 
452eac95f8SDave May #undef __FUNCT__
462eac95f8SDave May #define __FUNCT__ "DataFieldCreate"
472eac95f8SDave May PetscErrorCode DataFieldCreate(const char registeration_function[],const char name[],const size_t size,const PetscInt L,DataField *DF)
4852849c42SDave May {
4952849c42SDave May   DataField      df;
50521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
5152849c42SDave May 
52521f74f9SMatthew G. Knepley   PetscFunctionBegin;
53521f74f9SMatthew G. Knepley   ierr = PetscMalloc(sizeof(struct _p_DataField), &df);CHKERRQ(ierr);
54521f74f9SMatthew G. Knepley   ierr = PetscMemzero(df, sizeof(struct _p_DataField));CHKERRQ(ierr);
55521f74f9SMatthew G. Knepley   ierr = PetscStrallocpy(registeration_function, &df->registeration_function);CHKERRQ(ierr);
56521f74f9SMatthew G. Knepley   ierr = PetscStrallocpy(name, &df->name);CHKERRQ(ierr);
5752849c42SDave May   df->atomic_size = size;
5852849c42SDave May   df->L  = L;
5952c3ed93SDave May   df->bs = 1;
60521f74f9SMatthew G. Knepley   /* allocate something so we don't have to reallocate */
61521f74f9SMatthew G. Knepley   ierr = PetscMalloc(size * L, &df->data);CHKERRQ(ierr);
62521f74f9SMatthew G. Knepley   ierr = PetscMemzero(df->data, size * L);CHKERRQ(ierr);
6352849c42SDave May   *DF = df;
642eac95f8SDave May   PetscFunctionReturn(0);
6552849c42SDave May }
6652849c42SDave May 
672eac95f8SDave May #undef __FUNCT__
682eac95f8SDave May #define __FUNCT__ "DataFieldDestroy"
692eac95f8SDave May PetscErrorCode DataFieldDestroy(DataField *DF)
7052849c42SDave May {
7152849c42SDave May   DataField      df = *DF;
72521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
7352849c42SDave May 
74521f74f9SMatthew G. Knepley   PetscFunctionBegin;
75521f74f9SMatthew G. Knepley   ierr = PetscFree(df->registeration_function);CHKERRQ(ierr);
76521f74f9SMatthew G. Knepley   ierr = PetscFree(df->name);CHKERRQ(ierr);
77521f74f9SMatthew G. Knepley   ierr = PetscFree(df->data);CHKERRQ(ierr);
78521f74f9SMatthew G. Knepley   ierr = PetscFree(df);CHKERRQ(ierr);
7952849c42SDave May   *DF  = NULL;
802eac95f8SDave May   PetscFunctionReturn(0);
8152849c42SDave May }
8252849c42SDave May 
8352849c42SDave May /* data bucket */
842eac95f8SDave May #undef __FUNCT__
852eac95f8SDave May #define __FUNCT__ "DataBucketCreate"
862eac95f8SDave May PetscErrorCode DataBucketCreate(DataBucket *DB)
8752849c42SDave May {
8852849c42SDave May   DataBucket     db;
89521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
9052849c42SDave May 
91521f74f9SMatthew G. Knepley   PetscFunctionBegin;
92521f74f9SMatthew G. Knepley   ierr = PetscMalloc(sizeof(struct _p_DataBucket), &db);CHKERRQ(ierr);
93521f74f9SMatthew G. Knepley   ierr = PetscMemzero(db, sizeof(struct _p_DataBucket));CHKERRQ(ierr);
9452849c42SDave May 
9552849c42SDave May   db->finalised = PETSC_FALSE;
9652849c42SDave May   /* create empty spaces for fields */
973454631fSDave May   db->L         = -1;
9852849c42SDave May   db->buffer    = 1;
9952849c42SDave May   db->allocated = 1;
10052849c42SDave May   db->nfields   = 0;
101521f74f9SMatthew G. Knepley   ierr = PetscMalloc1(1, &db->field);CHKERRQ(ierr);
10252849c42SDave May   *DB  = db;
1032eac95f8SDave May   PetscFunctionReturn(0);
10452849c42SDave May }
10552849c42SDave May 
1062eac95f8SDave May #undef __FUNCT__
1072eac95f8SDave May #define __FUNCT__ "DataBucketDestroy"
1082eac95f8SDave May PetscErrorCode DataBucketDestroy(DataBucket *DB)
10952849c42SDave May {
11052849c42SDave May   DataBucket     db = *DB;
1115c18a9d6SDave May   PetscInt       f;
112dbe06d34SDave May   PetscErrorCode ierr;
11352849c42SDave May 
114521f74f9SMatthew G. Knepley   PetscFunctionBegin;
11552849c42SDave May   /* release fields */
116521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
117dbe06d34SDave May     ierr = DataFieldDestroy(&db->field[f]);CHKERRQ(ierr);
11852849c42SDave May   }
11952849c42SDave May   /* this will catch the initially allocated objects in the event that no fields are registered */
12052849c42SDave May   if (db->field != NULL) {
121521f74f9SMatthew G. Knepley     ierr = PetscFree(db->field);CHKERRQ(ierr);
12252849c42SDave May   }
123521f74f9SMatthew G. Knepley   ierr = PetscFree(db);CHKERRQ(ierr);
12452849c42SDave May   *DB = NULL;
1252eac95f8SDave May   PetscFunctionReturn(0);
12652849c42SDave May }
12752849c42SDave May 
1282eac95f8SDave May #undef __FUNCT__
1290cb17e37SDave May #define __FUNCT__ "DataBucketQueryForActiveFields"
1300cb17e37SDave May PetscErrorCode DataBucketQueryForActiveFields(DataBucket db,PetscBool *any_active_fields)
1310cb17e37SDave May {
1320cb17e37SDave May   PetscInt f;
133521f74f9SMatthew G. Knepley 
134521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1350cb17e37SDave May   *any_active_fields = PETSC_FALSE;
136521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
1370cb17e37SDave May     if (db->field[f]->active) {
1380cb17e37SDave May       *any_active_fields = PETSC_TRUE;
1390cb17e37SDave May       PetscFunctionReturn(0);
1400cb17e37SDave May     }
1410cb17e37SDave May   }
1420cb17e37SDave May   PetscFunctionReturn(0);
1430cb17e37SDave May }
1440cb17e37SDave May 
1450cb17e37SDave May #undef __FUNCT__
1462eac95f8SDave May #define __FUNCT__ "DataBucketRegisterField"
1472eac95f8SDave May PetscErrorCode DataBucketRegisterField(
14852849c42SDave May                               DataBucket db,
14952849c42SDave May                               const char registeration_function[],
15052849c42SDave May                               const char field_name[],
15152849c42SDave May                               size_t atomic_size, DataField *_gfield)
15252849c42SDave May {
15352849c42SDave May   PetscBool val;
154*4be7464cSMatthew G. Knepley   DataField fp;
155dbe06d34SDave May   PetscErrorCode ierr;
15652849c42SDave May 
157521f74f9SMatthew G. Knepley   PetscFunctionBegin;
15852849c42SDave May 	/* check we haven't finalised the registration of fields */
15952849c42SDave May 	/*
16052849c42SDave May    if(db->finalised==PETSC_TRUE) {
16152849c42SDave May    printf("ERROR: DataBucketFinalize() has been called. Cannot register more fields\n");
16252849c42SDave May    ERROR();
16352849c42SDave May    }
16452849c42SDave May    */
16552849c42SDave May   /* check for repeated name */
1662635f519SDave May   ierr = StringInList(field_name, db->nfields, (const DataField*) db->field, &val);CHKERRQ(ierr);
1672eac95f8SDave May   if (val == PETSC_TRUE) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field %s already exists. Cannot add same field twice",field_name);
16852849c42SDave May   /* create new space for data */
169*4be7464cSMatthew G. Knepley   ierr = PetscRealloc(sizeof(DataField)*(db->nfields+1), &db->field);CHKERRQ(ierr);
17052849c42SDave May   /* add field */
171dbe06d34SDave May   ierr = DataFieldCreate(registeration_function, field_name, atomic_size, db->allocated, &fp);CHKERRQ(ierr);
17252849c42SDave May   db->field[db->nfields] = fp;
17352849c42SDave May   db->nfields++;
17452849c42SDave May   if (_gfield != NULL) {
17552849c42SDave May     *_gfield = fp;
17652849c42SDave May   }
1772eac95f8SDave May   PetscFunctionReturn(0);
17852849c42SDave May }
17952849c42SDave May 
18052849c42SDave May /*
18152849c42SDave May  #define DataBucketRegisterField(db,name,size,k) {\
18252849c42SDave May  char *location;\
18352849c42SDave May  asprintf(&location,"Registered by %s() at line %d within file %s", __FUNCTION__, __LINE__, __FILE__);\
18452849c42SDave May  _DataBucketRegisterField( (db), location, (name), (size), (k) );\
185521f74f9SMatthew G. Knepley  ierr = PetscFree(location);\
18652849c42SDave May  }
18752849c42SDave May  */
18852849c42SDave May 
1892eac95f8SDave May #undef __FUNCT__
1902eac95f8SDave May #define __FUNCT__ "DataBucketGetDataFieldByName"
1912eac95f8SDave May PetscErrorCode DataBucketGetDataFieldByName(DataBucket db,const char name[],DataField *gfield)
19252849c42SDave May {
1935c18a9d6SDave May   PetscInt       idx;
19452849c42SDave May   PetscBool      found;
195521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
19652849c42SDave May 
197521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1982635f519SDave May   ierr = StringInList(name,db->nfields,(const DataField*)db->field,&found);CHKERRQ(ierr);
1992eac95f8SDave May   if (!found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot find DataField with name %s",name);
2002635f519SDave May   ierr = StringFindInList(name,db->nfields,(const DataField*)db->field,&idx);CHKERRQ(ierr);
20152849c42SDave May   *gfield = db->field[idx];
2022eac95f8SDave May   PetscFunctionReturn(0);
20352849c42SDave May }
20452849c42SDave May 
2057fbf63aeSDave May #undef __FUNCT__
2067fbf63aeSDave May #define __FUNCT__ "DataBucketQueryDataFieldByName"
2077fbf63aeSDave May PetscErrorCode DataBucketQueryDataFieldByName(DataBucket db,const char name[],PetscBool *found)
20852849c42SDave May {
2092635f519SDave May   PetscErrorCode ierr;
210521f74f9SMatthew G. Knepley 
211521f74f9SMatthew G. Knepley   PetscFunctionBegin;
21252849c42SDave May   *found = PETSC_FALSE;
2132635f519SDave May   ierr = StringInList(name,db->nfields,(const DataField*)db->field,found);CHKERRQ(ierr);
2147fbf63aeSDave May   PetscFunctionReturn(0);
21552849c42SDave May }
21652849c42SDave May 
2177fbf63aeSDave May #undef __FUNCT__
2187fbf63aeSDave May #define __FUNCT__ "DataBucketFinalize"
2197fbf63aeSDave May PetscErrorCode DataBucketFinalize(DataBucket db)
22052849c42SDave May {
221521f74f9SMatthew G. Knepley   PetscFunctionBegin;
22252849c42SDave May   db->finalised = PETSC_TRUE;
2237fbf63aeSDave May   PetscFunctionReturn(0);
22452849c42SDave May }
22552849c42SDave May 
2267fbf63aeSDave May #undef __FUNCT__
2277fbf63aeSDave May #define __FUNCT__ "DataFieldGetNumEntries"
2287fbf63aeSDave May PetscErrorCode DataFieldGetNumEntries(DataField df,PetscInt *sum)
22952849c42SDave May {
230521f74f9SMatthew G. Knepley   PetscFunctionBegin;
23152849c42SDave May   *sum = df->L;
2327fbf63aeSDave May   PetscFunctionReturn(0);
23352849c42SDave May }
23452849c42SDave May 
2357fbf63aeSDave May #undef __FUNCT__
23652c3ed93SDave May #define __FUNCT__ "DataFieldSetBlockSize"
23752c3ed93SDave May PetscErrorCode DataFieldSetBlockSize(DataField df,PetscInt blocksize)
23852c3ed93SDave May {
239521f74f9SMatthew G. Knepley   PetscFunctionBegin;
24052c3ed93SDave May   df->bs = blocksize;
24152c3ed93SDave May   PetscFunctionReturn(0);
24252c3ed93SDave May }
24352c3ed93SDave May 
24452c3ed93SDave May #undef __FUNCT__
2457fbf63aeSDave May #define __FUNCT__ "DataFieldSetSize"
2467fbf63aeSDave May PetscErrorCode DataFieldSetSize(DataField df,const PetscInt new_L)
24752849c42SDave May {
248521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
24952849c42SDave May 
250521f74f9SMatthew G. Knepley   PetscFunctionBegin;
251a233d522SDave May   if (new_L <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot set size of DataField to be <= 0");
2527fbf63aeSDave May   if (new_L == df->L) PetscFunctionReturn(0);
25352849c42SDave May   if (new_L > df->L) {
254*4be7464cSMatthew G. Knepley     ierr = PetscRealloc(df->atomic_size * (new_L), &df->data);CHKERRQ(ierr);
25552849c42SDave May     /* init new contents */
256521f74f9SMatthew G. Knepley     ierr = PetscMemzero(( ((char*)df->data)+df->L*df->atomic_size), (new_L-df->L)*df->atomic_size);CHKERRQ(ierr);
2577fbf63aeSDave May   } else {
25852849c42SDave May     /* reallocate pointer list, add +1 in case new_L = 0 */
259*4be7464cSMatthew G. Knepley     ierr = PetscRealloc(df->atomic_size * (new_L+1), &df->data);CHKERRQ(ierr);
26052849c42SDave May   }
26152849c42SDave May   df->L = new_L;
2627fbf63aeSDave May   PetscFunctionReturn(0);
26352849c42SDave May }
26452849c42SDave May 
2657fbf63aeSDave May #undef __FUNCT__
2667fbf63aeSDave May #define __FUNCT__ "DataFieldZeroBlock"
2677fbf63aeSDave May PetscErrorCode DataFieldZeroBlock(DataField df,const PetscInt start,const PetscInt end)
26852849c42SDave May {
269521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
270521f74f9SMatthew G. Knepley 
271521f74f9SMatthew G. Knepley   PetscFunctionBegin;
2727fbf63aeSDave May   if (start > end) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot zero a block of entries if start(%D) > end(%D)",start,end);
2737fbf63aeSDave May   if (start < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot zero a block of entries if start(%D) < 0",start);
274a233d522SDave May   if (end > df->L) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot zero a block of entries if end(%D) >= array size(%D)",end,df->L);
275521f74f9SMatthew G. Knepley   ierr = PetscMemzero((((char*)df->data)+start*df->atomic_size), (end-start)*df->atomic_size);CHKERRQ(ierr);
2767fbf63aeSDave May   PetscFunctionReturn(0);
27752849c42SDave May }
27852849c42SDave May 
27952849c42SDave May /*
28052849c42SDave May  A negative buffer value will simply be ignored and the old buffer value will be used.
28152849c42SDave May  */
2827fbf63aeSDave May #undef __FUNCT__
2837fbf63aeSDave May #define __FUNCT__ "DataBucketSetSizes"
2847fbf63aeSDave May PetscErrorCode DataBucketSetSizes(DataBucket db,const PetscInt L,const PetscInt buffer)
28552849c42SDave May {
2865c18a9d6SDave May   PetscInt       current_allocated,new_used,new_unused,new_buffer,new_allocated,f;
2870cb17e37SDave May   PetscBool      any_active_fields;
288dbe06d34SDave May   PetscErrorCode ierr;
28952849c42SDave May 
290521f74f9SMatthew G. Knepley   PetscFunctionBegin;
2917fbf63aeSDave May   if (db->finalised == PETSC_FALSE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"You must call DataBucketFinalize() before DataBucketSetSizes()");
2920cb17e37SDave May   ierr = DataBucketQueryForActiveFields(db,&any_active_fields);CHKERRQ(ierr);
2930cb17e37SDave May   if (any_active_fields) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot safely re-size as at least one DataField is currently being accessed");
2940cb17e37SDave May 
29552849c42SDave May   current_allocated = db->allocated;
29652849c42SDave May   new_used   = L;
29752849c42SDave May   new_unused = current_allocated - new_used;
29852849c42SDave May   new_buffer = db->buffer;
29952849c42SDave May   if (buffer >= 0) { /* update the buffer value */
30052849c42SDave May     new_buffer = buffer;
30152849c42SDave May   }
30252849c42SDave May   new_allocated = new_used + new_buffer;
30352849c42SDave May   /* action */
30452849c42SDave May   if (new_allocated > current_allocated) {
30552849c42SDave May     /* increase size to new_used + new_buffer */
30652849c42SDave May     for (f=0; f<db->nfields; f++) {
307dbe06d34SDave May       ierr = DataFieldSetSize(db->field[f], new_allocated);CHKERRQ(ierr);
30852849c42SDave May     }
30952849c42SDave May     db->L         = new_used;
31052849c42SDave May     db->buffer    = new_buffer;
31152849c42SDave May     db->allocated = new_used + new_buffer;
312521f74f9SMatthew G. Knepley   } else {
31352849c42SDave May     if (new_unused > 2 * new_buffer) {
31452849c42SDave May       /* shrink array to new_used + new_buffer */
315521f74f9SMatthew G. Knepley       for (f = 0; f < db->nfields; ++f) {
316dbe06d34SDave May         ierr = DataFieldSetSize(db->field[f], new_allocated);CHKERRQ(ierr);
31752849c42SDave May       }
31852849c42SDave May       db->L         = new_used;
31952849c42SDave May       db->buffer    = new_buffer;
32052849c42SDave May       db->allocated = new_used + new_buffer;
321521f74f9SMatthew G. Knepley     } else {
32252849c42SDave May       db->L      = new_used;
32352849c42SDave May       db->buffer = new_buffer;
32452849c42SDave May     }
32552849c42SDave May   }
32652849c42SDave May   /* zero all entries from db->L to db->allocated */
327521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
32852849c42SDave May     DataField field = db->field[f];
329dbe06d34SDave May     ierr = DataFieldZeroBlock(field, db->L,db->allocated);CHKERRQ(ierr);
33052849c42SDave May   }
3317fbf63aeSDave May   PetscFunctionReturn(0);
33252849c42SDave May }
33352849c42SDave May 
3347fbf63aeSDave May #undef __FUNCT__
3357fbf63aeSDave May #define __FUNCT__ "DataBucketSetInitialSizes"
3367fbf63aeSDave May PetscErrorCode DataBucketSetInitialSizes(DataBucket db,const PetscInt L,const PetscInt buffer)
33752849c42SDave May {
3385c18a9d6SDave May   PetscInt       f;
339dbe06d34SDave May   PetscErrorCode ierr;
340dbe06d34SDave May 
341521f74f9SMatthew G. Knepley   PetscFunctionBegin;
342dbe06d34SDave May   ierr = DataBucketSetSizes(db,L,buffer);CHKERRQ(ierr);
343521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
34452849c42SDave May     DataField field = db->field[f];
345dbe06d34SDave May     ierr = DataFieldZeroBlock(field,0,db->allocated);CHKERRQ(ierr);
34652849c42SDave May   }
3477fbf63aeSDave May   PetscFunctionReturn(0);
34852849c42SDave May }
34952849c42SDave May 
3507fbf63aeSDave May #undef __FUNCT__
3517fbf63aeSDave May #define __FUNCT__ "DataBucketGetSizes"
3527fbf63aeSDave May PetscErrorCode DataBucketGetSizes(DataBucket db,PetscInt *L,PetscInt *buffer,PetscInt *allocated)
35352849c42SDave May {
354521f74f9SMatthew G. Knepley   PetscFunctionBegin;
35552849c42SDave May   if (L) {*L = db->L;}
35652849c42SDave May   if (buffer) {*buffer = db->buffer;}
35752849c42SDave May   if (allocated) {*allocated = db->allocated;}
3587fbf63aeSDave May   PetscFunctionReturn(0);
35952849c42SDave May }
36052849c42SDave May 
3617fbf63aeSDave May #undef __FUNCT__
3627fbf63aeSDave May #define __FUNCT__ "DataBucketGetGlobalSizes"
3637fbf63aeSDave May PetscErrorCode DataBucketGetGlobalSizes(MPI_Comm comm,DataBucket db,PetscInt *L,PetscInt *buffer,PetscInt *allocated)
36452849c42SDave May {
3655c18a9d6SDave May   PetscInt _L,_buffer,_allocated;
3665c18a9d6SDave May   PetscInt ierr;
36752849c42SDave May 
368521f74f9SMatthew G. Knepley   PetscFunctionBegin;
3695c18a9d6SDave May   _L = db->L;
3705c18a9d6SDave May   _buffer = db->buffer;
3715c18a9d6SDave May   _allocated = db->allocated;
37252849c42SDave May 
37333564166SDave May   if (L) {         ierr = MPI_Allreduce(&_L,L,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); }
37433564166SDave May   if (buffer) {    ierr = MPI_Allreduce(&_buffer,buffer,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); }
37533564166SDave May   if (allocated) { ierr = MPI_Allreduce(&_allocated,allocated,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); }
3767fbf63aeSDave May   PetscFunctionReturn(0);
37752849c42SDave May }
37852849c42SDave May 
3797fbf63aeSDave May #undef __FUNCT__
38089884300SDave May #define __FUNCT__ "DataBucketGetDataFields"
3817fbf63aeSDave May PetscErrorCode DataBucketGetDataFields(DataBucket db,PetscInt *L,DataField *fields[])
38252849c42SDave May {
383521f74f9SMatthew G. Knepley   PetscFunctionBegin;
38452849c42SDave May   if (L)      {*L      = db->nfields;}
38552849c42SDave May   if (fields) {*fields = db->field;}
3867fbf63aeSDave May   PetscFunctionReturn(0);
38752849c42SDave May }
38852849c42SDave May 
3897fbf63aeSDave May #undef __FUNCT__
3907fbf63aeSDave May #define __FUNCT__ "DataFieldGetAccess"
3917fbf63aeSDave May PetscErrorCode DataFieldGetAccess(const DataField gfield)
39252849c42SDave May {
393521f74f9SMatthew G. Knepley   PetscFunctionBegin;
3947fbf63aeSDave May   if (gfield->active) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is already active. You must call DataFieldRestoreAccess()",gfield->name);
39552849c42SDave May   gfield->active = PETSC_TRUE;
3967fbf63aeSDave May   PetscFunctionReturn(0);
39752849c42SDave May }
39852849c42SDave May 
3997fbf63aeSDave May #undef __FUNCT__
4007fbf63aeSDave May #define __FUNCT__ "DataFieldAccessPoint"
4017fbf63aeSDave May PetscErrorCode DataFieldAccessPoint(const DataField gfield,const PetscInt pid,void **ctx_p)
40252849c42SDave May {
403521f74f9SMatthew G. Knepley   PetscFunctionBegin;
40452849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
40552849c42SDave May   /* debug mode */
40684bcda08SDave May   /* check point is valid */
4077fbf63aeSDave May   if (pid < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
4087fbf63aeSDave May   if (pid >= gfield->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",gfield->L);
40984bcda08SDave May   if (gfield->active == PETSC_FALSE) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is not active. You must call DataFieldGetAccess() before point data can be retrivied",gfield->name);
41052849c42SDave May #endif
41152849c42SDave May   *ctx_p = __DATATFIELD_point_access(gfield->data,pid,gfield->atomic_size);
4127fbf63aeSDave May   PetscFunctionReturn(0);
41352849c42SDave May }
41452849c42SDave May 
4157fbf63aeSDave May #undef __FUNCT__
4167fbf63aeSDave May #define __FUNCT__ "DataFieldAccessPointOffset"
4177fbf63aeSDave May PetscErrorCode DataFieldAccessPointOffset(const DataField gfield,const size_t offset,const PetscInt pid,void **ctx_p)
41852849c42SDave May {
419521f74f9SMatthew G. Knepley   PetscFunctionBegin;
42052849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
42152849c42SDave May   /* debug mode */
42284bcda08SDave May   /* check point is valid */
423521f74f9SMatthew G. Knepley   /* if( offset < 0 ) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"offset must be >= 0");*/
424521f74f9SMatthew G. Knepley   /* Note compiler realizes this can never happen with an unsigned PetscInt */
4257fbf63aeSDave May   if (offset >= gfield->atomic_size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"offset must be < %zu",gfield->atomic_size);
42684bcda08SDave May   /* check point is valid */
4277fbf63aeSDave May   if (pid < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
428a233d522SDave May   if (pid >= gfield->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",gfield->L);
429a233d522SDave May   if (gfield->active == PETSC_FALSE) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is not active. You must call DataFieldGetAccess() before point data can be retrivied",gfield->name);
43052849c42SDave May #endif
43152849c42SDave May   *ctx_p = __DATATFIELD_point_access_offset(gfield->data,pid,gfield->atomic_size,offset);
4327fbf63aeSDave May   PetscFunctionReturn(0);
43352849c42SDave May }
43452849c42SDave May 
4357fbf63aeSDave May #undef __FUNCT__
43689884300SDave May #define __FUNCT__ "DataFieldRestoreAccess"
4377fbf63aeSDave May PetscErrorCode DataFieldRestoreAccess(DataField gfield)
43852849c42SDave May {
439521f74f9SMatthew G. Knepley   PetscFunctionBegin;
4407fbf63aeSDave May   if (gfield->active == PETSC_FALSE) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is not active. You must call DataFieldGetAccess()", gfield->name);
44152849c42SDave May   gfield->active = PETSC_FALSE;
4427fbf63aeSDave May   PetscFunctionReturn(0);
44352849c42SDave May }
44452849c42SDave May 
4457fbf63aeSDave May #undef __FUNCT__
4467fbf63aeSDave May #define __FUNCT__ "DataFieldVerifyAccess"
4477fbf63aeSDave May PetscErrorCode DataFieldVerifyAccess(const DataField gfield,const size_t size)
44852849c42SDave May {
449521f74f9SMatthew G. Knepley   PetscFunctionBegin;
45052849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
451521f74f9SMatthew G. Knepley   if (gfield->atomic_size != size) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" must be mapped to %zu bytes, your intended structure is %zu bytes in length.",gfield->name, gfield->atomic_size, size );
45252849c42SDave May #endif
4537fbf63aeSDave May   PetscFunctionReturn(0);
45452849c42SDave May }
45552849c42SDave May 
4567fbf63aeSDave May #undef __FUNCT__
4577fbf63aeSDave May #define __FUNCT__ "DataFieldGetAtomicSize"
4587fbf63aeSDave May PetscErrorCode DataFieldGetAtomicSize(const DataField gfield,size_t *size)
45952849c42SDave May {
460521f74f9SMatthew G. Knepley   PetscFunctionBegin;
46152849c42SDave May   if (size) {*size = gfield->atomic_size;}
4627fbf63aeSDave May   PetscFunctionReturn(0);
46352849c42SDave May }
46452849c42SDave May 
4657fbf63aeSDave May #undef __FUNCT__
4667fbf63aeSDave May #define __FUNCT__ "DataFieldGetEntries"
4677fbf63aeSDave May PetscErrorCode DataFieldGetEntries(const DataField gfield,void **data)
46852849c42SDave May {
469521f74f9SMatthew G. Knepley   PetscFunctionBegin;
470521f74f9SMatthew G. Knepley   if (data) {*data = gfield->data;}
4717fbf63aeSDave May   PetscFunctionReturn(0);
47252849c42SDave May }
47352849c42SDave May 
4747fbf63aeSDave May #undef __FUNCT__
4757fbf63aeSDave May #define __FUNCT__ "DataFieldRestoreEntries"
4767fbf63aeSDave May PetscErrorCode DataFieldRestoreEntries(const DataField gfield,void **data)
47752849c42SDave May {
478521f74f9SMatthew G. Knepley   PetscFunctionBegin;
479521f74f9SMatthew G. Knepley   if (data) {*data = NULL;}
4807fbf63aeSDave May   PetscFunctionReturn(0);
48152849c42SDave May }
48252849c42SDave May 
48352849c42SDave May /* y = x */
4847fbf63aeSDave May #undef __FUNCT__
4857fbf63aeSDave May #define __FUNCT__ "DataBucketCopyPoint"
4867fbf63aeSDave May PetscErrorCode DataBucketCopyPoint(const DataBucket xb,const PetscInt pid_x,
4875c18a9d6SDave May                          const DataBucket yb,const PetscInt pid_y)
48852849c42SDave May {
4895c18a9d6SDave May   PetscInt f;
490dbe06d34SDave May   PetscErrorCode ierr;
491dbe06d34SDave May 
492521f74f9SMatthew G. Knepley   PetscFunctionBegin;
493521f74f9SMatthew G. Knepley   for (f = 0; f < xb->nfields; ++f) {
49452849c42SDave May     void *dest;
49552849c42SDave May     void *src;
49652849c42SDave May 
497dbe06d34SDave May     ierr = DataFieldGetAccess(xb->field[f]);CHKERRQ(ierr);
4986845f8f5SDave May     if (xb != yb) { ierr = DataFieldGetAccess( yb->field[f]);CHKERRQ(ierr); }
499dbe06d34SDave May     ierr = DataFieldAccessPoint(xb->field[f],pid_x, &src);CHKERRQ(ierr);
500dbe06d34SDave May     ierr = DataFieldAccessPoint(yb->field[f],pid_y, &dest);CHKERRQ(ierr);
501521f74f9SMatthew G. Knepley     ierr = PetscMemcpy(dest, src, xb->field[f]->atomic_size);CHKERRQ(ierr);
502dbe06d34SDave May     ierr = DataFieldRestoreAccess(xb->field[f]);CHKERRQ(ierr);
5036845f8f5SDave May     if (xb != yb) {ierr = DataFieldRestoreAccess(yb->field[f]);CHKERRQ(ierr);}
50452849c42SDave May   }
5057fbf63aeSDave May   PetscFunctionReturn(0);
50652849c42SDave May }
50752849c42SDave May 
5087fbf63aeSDave May #undef __FUNCT__
5097fbf63aeSDave May #define __FUNCT__ "DataBucketCreateFromSubset"
5107fbf63aeSDave May PetscErrorCode DataBucketCreateFromSubset(DataBucket DBIn,const PetscInt N,const PetscInt list[],DataBucket *DB)
51152849c42SDave May {
5125c18a9d6SDave May   PetscInt nfields;
51352849c42SDave May   DataField *fields;
5145c18a9d6SDave May   PetscInt f,L,buffer,allocated,p;
515dbe06d34SDave May   PetscErrorCode ierr;
51652849c42SDave May 
517521f74f9SMatthew G. Knepley   PetscFunctionBegin;
518521f74f9SMatthew G. Knepley   ierr = DataBucketCreate(DB);CHKERRQ(ierr);
51952849c42SDave May   /* copy contents of DBIn */
520dbe06d34SDave May   ierr = DataBucketGetDataFields(DBIn,&nfields,&fields);CHKERRQ(ierr);
521dbe06d34SDave May   ierr = DataBucketGetSizes(DBIn,&L,&buffer,&allocated);CHKERRQ(ierr);
522521f74f9SMatthew G. Knepley   for (f = 0; f < nfields; ++f) {
523dbe06d34SDave May     ierr = DataBucketRegisterField(*DB,"DataBucketCreateFromSubset",fields[f]->name,fields[f]->atomic_size,NULL);CHKERRQ(ierr);
52452849c42SDave May   }
525dbe06d34SDave May   ierr = DataBucketFinalize(*DB);CHKERRQ(ierr);
526dbe06d34SDave May   ierr = DataBucketSetSizes(*DB,L,buffer);CHKERRQ(ierr);
52752849c42SDave May   /* now copy the desired guys from DBIn => DB */
528521f74f9SMatthew G. Knepley   for (p = 0; p < N; ++p) {
529dbe06d34SDave May     ierr = DataBucketCopyPoint(DBIn,list[p], *DB,p);CHKERRQ(ierr);
53052849c42SDave May   }
5317fbf63aeSDave May   PetscFunctionReturn(0);
53252849c42SDave May }
53352849c42SDave May 
534521f74f9SMatthew G. Knepley /* insert into an exisitng location */
5357fbf63aeSDave May #undef __FUNCT__
5367fbf63aeSDave May #define __FUNCT__ "DataFieldInsertPoint"
5377fbf63aeSDave May PetscErrorCode DataFieldInsertPoint(const DataField field,const PetscInt index,const void *ctx)
53852849c42SDave May {
539521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
54052849c42SDave May 
541521f74f9SMatthew G. Knepley   PetscFunctionBegin;
54252849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
54384bcda08SDave May   /* check point is valid */
544a233d522SDave May   if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
545a233d522SDave May   if (index >= field->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",field->L);
54652849c42SDave May #endif
547521f74f9SMatthew G. Knepley   ierr = PetscMemcpy(__DATATFIELD_point_access(field->data,index,field->atomic_size), ctx, field->atomic_size);CHKERRQ(ierr);
5487fbf63aeSDave May   PetscFunctionReturn(0);
54952849c42SDave May }
55052849c42SDave May 
551521f74f9SMatthew G. Knepley /* remove data at index - replace with last point */
552a233d522SDave May #undef __FUNCT__
553a233d522SDave May #define __FUNCT__ "DataBucketRemovePointAtIndex"
5547fbf63aeSDave May PetscErrorCode DataBucketRemovePointAtIndex(const DataBucket db,const PetscInt index)
55552849c42SDave May {
5565c18a9d6SDave May   PetscInt       f;
5570cb17e37SDave May   PetscBool      any_active_fields;
558dbe06d34SDave May   PetscErrorCode ierr;
55952849c42SDave May 
560521f74f9SMatthew G. Knepley   PetscFunctionBegin;
56152849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
56284bcda08SDave May   /* check point is valid */
563a233d522SDave May   if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
564a233d522SDave May   if (index >= db->allocated) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",db->L+db->buffer);
56552849c42SDave May #endif
5660cb17e37SDave May   ierr = DataBucketQueryForActiveFields(db,&any_active_fields);CHKERRQ(ierr);
5670cb17e37SDave May   if (any_active_fields) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot safely remove point as at least one DataField is currently being accessed");
568a233d522SDave May   if (index >= db->L) { /* this point is not in the list - no need to error, but I will anyway */
569a233d522SDave May     SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"You should not be trying to remove point at index=%D since it's < db->L = %D", index, db->L);
57052849c42SDave May   }
571a233d522SDave May   if (index != db->L-1) { /* not last point in list */
572521f74f9SMatthew G. Knepley     for (f = 0; f < db->nfields; ++f) {
57352849c42SDave May       DataField field = db->field[f];
57452849c42SDave May 
57552849c42SDave May       /* copy then remove */
576dbe06d34SDave May       ierr = DataFieldCopyPoint(db->L-1, field, index, field);CHKERRQ(ierr);
577521f74f9SMatthew G. Knepley       /* DataFieldZeroPoint(field,index); */
57852849c42SDave May     }
57952849c42SDave May   }
58052849c42SDave May   /* decrement size */
58152849c42SDave May   /* this will zero out an crap at the end of the list */
582dbe06d34SDave May   ierr = DataBucketRemovePoint(db);CHKERRQ(ierr);
5837fbf63aeSDave May   PetscFunctionReturn(0);
58452849c42SDave May }
58552849c42SDave May 
58652849c42SDave May /* copy x into y */
5877fbf63aeSDave May #undef __FUNCT__
5887fbf63aeSDave May #define __FUNCT__ "DataFieldCopyPoint"
5897fbf63aeSDave May PetscErrorCode DataFieldCopyPoint(const PetscInt pid_x,const DataField field_x,
5905c18a9d6SDave May                         const PetscInt pid_y,const DataField field_y )
59152849c42SDave May {
592521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
59352849c42SDave May 
594521f74f9SMatthew G. Knepley   PetscFunctionBegin;
59552849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
59684bcda08SDave May   /* check point is valid */
597a233d522SDave May   if (pid_x < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"(IN) index must be >= 0");
598a233d522SDave May   if (pid_x >= field_x->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"(IN) index must be < %D",field_x->L);
599a233d522SDave May   if (pid_y < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"(OUT) index must be >= 0");
600a233d522SDave May   if (pid_y >= field_y->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"(OUT) index must be < %D",field_y->L);
601521f74f9SMatthew G. Knepley   if( field_y->atomic_size != field_x->atomic_size ) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"atomic size must match");
60252849c42SDave May #endif
603521f74f9SMatthew G. Knepley   ierr = PetscMemcpy(__DATATFIELD_point_access(field_y->data,pid_y,field_y->atomic_size),
60452849c42SDave May                      __DATATFIELD_point_access(field_x->data,pid_x,field_x->atomic_size),
605521f74f9SMatthew G. Knepley                      field_y->atomic_size);CHKERRQ(ierr);
6067fbf63aeSDave May   PetscFunctionReturn(0);
60752849c42SDave May }
60852849c42SDave May 
60952849c42SDave May 
610521f74f9SMatthew G. Knepley /* zero only the datafield at this point */
6117fbf63aeSDave May #undef __FUNCT__
6127fbf63aeSDave May #define __FUNCT__ "DataFieldZeroPoint"
6137fbf63aeSDave May PetscErrorCode DataFieldZeroPoint(const DataField field,const PetscInt index)
61452849c42SDave May {
615521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
616521f74f9SMatthew G. Knepley 
617521f74f9SMatthew G. Knepley   PetscFunctionBegin;
61852849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
61984bcda08SDave May   /* check point is valid */
620a233d522SDave May   if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
621a233d522SDave May   if (index >= field->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",field->L);
62252849c42SDave May #endif
623521f74f9SMatthew G. Knepley   ierr = PetscMemzero(__DATATFIELD_point_access(field->data,index,field->atomic_size), field->atomic_size);CHKERRQ(ierr);
6247fbf63aeSDave May   PetscFunctionReturn(0);
62552849c42SDave May }
62652849c42SDave May 
627521f74f9SMatthew G. Knepley /* zero ALL data for this point */
6287fbf63aeSDave May #undef __FUNCT__
6297fbf63aeSDave May #define __FUNCT__ "DataBucketZeroPoint"
6307fbf63aeSDave May PetscErrorCode DataBucketZeroPoint(const DataBucket db,const PetscInt index)
63152849c42SDave May {
6325c18a9d6SDave May   PetscInt f;
633dbe06d34SDave May   PetscErrorCode ierr;
63452849c42SDave May 
635521f74f9SMatthew G. Knepley   PetscFunctionBegin;
63684bcda08SDave May   /* check point is valid */
637a233d522SDave May   if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
638a233d522SDave May   if (index >= db->allocated) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",db->allocated);
639521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
64052849c42SDave May     DataField field = db->field[f];
641dbe06d34SDave May     ierr = DataFieldZeroPoint(field,index);CHKERRQ(ierr);
64252849c42SDave May   }
6437fbf63aeSDave May   PetscFunctionReturn(0);
64452849c42SDave May }
64552849c42SDave May 
64652849c42SDave May /* increment */
6477fbf63aeSDave May #undef __FUNCT__
6487fbf63aeSDave May #define __FUNCT__ "DataBucketAddPoint"
6497fbf63aeSDave May PetscErrorCode DataBucketAddPoint(DataBucket db)
65052849c42SDave May {
651dbe06d34SDave May   PetscErrorCode ierr;
652dbe06d34SDave May 
653521f74f9SMatthew G. Knepley   PetscFunctionBegin;
654dbe06d34SDave May   ierr = DataBucketSetSizes(db,db->L+1,-1);CHKERRQ(ierr);
6557fbf63aeSDave May   PetscFunctionReturn(0);
65652849c42SDave May }
65752849c42SDave May 
6587fbf63aeSDave May /* decrement */
6597fbf63aeSDave May #undef __FUNCT__
6607fbf63aeSDave May #define __FUNCT__ "DataBucketRemovePoint"
6617fbf63aeSDave May PetscErrorCode DataBucketRemovePoint(DataBucket db)
6627fbf63aeSDave May {
663dbe06d34SDave May   PetscErrorCode ierr;
664dbe06d34SDave May 
665521f74f9SMatthew G. Knepley   PetscFunctionBegin;
666dbe06d34SDave May   ierr = DataBucketSetSizes(db,db->L-1,-1);CHKERRQ(ierr);
6677fbf63aeSDave May   PetscFunctionReturn(0);
6687fbf63aeSDave May }
6697fbf63aeSDave May 
6707fbf63aeSDave May #undef __FUNCT__
6717fbf63aeSDave May #define __FUNCT__ "_DataFieldViewBinary"
6727fbf63aeSDave May PetscErrorCode _DataFieldViewBinary(DataField field,FILE *fp)
67352849c42SDave May {
674521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
67552849c42SDave May 
676521f74f9SMatthew G. Knepley   PetscFunctionBegin;
677521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF, fp,"<DataField>\n");CHKERRQ(ierr);
678521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF, fp,"%D\n", field->L);CHKERRQ(ierr);
679521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF, fp,"%zu\n",field->atomic_size);CHKERRQ(ierr);
680521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF, fp,"%s\n", field->registeration_function);CHKERRQ(ierr);
681521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF, fp,"%s\n", field->name);CHKERRQ(ierr);
68252849c42SDave May   fwrite(field->data, field->atomic_size, field->L, fp);
683521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF, fp,"\n</DataField>\n");CHKERRQ(ierr);
6847fbf63aeSDave May   PetscFunctionReturn(0);
68552849c42SDave May }
68652849c42SDave May 
6877fbf63aeSDave May #undef __FUNCT__
6887fbf63aeSDave May #define __FUNCT__ "_DataBucketRegisterFieldFromFile"
6897fbf63aeSDave May PetscErrorCode _DataBucketRegisterFieldFromFile(FILE *fp,DataBucket db)
69052849c42SDave May {
69152849c42SDave May   PetscBool      val;
69252849c42SDave May   DataField      gfield;
69352849c42SDave May   char           dummy[100];
69452849c42SDave May   char           registeration_function[5000];
69552849c42SDave May   char           field_name[5000];
6965c18a9d6SDave May   PetscInt       L;
69752849c42SDave May   size_t         atomic_size,strL;
698dbe06d34SDave May   PetscErrorCode ierr;
69952849c42SDave May 
700521f74f9SMatthew G. Knepley   PetscFunctionBegin;
70152849c42SDave May   /* check we haven't finalised the registration of fields */
70252849c42SDave May   /*
70352849c42SDave May    if(db->finalised==PETSC_TRUE) {
70452849c42SDave May    printf("ERROR: DataBucketFinalize() has been called. Cannot register more fields\n");
70552849c42SDave May    ERROR();
70652849c42SDave May    }
70752849c42SDave May    */
70852849c42SDave May   /* read file contents */
709521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
710fc2c8c6aSSatish Balay   fscanf(fp, "%" PetscInt_FMT "\n",&L);
711521f74f9SMatthew G. Knepley   fscanf(fp, "%zu\n",&atomic_size);
712521f74f9SMatthew G. Knepley   fgets(registeration_function,4999,fp);
71352849c42SDave May   strL = strlen(registeration_function);
71452849c42SDave May   if (strL > 1) {
71552849c42SDave May     registeration_function[strL-1] = 0;
71652849c42SDave May   }
717521f74f9SMatthew G. Knepley   fgets(field_name,4999,fp);
71852849c42SDave May   strL = strlen(field_name);
71952849c42SDave May   if (strL > 1) {
72052849c42SDave May     field_name[strL-1] = 0;
72152849c42SDave May   }
72252849c42SDave May 
7234b46c5e1SDave May #ifdef DATA_BUCKET_LOG
724521f74f9SMatthew G. Knepley   ierr = PetscPrintf(PETSC_COMM_SELF,"  ** read L=%D; atomic_size=%zu; reg_func=\"%s\"; name=\"%s\" \n", L,atomic_size,registeration_function,field_name);CHKERRQ(ierr);
72552849c42SDave May #endif
72652849c42SDave May   /* check for repeated name */
7272635f519SDave May   ierr = StringInList( field_name, db->nfields, (const DataField*)db->field, &val );CHKERRQ(ierr);
728a233d522SDave May   if (val == PETSC_TRUE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot add same field twice");
72952849c42SDave May   /* create new space for data */
730*4be7464cSMatthew G. Knepley   ierr = PetscRealloc(sizeof(DataField)*(db->nfields+1), &db->field);CHKERRQ(ierr);
73152849c42SDave May   /* add field */
732dbe06d34SDave May   ierr = DataFieldCreate( registeration_function, field_name, atomic_size, L, &gfield );CHKERRQ(ierr);
73352849c42SDave May   /* copy contents of file */
73452849c42SDave May   fread(gfield->data, gfield->atomic_size, gfield->L, fp);
7354b46c5e1SDave May #ifdef DATA_BUCKET_LOG
736521f74f9SMatthew G. Knepley   ierr = PetscPrintf(PETSC_COMM_SELF,"  ** read %zu bytes for DataField \"%s\" \n", gfield->atomic_size * gfield->L, field_name);CHKERRQ(ierr);
73752849c42SDave May #endif
73852849c42SDave May   /* finish reading meta data */
739521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
740521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
74152849c42SDave May   db->field[db->nfields] = gfield;
74252849c42SDave May   db->nfields++;
7437fbf63aeSDave May   PetscFunctionReturn(0);
74452849c42SDave May }
74552849c42SDave May 
7467fbf63aeSDave May #undef __FUNCT__
7477fbf63aeSDave May #define __FUNCT__ "_DataBucketViewAscii_HeaderWrite_v00"
7487fbf63aeSDave May PetscErrorCode _DataBucketViewAscii_HeaderWrite_v00(FILE *fp)
74952849c42SDave May {
750521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
751521f74f9SMatthew G. Knepley 
752521f74f9SMatthew G. Knepley   PetscFunctionBegin;
753521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"<DataBucketHeader>\n");CHKERRQ(ierr);
754521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"type=DataBucket\n");CHKERRQ(ierr);
755521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"format=ascii\n");CHKERRQ(ierr);
756521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"version=0.0\n");CHKERRQ(ierr);
757521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"options=\n");CHKERRQ(ierr);
758521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"</DataBucketHeader>\n");CHKERRQ(ierr);
7597fbf63aeSDave May   PetscFunctionReturn(0);
76052849c42SDave May }
7617fbf63aeSDave May 
7627fbf63aeSDave May #undef __FUNCT__
7637fbf63aeSDave May #define __FUNCT__ "_DataBucketViewAscii_HeaderRead_v00"
7647fbf63aeSDave May PetscErrorCode _DataBucketViewAscii_HeaderRead_v00(FILE *fp)
76552849c42SDave May {
76652849c42SDave May   char           dummy[100];
76752849c42SDave May   size_t         strL;
768521f74f9SMatthew G. Knepley   PetscBool      flg;
769521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
77052849c42SDave May 
771521f74f9SMatthew G. Knepley   PetscFunctionBegin;
772521f74f9SMatthew G. Knepley   /* header open */
773521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
77452849c42SDave May 
775521f74f9SMatthew G. Knepley   /* type */
776521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
77752849c42SDave May   strL = strlen(dummy);
77852849c42SDave May   if (strL > 1) {dummy[strL-1] = 0;}
779521f74f9SMatthew G. Knepley   ierr = PetscStrcmp(dummy, "type=DataBucket", &flg);CHKERRQ(ierr);
780521f74f9SMatthew G. Knepley   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Data file doesn't contain a DataBucket type");
781521f74f9SMatthew G. Knepley   /* format */
782521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
783521f74f9SMatthew G. Knepley   /* version */
784521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
78552849c42SDave May   strL = strlen(dummy);
78652849c42SDave May   if (strL > 1) { dummy[strL-1] = 0; }
787521f74f9SMatthew G. Knepley   ierr = PetscStrcmp(dummy, "version=0.0", &flg);CHKERRQ(ierr);
788521f74f9SMatthew G. Knepley   if (!flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"DataBucket file must be parsed with version=0.0 : You tried %s", dummy);
789521f74f9SMatthew G. Knepley   /* options */
790521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
791521f74f9SMatthew G. Knepley   /* header close */
792521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
7937fbf63aeSDave May   PetscFunctionReturn(0);
79452849c42SDave May }
79552849c42SDave May 
7967fbf63aeSDave May #undef __FUNCT__
7977fbf63aeSDave May #define __FUNCT__ "_DataBucketLoadFromFileBinary_SEQ"
7987fbf63aeSDave May PetscErrorCode _DataBucketLoadFromFileBinary_SEQ(const char filename[],DataBucket *_db)
79952849c42SDave May {
80052849c42SDave May   DataBucket db;
80152849c42SDave May   FILE *fp;
8025c18a9d6SDave May   PetscInt L,buffer,f,nfields;
803dbe06d34SDave May   PetscErrorCode ierr;
80452849c42SDave May 
805521f74f9SMatthew G. Knepley   PetscFunctionBegin;
8064b46c5e1SDave May #ifdef DATA_BUCKET_LOG
807521f74f9SMatthew G. Knepley   ierr = PetscPrintf(PETSC_COMM_SELF,"** DataBucketLoadFromFile **\n");CHKERRQ(ierr);
80852849c42SDave May #endif
80952849c42SDave May   /* open file */
81052849c42SDave May   fp = fopen(filename,"rb");
811521f74f9SMatthew G. Knepley   if (fp == NULL) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file with name %s", filename);
81252849c42SDave May   /* read header */
813dbe06d34SDave May   ierr = _DataBucketViewAscii_HeaderRead_v00(fp);CHKERRQ(ierr);
814fc2c8c6aSSatish Balay   fscanf(fp,"%" PetscInt_FMT "\n%" PetscInt_FMT "\n%" PetscInt_FMT "\n",&L,&buffer,&nfields);
815dbe06d34SDave May   ierr = DataBucketCreate(&db);CHKERRQ(ierr);
816521f74f9SMatthew G. Knepley   for (f = 0; f < nfields; ++f) {
817dbe06d34SDave May     ierr = _DataBucketRegisterFieldFromFile(fp,db);CHKERRQ(ierr);
81852849c42SDave May   }
81952849c42SDave May   fclose(fp);
820dbe06d34SDave May   ierr = DataBucketFinalize(db);CHKERRQ(ierr);
82152849c42SDave May   /*
82252849c42SDave May    DataBucketSetSizes(db,L,buffer);
82352849c42SDave May    */
82452849c42SDave May   db->L = L;
82552849c42SDave May   db->buffer = buffer;
82652849c42SDave May   db->allocated = L + buffer;
82752849c42SDave May   *_db = db;
8287fbf63aeSDave May   PetscFunctionReturn(0);
82952849c42SDave May }
83052849c42SDave May 
8317fbf63aeSDave May #undef __FUNCT__
8327fbf63aeSDave May #define __FUNCT__ "DataBucketLoadFromFile"
8337fbf63aeSDave May PetscErrorCode DataBucketLoadFromFile(MPI_Comm comm,const char filename[],DataBucketViewType type,DataBucket *db)
83452849c42SDave May {
8355c18a9d6SDave May   PetscMPIInt    nproc,rank;
836997fa542SDave May   PetscErrorCode ierr;
83752849c42SDave May 
838521f74f9SMatthew G. Knepley   PetscFunctionBegin;
839997fa542SDave May   ierr = MPI_Comm_size(comm,&nproc);CHKERRQ(ierr);
840997fa542SDave May   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
8414b46c5e1SDave May #ifdef DATA_BUCKET_LOG
842521f74f9SMatthew G. Knepley   ierr = PetscPrintf(PETSC_COMM_SELF,"** DataBucketLoadFromFile **\n");CHKERRQ(ierr);
84352849c42SDave May #endif
84452849c42SDave May   if (type == DATABUCKET_VIEW_STDOUT) {
84552849c42SDave May   } else if (type == DATABUCKET_VIEW_ASCII) {
846a233d522SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot be implemented as we don't know the underlying particle data structure");
84752849c42SDave May   } else if (type == DATABUCKET_VIEW_BINARY) {
84852849c42SDave May     if (nproc == 1) {
849dbe06d34SDave May       ierr = _DataBucketLoadFromFileBinary_SEQ(filename,db);CHKERRQ(ierr);
85052849c42SDave May     } else {
851521f74f9SMatthew G. Knepley       char name[PETSC_MAX_PATH_LEN];
85252849c42SDave May 
853521f74f9SMatthew G. Knepley       ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "%s_p%1.5d", filename, rank);CHKERRQ(ierr);
854dbe06d34SDave May       ierr = _DataBucketLoadFromFileBinary_SEQ(name, db);CHKERRQ(ierr);
85552849c42SDave May     }
856521f74f9SMatthew G. Knepley   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unknown viewer requested");
8577fbf63aeSDave May   PetscFunctionReturn(0);
85852849c42SDave May }
85952849c42SDave May 
8607fbf63aeSDave May #undef __FUNCT__
8617fbf63aeSDave May #define __FUNCT__ "_DataBucketViewBinary"
8627fbf63aeSDave May PetscErrorCode _DataBucketViewBinary(DataBucket db,const char filename[])
86352849c42SDave May {
86452849c42SDave May   FILE          *fp = NULL;
8655c18a9d6SDave May   PetscInt       f;
866dbe06d34SDave May   PetscErrorCode ierr;
86752849c42SDave May 
868521f74f9SMatthew G. Knepley   PetscFunctionBegin;
86952849c42SDave May   fp = fopen(filename,"wb");
870a233d522SDave May   if (fp == NULL) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot open file with name %s", filename);
87152849c42SDave May   /* db header */
872dbe06d34SDave May   ierr =_DataBucketViewAscii_HeaderWrite_v00(fp);CHKERRQ(ierr);
87352849c42SDave May   /* meta-data */
874521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF, fp, "%D\n%D\n%D\n", db->L,db->buffer,db->nfields);CHKERRQ(ierr);
87552849c42SDave May   /* load datafields */
876521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
877dbe06d34SDave May     ierr = _DataFieldViewBinary(db->field[f],fp);CHKERRQ(ierr);
87852849c42SDave May   }
87952849c42SDave May   fclose(fp);
8807fbf63aeSDave May   PetscFunctionReturn(0);
88152849c42SDave May }
88252849c42SDave May 
8837fbf63aeSDave May #undef __FUNCT__
8847fbf63aeSDave May #define __FUNCT__ "DataBucketView_SEQ"
8857fbf63aeSDave May PetscErrorCode DataBucketView_SEQ(DataBucket db,const char filename[],DataBucketViewType type)
88652849c42SDave May {
887dbe06d34SDave May   PetscErrorCode ierr;
888dbe06d34SDave May 
889521f74f9SMatthew G. Knepley   PetscFunctionBegin;
89052849c42SDave May   switch (type) {
89152849c42SDave May   case DATABUCKET_VIEW_STDOUT:
89252849c42SDave May   {
8935c18a9d6SDave May     PetscInt f;
89452849c42SDave May     double memory_usage_total = 0.0;
89552849c42SDave May 
896521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"DataBucketView(SEQ): (\"%s\")\n",filename);CHKERRQ(ierr);
897521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  L                  = %D \n", db->L);CHKERRQ(ierr);
898521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  buffer             = %D \n", db->buffer);CHKERRQ(ierr);
899521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  allocated          = %D \n", db->allocated);CHKERRQ(ierr);
900521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  nfields registered = %D \n", db->nfields);CHKERRQ(ierr);
901521f74f9SMatthew G. Knepley     for (f = 0; f < db->nfields; ++f) {
90252849c42SDave May       double memory_usage_f = (double)(db->field[f]->atomic_size * db->allocated) * 1.0e-6;
903521f74f9SMatthew G. Knepley       ierr = PetscPrintf(PETSC_COMM_SELF,"    [%3D]: field name  ==>> %30s : Mem. usage = %1.2e (MB) \n", f, db->field[f]->name, memory_usage_f );CHKERRQ(ierr);
904521f74f9SMatthew G. Knepley       ierr = PetscPrintf(PETSC_COMM_SELF,"           blocksize          = %D \n", db->field[f]->bs);CHKERRQ(ierr);
90552c3ed93SDave May       if (db->field[f]->bs != 1) {
906521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PETSC_COMM_SELF,"           atomic size        = %zu [full block, bs=%D]\n", db->field[f]->atomic_size,db->field[f]->bs);CHKERRQ(ierr);
907521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PETSC_COMM_SELF,"           atomic size/item   = %zu \n", db->field[f]->atomic_size/db->field[f]->bs);CHKERRQ(ierr);
90852c3ed93SDave May       } else {
909521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PETSC_COMM_SELF,"           atomic size        = %zu \n", db->field[f]->atomic_size);CHKERRQ(ierr);
91052c3ed93SDave May       }
91152849c42SDave May       memory_usage_total += memory_usage_f;
91252849c42SDave May     }
913521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  Total mem. usage                                                      = %1.2e (MB) \n", memory_usage_total);CHKERRQ(ierr);
91452849c42SDave May   }
91552849c42SDave May   break;
91652849c42SDave May   case DATABUCKET_VIEW_ASCII:
91752849c42SDave May   {
918a233d522SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot be implemented as we don't know the underlying particle data structure");
91952849c42SDave May   }
92052849c42SDave May   break;
92152849c42SDave May   case DATABUCKET_VIEW_BINARY:
92252849c42SDave May   {
923dbe06d34SDave May     ierr = _DataBucketViewBinary(db,filename);CHKERRQ(ierr);
92452849c42SDave May   }
92552849c42SDave May   break;
92652849c42SDave May   case DATABUCKET_VIEW_HDF5:
92752849c42SDave May   {
928a233d522SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No HDF5 support");
92952849c42SDave May   }
93052849c42SDave May   break;
931521f74f9SMatthew G. Knepley   default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer method requested");
93252849c42SDave May   }
9337fbf63aeSDave May   PetscFunctionReturn(0);
93452849c42SDave May }
93552849c42SDave May 
9367fbf63aeSDave May #undef __FUNCT__
9377fbf63aeSDave May #define __FUNCT__ "DataBucketView_MPI"
9387fbf63aeSDave May PetscErrorCode DataBucketView_MPI(MPI_Comm comm,DataBucket db,const char filename[],DataBucketViewType type)
93952849c42SDave May {
940997fa542SDave May   PetscErrorCode ierr;
941997fa542SDave May 
942521f74f9SMatthew G. Knepley   PetscFunctionBegin;
94352849c42SDave May   switch (type) {
94452849c42SDave May   case DATABUCKET_VIEW_STDOUT:
94552849c42SDave May   {
9465c18a9d6SDave May     PetscInt f;
9475c18a9d6SDave May     PetscInt L,buffer,allocated;
94852849c42SDave May     double memory_usage_total,memory_usage_total_local = 0.0;
9495c18a9d6SDave May     PetscMPIInt rank;
95052849c42SDave May 
951997fa542SDave May     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
952dbe06d34SDave May     ierr = DataBucketGetGlobalSizes(comm,db,&L,&buffer,&allocated);CHKERRQ(ierr);
953521f74f9SMatthew G. Knepley     for (f = 0; f < db->nfields; ++f) {
95452849c42SDave May       double memory_usage_f = (double)(db->field[f]->atomic_size * db->allocated) * 1.0e-6;
95552849c42SDave May       memory_usage_total_local += memory_usage_f;
95652849c42SDave May     }
957dbe06d34SDave May     ierr = MPI_Allreduce(&memory_usage_total_local,&memory_usage_total,1,MPI_DOUBLE,MPI_SUM,comm);CHKERRQ(ierr);
958521f74f9SMatthew G. Knepley     ierr = PetscPrintf(comm,"DataBucketView(MPI): (\"%s\")\n",filename);CHKERRQ(ierr);
959521f74f9SMatthew G. Knepley     ierr = PetscPrintf(comm,"  L                  = %D \n", L);CHKERRQ(ierr);
960521f74f9SMatthew G. Knepley     ierr = PetscPrintf(comm,"  buffer (max)       = %D \n", buffer);CHKERRQ(ierr);
961521f74f9SMatthew G. Knepley     ierr = PetscPrintf(comm,"  allocated          = %D \n", allocated);CHKERRQ(ierr);
962521f74f9SMatthew G. Knepley     ierr = PetscPrintf(comm,"  nfields registered = %D \n", db->nfields);CHKERRQ(ierr);
96352849c42SDave May     for (f=0; f<db->nfields; f++) {
96452849c42SDave May       double memory_usage_f = (double)(db->field[f]->atomic_size * db->allocated) * 1.0e-6;
965521f74f9SMatthew G. Knepley       ierr = PetscPrintf(PETSC_COMM_SELF,"    [%3D]: field name  ==>> %30s : Mem. usage = %1.2e (MB) : rank0\n", f, db->field[f]->name, memory_usage_f);CHKERRQ(ierr);
96652849c42SDave May     }
967521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  Total mem. usage                                                      = %1.2e (MB) : collective\n", memory_usage_total);CHKERRQ(ierr);
96852849c42SDave May   }
96952849c42SDave May   break;
97052849c42SDave May   case DATABUCKET_VIEW_ASCII:
97152849c42SDave May   {
972a233d522SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot be implemented as we don't know the underlying data structure");
97352849c42SDave May   }
97452849c42SDave May   break;
97552849c42SDave May   case DATABUCKET_VIEW_BINARY:
97652849c42SDave May   {
977521f74f9SMatthew G. Knepley     char        name[PETSC_MAX_PATH_LEN];
9785c18a9d6SDave May     PetscMPIInt rank;
97952849c42SDave May 
98052849c42SDave May     /* create correct extension */
981997fa542SDave May     ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
982521f74f9SMatthew G. Knepley     ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "%s_p%1.5d", filename, rank);CHKERRQ(ierr);
983dbe06d34SDave May     ierr = _DataBucketViewBinary(db, name);CHKERRQ(ierr);
98452849c42SDave May   }
98552849c42SDave May   break;
98652849c42SDave May   case DATABUCKET_VIEW_HDF5:
98752849c42SDave May   {
988a233d522SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for HDF5");
98952849c42SDave May   }
99052849c42SDave May   break;
991521f74f9SMatthew G. Knepley   default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer method requested");
99252849c42SDave May   }
9937fbf63aeSDave May   PetscFunctionReturn(0);
99452849c42SDave May }
99552849c42SDave May 
9967fbf63aeSDave May #undef __FUNCT__
9977fbf63aeSDave May #define __FUNCT__ "DataBucketView"
9987fbf63aeSDave May PetscErrorCode DataBucketView(MPI_Comm comm,DataBucket db,const char filename[],DataBucketViewType type)
99952849c42SDave May {
10005c18a9d6SDave May   PetscMPIInt nproc;
1001997fa542SDave May   PetscErrorCode ierr;
100252849c42SDave May 
1003521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1004997fa542SDave May   ierr = MPI_Comm_size(comm,&nproc);CHKERRQ(ierr);
100552849c42SDave May   if (nproc == 1) {
1006dbe06d34SDave May     ierr = DataBucketView_SEQ(db,filename,type);CHKERRQ(ierr);
100752849c42SDave May   } else {
1008dbe06d34SDave May     ierr = DataBucketView_MPI(comm,db,filename,type);CHKERRQ(ierr);
100952849c42SDave May   }
10107fbf63aeSDave May   PetscFunctionReturn(0);
101152849c42SDave May }
101252849c42SDave May 
10137fbf63aeSDave May #undef __FUNCT__
10147fbf63aeSDave May #define __FUNCT__ "DataBucketDuplicateFields"
10157fbf63aeSDave May PetscErrorCode DataBucketDuplicateFields(DataBucket dbA,DataBucket *dbB)
101652849c42SDave May {
101752849c42SDave May   DataBucket db2;
10185c18a9d6SDave May   PetscInt f;
1019dbe06d34SDave May   PetscErrorCode ierr;
102052849c42SDave May 
1021521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1022dbe06d34SDave May   ierr = DataBucketCreate(&db2);CHKERRQ(ierr);
102352849c42SDave May   /* copy contents from dbA into db2 */
1024521f74f9SMatthew G. Knepley   for (f = 0; f < dbA->nfields; ++f) {
102552849c42SDave May     DataField field;
102652849c42SDave May     size_t    atomic_size;
102752849c42SDave May     char      *name;
102852849c42SDave May 
102952849c42SDave May     field = dbA->field[f];
103052849c42SDave May     atomic_size = field->atomic_size;
103152849c42SDave May     name        = field->name;
1032dbe06d34SDave May     ierr = DataBucketRegisterField(db2,"DataBucketDuplicateFields",name,atomic_size,NULL);CHKERRQ(ierr);
103352849c42SDave May   }
1034dbe06d34SDave May   ierr = DataBucketFinalize(db2);CHKERRQ(ierr);
1035dbe06d34SDave May   ierr = DataBucketSetInitialSizes(db2,0,1000);CHKERRQ(ierr);
103652849c42SDave May   *dbB = db2;
10377fbf63aeSDave May   PetscFunctionReturn(0);
103852849c42SDave May }
103952849c42SDave May 
104052849c42SDave May /*
104152849c42SDave May  Insert points from db2 into db1
104252849c42SDave May  db1 <<== db2
104352849c42SDave May  */
10447fbf63aeSDave May #undef __FUNCT__
10457fbf63aeSDave May #define __FUNCT__ "DataBucketInsertValues"
10467fbf63aeSDave May PetscErrorCode DataBucketInsertValues(DataBucket db1,DataBucket db2)
104752849c42SDave May {
10485c18a9d6SDave May   PetscInt n_mp_points1,n_mp_points2;
10495c18a9d6SDave May   PetscInt n_mp_points1_new,p;
1050dbe06d34SDave May   PetscErrorCode ierr;
105152849c42SDave May 
1052521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1053dbe06d34SDave May   ierr = DataBucketGetSizes(db1,&n_mp_points1,0,0);CHKERRQ(ierr);
1054dbe06d34SDave May   ierr = DataBucketGetSizes(db2,&n_mp_points2,0,0);CHKERRQ(ierr);
105552849c42SDave May   n_mp_points1_new = n_mp_points1 + n_mp_points2;
1056dbe06d34SDave May   ierr = DataBucketSetSizes(db1,n_mp_points1_new,-1);CHKERRQ(ierr);
1057521f74f9SMatthew G. Knepley   for (p = 0; p < n_mp_points2; ++p) {
1058521f74f9SMatthew G. Knepley     /* db1 <<== db2 */
1059dbe06d34SDave May     ierr = DataBucketCopyPoint(db2,p, db1,(n_mp_points1 + p));CHKERRQ(ierr);
106052849c42SDave May   }
10617fbf63aeSDave May   PetscFunctionReturn(0);
106252849c42SDave May }
106352849c42SDave May 
106452849c42SDave May /* helpers for parallel send/recv */
10657fbf63aeSDave May #undef __FUNCT__
10667fbf63aeSDave May #define __FUNCT__ "DataBucketCreatePackedArray"
10677fbf63aeSDave May PetscErrorCode DataBucketCreatePackedArray(DataBucket db,size_t *bytes,void **buf)
106852849c42SDave May {
10695c18a9d6SDave May   PetscInt       f;
107052849c42SDave May   size_t         sizeof_marker_contents;
107152849c42SDave May   void          *buffer;
1072521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
107352849c42SDave May 
1074521f74f9SMatthew G. Knepley   PetscFunctionBegin;
107552849c42SDave May   sizeof_marker_contents = 0;
1076521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
107752849c42SDave May     DataField df = db->field[f];
107852849c42SDave May     sizeof_marker_contents += df->atomic_size;
107952849c42SDave May   }
1080521f74f9SMatthew G. Knepley   ierr = PetscMalloc(sizeof_marker_contents, &buffer);CHKERRQ(ierr);
1081521f74f9SMatthew G. Knepley   ierr = PetscMemzero(buffer, sizeof_marker_contents);CHKERRQ(ierr);
108252849c42SDave May   if (bytes) {*bytes = sizeof_marker_contents;}
108352849c42SDave May   if (buf)   {*buf   = buffer;}
10847fbf63aeSDave May   PetscFunctionReturn(0);
108552849c42SDave May }
108652849c42SDave May 
10877fbf63aeSDave May #undef __FUNCT__
10887fbf63aeSDave May #define __FUNCT__ "DataBucketDestroyPackedArray"
10897fbf63aeSDave May PetscErrorCode DataBucketDestroyPackedArray(DataBucket db,void **buf)
109052849c42SDave May {
1091521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
1092521f74f9SMatthew G. Knepley 
1093521f74f9SMatthew G. Knepley   PetscFunctionBegin;
109452849c42SDave May   if (buf) {
1095521f74f9SMatthew G. Knepley     ierr = PetscFree(*buf);CHKERRQ(ierr);
109652849c42SDave May     *buf = NULL;
109752849c42SDave May   }
10987fbf63aeSDave May   PetscFunctionReturn(0);
109952849c42SDave May }
110052849c42SDave May 
11017fbf63aeSDave May #undef __FUNCT__
11027fbf63aeSDave May #define __FUNCT__ "DataBucketFillPackedArray"
11037fbf63aeSDave May PetscErrorCode DataBucketFillPackedArray(DataBucket db,const PetscInt index,void *buf)
110452849c42SDave May {
11055c18a9d6SDave May   PetscInt       f;
110652849c42SDave May   void          *data, *data_p;
110752849c42SDave May   size_t         asize, offset;
1108521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
110952849c42SDave May 
1110521f74f9SMatthew G. Knepley   PetscFunctionBegin;
111152849c42SDave May   offset = 0;
1112521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
111352849c42SDave May     DataField df = db->field[f];
111452849c42SDave May 
111552849c42SDave May     asize = df->atomic_size;
111652849c42SDave May     data = (void*)( df->data );
111752849c42SDave May     data_p = (void*)( (char*)data + index*asize );
1118521f74f9SMatthew G. Knepley     ierr = PetscMemcpy((void*)((char*)buf + offset), data_p, asize);CHKERRQ(ierr);
111952849c42SDave May     offset = offset + asize;
112052849c42SDave May   }
11217fbf63aeSDave May   PetscFunctionReturn(0);
112252849c42SDave May }
112352849c42SDave May 
11247fbf63aeSDave May #undef __FUNCT__
11257fbf63aeSDave May #define __FUNCT__ "DataBucketInsertPackedArray"
11267fbf63aeSDave May PetscErrorCode DataBucketInsertPackedArray(DataBucket db,const PetscInt idx,void *data)
112752849c42SDave May {
11285c18a9d6SDave May   PetscInt f;
112952849c42SDave May   void *data_p;
113052849c42SDave May   size_t offset;
1131dbe06d34SDave May   PetscErrorCode ierr;
113252849c42SDave May 
1133521f74f9SMatthew G. Knepley   PetscFunctionBegin;
113452849c42SDave May   offset = 0;
1135521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
113652849c42SDave May     DataField df = db->field[f];
113752849c42SDave May 
113852849c42SDave May     data_p = (void*)( (char*)data + offset );
1139dbe06d34SDave May     ierr = DataFieldInsertPoint(df, idx, (void*)data_p);CHKERRQ(ierr);
114052849c42SDave May     offset = offset + df->atomic_size;
114152849c42SDave May   }
11427fbf63aeSDave May   PetscFunctionReturn(0);
114352849c42SDave May }
1144