xref: /petsc/src/dm/impls/swarm/data_bucket.c (revision 071ce36955fadffe0b844446be2d7b35dd4d4a1f)
152849c42SDave May 
252849c42SDave May #include "data_bucket.h"
352849c42SDave May 
452849c42SDave May /* string helpers */
52eac95f8SDave May PetscErrorCode StringInList(const char name[],const PetscInt N,const DataField gfield[],PetscBool *val)
652849c42SDave May {
75c18a9d6SDave May   PetscInt       i;
8521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
952849c42SDave May 
10521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1152849c42SDave May   *val = PETSC_FALSE;
12521f74f9SMatthew G. Knepley   for (i = 0; i < N; ++i) {
13521f74f9SMatthew G. Knepley     PetscBool flg;
14521f74f9SMatthew G. Knepley     ierr = PetscStrcmp(name, gfield[i]->name, &flg);CHKERRQ(ierr);
15521f74f9SMatthew G. Knepley     if (flg) {
1652849c42SDave May       *val = PETSC_TRUE;
172eac95f8SDave May       PetscFunctionReturn(0);
1852849c42SDave May     }
1952849c42SDave May   }
202eac95f8SDave May   PetscFunctionReturn(0);
2152849c42SDave May }
2252849c42SDave May 
232eac95f8SDave May PetscErrorCode StringFindInList(const char name[],const PetscInt N,const DataField gfield[],PetscInt *index)
2452849c42SDave May {
255c18a9d6SDave May   PetscInt       i;
26521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
2752849c42SDave May 
28521f74f9SMatthew G. Knepley   PetscFunctionBegin;
2952849c42SDave May   *index = -1;
30521f74f9SMatthew G. Knepley   for (i = 0; i < N; ++i) {
31521f74f9SMatthew G. Knepley     PetscBool flg;
32521f74f9SMatthew G. Knepley     ierr = PetscStrcmp(name, gfield[i]->name, &flg);CHKERRQ(ierr);
33521f74f9SMatthew G. Knepley     if (flg) {
3452849c42SDave May       *index = i;
352eac95f8SDave May       PetscFunctionReturn(0);
3652849c42SDave May     }
3752849c42SDave May   }
382eac95f8SDave May   PetscFunctionReturn(0);
3952849c42SDave May }
4052849c42SDave May 
412eac95f8SDave May PetscErrorCode DataFieldCreate(const char registeration_function[],const char name[],const size_t size,const PetscInt L,DataField *DF)
4252849c42SDave May {
4352849c42SDave May   DataField      df;
44521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
4552849c42SDave May 
46521f74f9SMatthew G. Knepley   PetscFunctionBegin;
47521f74f9SMatthew G. Knepley   ierr = PetscMalloc(sizeof(struct _p_DataField), &df);CHKERRQ(ierr);
48521f74f9SMatthew G. Knepley   ierr = PetscMemzero(df, sizeof(struct _p_DataField));CHKERRQ(ierr);
49521f74f9SMatthew G. Knepley   ierr = PetscStrallocpy(registeration_function, &df->registeration_function);CHKERRQ(ierr);
50521f74f9SMatthew G. Knepley   ierr = PetscStrallocpy(name, &df->name);CHKERRQ(ierr);
5152849c42SDave May   df->atomic_size = size;
5252849c42SDave May   df->L  = L;
5352c3ed93SDave May   df->bs = 1;
54521f74f9SMatthew G. Knepley   /* allocate something so we don't have to reallocate */
55521f74f9SMatthew G. Knepley   ierr = PetscMalloc(size * L, &df->data);CHKERRQ(ierr);
56521f74f9SMatthew G. Knepley   ierr = PetscMemzero(df->data, size * L);CHKERRQ(ierr);
5752849c42SDave May   *DF = df;
582eac95f8SDave May   PetscFunctionReturn(0);
5952849c42SDave May }
6052849c42SDave May 
612eac95f8SDave May PetscErrorCode DataFieldDestroy(DataField *DF)
6252849c42SDave May {
6352849c42SDave May   DataField      df = *DF;
64521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
6552849c42SDave May 
66521f74f9SMatthew G. Knepley   PetscFunctionBegin;
67521f74f9SMatthew G. Knepley   ierr = PetscFree(df->registeration_function);CHKERRQ(ierr);
68521f74f9SMatthew G. Knepley   ierr = PetscFree(df->name);CHKERRQ(ierr);
69521f74f9SMatthew G. Knepley   ierr = PetscFree(df->data);CHKERRQ(ierr);
70521f74f9SMatthew G. Knepley   ierr = PetscFree(df);CHKERRQ(ierr);
7152849c42SDave May   *DF  = NULL;
722eac95f8SDave May   PetscFunctionReturn(0);
7352849c42SDave May }
7452849c42SDave May 
7552849c42SDave May /* data bucket */
762eac95f8SDave May PetscErrorCode DataBucketCreate(DataBucket *DB)
7752849c42SDave May {
7852849c42SDave May   DataBucket     db;
79521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
8052849c42SDave May 
81521f74f9SMatthew G. Knepley   PetscFunctionBegin;
82521f74f9SMatthew G. Knepley   ierr = PetscMalloc(sizeof(struct _p_DataBucket), &db);CHKERRQ(ierr);
83521f74f9SMatthew G. Knepley   ierr = PetscMemzero(db, sizeof(struct _p_DataBucket));CHKERRQ(ierr);
8452849c42SDave May 
8552849c42SDave May   db->finalised = PETSC_FALSE;
8652849c42SDave May   /* create empty spaces for fields */
873454631fSDave May   db->L         = -1;
8852849c42SDave May   db->buffer    = 1;
8952849c42SDave May   db->allocated = 1;
9052849c42SDave May   db->nfields   = 0;
91521f74f9SMatthew G. Knepley   ierr = PetscMalloc1(1, &db->field);CHKERRQ(ierr);
9252849c42SDave May   *DB  = db;
932eac95f8SDave May   PetscFunctionReturn(0);
9452849c42SDave May }
9552849c42SDave May 
962eac95f8SDave May PetscErrorCode DataBucketDestroy(DataBucket *DB)
9752849c42SDave May {
9852849c42SDave May   DataBucket     db = *DB;
995c18a9d6SDave May   PetscInt       f;
100dbe06d34SDave May   PetscErrorCode ierr;
10152849c42SDave May 
102521f74f9SMatthew G. Knepley   PetscFunctionBegin;
10352849c42SDave May   /* release fields */
104521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
105dbe06d34SDave May     ierr = DataFieldDestroy(&db->field[f]);CHKERRQ(ierr);
10652849c42SDave May   }
10752849c42SDave May   /* this will catch the initially allocated objects in the event that no fields are registered */
10852849c42SDave May   if (db->field != NULL) {
109521f74f9SMatthew G. Knepley     ierr = PetscFree(db->field);CHKERRQ(ierr);
11052849c42SDave May   }
111521f74f9SMatthew G. Knepley   ierr = PetscFree(db);CHKERRQ(ierr);
11252849c42SDave May   *DB = NULL;
1132eac95f8SDave May   PetscFunctionReturn(0);
11452849c42SDave May }
11552849c42SDave May 
1160cb17e37SDave May PetscErrorCode DataBucketQueryForActiveFields(DataBucket db,PetscBool *any_active_fields)
1170cb17e37SDave May {
1180cb17e37SDave May   PetscInt f;
119521f74f9SMatthew G. Knepley 
120521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1210cb17e37SDave May   *any_active_fields = PETSC_FALSE;
122521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
1230cb17e37SDave May     if (db->field[f]->active) {
1240cb17e37SDave May       *any_active_fields = PETSC_TRUE;
1250cb17e37SDave May       PetscFunctionReturn(0);
1260cb17e37SDave May     }
1270cb17e37SDave May   }
1280cb17e37SDave May   PetscFunctionReturn(0);
1290cb17e37SDave May }
1300cb17e37SDave May 
1312eac95f8SDave May PetscErrorCode DataBucketRegisterField(
13252849c42SDave May                               DataBucket db,
13352849c42SDave May                               const char registeration_function[],
13452849c42SDave May                               const char field_name[],
13552849c42SDave May                               size_t atomic_size, DataField *_gfield)
13652849c42SDave May {
13752849c42SDave May   PetscBool val;
1384be7464cSMatthew G. Knepley   DataField fp;
139dbe06d34SDave May   PetscErrorCode ierr;
14052849c42SDave May 
141521f74f9SMatthew G. Knepley   PetscFunctionBegin;
14252849c42SDave May 	/* check we haven't finalised the registration of fields */
14352849c42SDave May 	/*
14452849c42SDave May    if(db->finalised==PETSC_TRUE) {
14552849c42SDave May    printf("ERROR: DataBucketFinalize() has been called. Cannot register more fields\n");
14652849c42SDave May    ERROR();
14752849c42SDave May    }
14852849c42SDave May    */
14952849c42SDave May   /* check for repeated name */
1502635f519SDave May   ierr = StringInList(field_name, db->nfields, (const DataField*) db->field, &val);CHKERRQ(ierr);
1512eac95f8SDave May   if (val == PETSC_TRUE) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field %s already exists. Cannot add same field twice",field_name);
15252849c42SDave May   /* create new space for data */
1534be7464cSMatthew G. Knepley   ierr = PetscRealloc(sizeof(DataField)*(db->nfields+1), &db->field);CHKERRQ(ierr);
15452849c42SDave May   /* add field */
155dbe06d34SDave May   ierr = DataFieldCreate(registeration_function, field_name, atomic_size, db->allocated, &fp);CHKERRQ(ierr);
15652849c42SDave May   db->field[db->nfields] = fp;
15752849c42SDave May   db->nfields++;
15852849c42SDave May   if (_gfield != NULL) {
15952849c42SDave May     *_gfield = fp;
16052849c42SDave May   }
1612eac95f8SDave May   PetscFunctionReturn(0);
16252849c42SDave May }
16352849c42SDave May 
16452849c42SDave May /*
16552849c42SDave May  #define DataBucketRegisterField(db,name,size,k) {\
16652849c42SDave May  char *location;\
16752849c42SDave May  asprintf(&location,"Registered by %s() at line %d within file %s", __FUNCTION__, __LINE__, __FILE__);\
16852849c42SDave May  _DataBucketRegisterField( (db), location, (name), (size), (k) );\
169521f74f9SMatthew G. Knepley  ierr = PetscFree(location);\
17052849c42SDave May  }
17152849c42SDave May  */
17252849c42SDave May 
1732eac95f8SDave May PetscErrorCode DataBucketGetDataFieldByName(DataBucket db,const char name[],DataField *gfield)
17452849c42SDave May {
1755c18a9d6SDave May   PetscInt       idx;
17652849c42SDave May   PetscBool      found;
177521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
17852849c42SDave May 
179521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1802635f519SDave May   ierr = StringInList(name,db->nfields,(const DataField*)db->field,&found);CHKERRQ(ierr);
1812eac95f8SDave May   if (!found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot find DataField with name %s",name);
1822635f519SDave May   ierr = StringFindInList(name,db->nfields,(const DataField*)db->field,&idx);CHKERRQ(ierr);
18352849c42SDave May   *gfield = db->field[idx];
1842eac95f8SDave May   PetscFunctionReturn(0);
18552849c42SDave May }
18652849c42SDave May 
1877fbf63aeSDave May PetscErrorCode DataBucketQueryDataFieldByName(DataBucket db,const char name[],PetscBool *found)
18852849c42SDave May {
1892635f519SDave May   PetscErrorCode ierr;
190521f74f9SMatthew G. Knepley 
191521f74f9SMatthew G. Knepley   PetscFunctionBegin;
19252849c42SDave May   *found = PETSC_FALSE;
1932635f519SDave May   ierr = StringInList(name,db->nfields,(const DataField*)db->field,found);CHKERRQ(ierr);
1947fbf63aeSDave May   PetscFunctionReturn(0);
19552849c42SDave May }
19652849c42SDave May 
1977fbf63aeSDave May PetscErrorCode DataBucketFinalize(DataBucket db)
19852849c42SDave May {
199521f74f9SMatthew G. Knepley   PetscFunctionBegin;
20052849c42SDave May   db->finalised = PETSC_TRUE;
2017fbf63aeSDave May   PetscFunctionReturn(0);
20252849c42SDave May }
20352849c42SDave May 
2047fbf63aeSDave May PetscErrorCode DataFieldGetNumEntries(DataField df,PetscInt *sum)
20552849c42SDave May {
206521f74f9SMatthew G. Knepley   PetscFunctionBegin;
20752849c42SDave May   *sum = df->L;
2087fbf63aeSDave May   PetscFunctionReturn(0);
20952849c42SDave May }
21052849c42SDave May 
21152c3ed93SDave May PetscErrorCode DataFieldSetBlockSize(DataField df,PetscInt blocksize)
21252c3ed93SDave May {
213521f74f9SMatthew G. Knepley   PetscFunctionBegin;
21452c3ed93SDave May   df->bs = blocksize;
21552c3ed93SDave May   PetscFunctionReturn(0);
21652c3ed93SDave May }
21752c3ed93SDave May 
2187fbf63aeSDave May PetscErrorCode DataFieldSetSize(DataField df,const PetscInt new_L)
21952849c42SDave May {
220521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
22152849c42SDave May 
222521f74f9SMatthew G. Knepley   PetscFunctionBegin;
223a233d522SDave May   if (new_L <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot set size of DataField to be <= 0");
2247fbf63aeSDave May   if (new_L == df->L) PetscFunctionReturn(0);
22552849c42SDave May   if (new_L > df->L) {
2264be7464cSMatthew G. Knepley     ierr = PetscRealloc(df->atomic_size * (new_L), &df->data);CHKERRQ(ierr);
22752849c42SDave May     /* init new contents */
228521f74f9SMatthew G. Knepley     ierr = PetscMemzero(( ((char*)df->data)+df->L*df->atomic_size), (new_L-df->L)*df->atomic_size);CHKERRQ(ierr);
2297fbf63aeSDave May   } else {
23052849c42SDave May     /* reallocate pointer list, add +1 in case new_L = 0 */
2314be7464cSMatthew G. Knepley     ierr = PetscRealloc(df->atomic_size * (new_L+1), &df->data);CHKERRQ(ierr);
23252849c42SDave May   }
23352849c42SDave May   df->L = new_L;
2347fbf63aeSDave May   PetscFunctionReturn(0);
23552849c42SDave May }
23652849c42SDave May 
2377fbf63aeSDave May PetscErrorCode DataFieldZeroBlock(DataField df,const PetscInt start,const PetscInt end)
23852849c42SDave May {
239521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
240521f74f9SMatthew G. Knepley 
241521f74f9SMatthew G. Knepley   PetscFunctionBegin;
2427fbf63aeSDave May   if (start > end) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot zero a block of entries if start(%D) > end(%D)",start,end);
2437fbf63aeSDave May   if (start < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot zero a block of entries if start(%D) < 0",start);
244a233d522SDave 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);
245521f74f9SMatthew G. Knepley   ierr = PetscMemzero((((char*)df->data)+start*df->atomic_size), (end-start)*df->atomic_size);CHKERRQ(ierr);
2467fbf63aeSDave May   PetscFunctionReturn(0);
24752849c42SDave May }
24852849c42SDave May 
24952849c42SDave May /*
25052849c42SDave May  A negative buffer value will simply be ignored and the old buffer value will be used.
25152849c42SDave May  */
2527fbf63aeSDave May PetscErrorCode DataBucketSetSizes(DataBucket db,const PetscInt L,const PetscInt buffer)
25352849c42SDave May {
2545c18a9d6SDave May   PetscInt       current_allocated,new_used,new_unused,new_buffer,new_allocated,f;
2550cb17e37SDave May   PetscBool      any_active_fields;
256dbe06d34SDave May   PetscErrorCode ierr;
25752849c42SDave May 
258521f74f9SMatthew G. Knepley   PetscFunctionBegin;
2597fbf63aeSDave May   if (db->finalised == PETSC_FALSE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"You must call DataBucketFinalize() before DataBucketSetSizes()");
2600cb17e37SDave May   ierr = DataBucketQueryForActiveFields(db,&any_active_fields);CHKERRQ(ierr);
2610cb17e37SDave 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");
2620cb17e37SDave May 
26352849c42SDave May   current_allocated = db->allocated;
26452849c42SDave May   new_used   = L;
26552849c42SDave May   new_unused = current_allocated - new_used;
26652849c42SDave May   new_buffer = db->buffer;
26752849c42SDave May   if (buffer >= 0) { /* update the buffer value */
26852849c42SDave May     new_buffer = buffer;
26952849c42SDave May   }
27052849c42SDave May   new_allocated = new_used + new_buffer;
27152849c42SDave May   /* action */
27252849c42SDave May   if (new_allocated > current_allocated) {
27352849c42SDave May     /* increase size to new_used + new_buffer */
27452849c42SDave May     for (f=0; f<db->nfields; f++) {
275dbe06d34SDave May       ierr = DataFieldSetSize(db->field[f], new_allocated);CHKERRQ(ierr);
27652849c42SDave May     }
27752849c42SDave May     db->L         = new_used;
27852849c42SDave May     db->buffer    = new_buffer;
27952849c42SDave May     db->allocated = new_used + new_buffer;
280521f74f9SMatthew G. Knepley   } else {
28152849c42SDave May     if (new_unused > 2 * new_buffer) {
28252849c42SDave May       /* shrink array to new_used + new_buffer */
283521f74f9SMatthew G. Knepley       for (f = 0; f < db->nfields; ++f) {
284dbe06d34SDave May         ierr = DataFieldSetSize(db->field[f], new_allocated);CHKERRQ(ierr);
28552849c42SDave May       }
28652849c42SDave May       db->L         = new_used;
28752849c42SDave May       db->buffer    = new_buffer;
28852849c42SDave May       db->allocated = new_used + new_buffer;
289521f74f9SMatthew G. Knepley     } else {
29052849c42SDave May       db->L      = new_used;
29152849c42SDave May       db->buffer = new_buffer;
29252849c42SDave May     }
29352849c42SDave May   }
29452849c42SDave May   /* zero all entries from db->L to db->allocated */
295521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
29652849c42SDave May     DataField field = db->field[f];
297dbe06d34SDave May     ierr = DataFieldZeroBlock(field, db->L,db->allocated);CHKERRQ(ierr);
29852849c42SDave May   }
2997fbf63aeSDave May   PetscFunctionReturn(0);
30052849c42SDave May }
30152849c42SDave May 
3027fbf63aeSDave May PetscErrorCode DataBucketSetInitialSizes(DataBucket db,const PetscInt L,const PetscInt buffer)
30352849c42SDave May {
3045c18a9d6SDave May   PetscInt       f;
305dbe06d34SDave May   PetscErrorCode ierr;
306dbe06d34SDave May 
307521f74f9SMatthew G. Knepley   PetscFunctionBegin;
308dbe06d34SDave May   ierr = DataBucketSetSizes(db,L,buffer);CHKERRQ(ierr);
309521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
31052849c42SDave May     DataField field = db->field[f];
311dbe06d34SDave May     ierr = DataFieldZeroBlock(field,0,db->allocated);CHKERRQ(ierr);
31252849c42SDave May   }
3137fbf63aeSDave May   PetscFunctionReturn(0);
31452849c42SDave May }
31552849c42SDave May 
3167fbf63aeSDave May PetscErrorCode DataBucketGetSizes(DataBucket db,PetscInt *L,PetscInt *buffer,PetscInt *allocated)
31752849c42SDave May {
318521f74f9SMatthew G. Knepley   PetscFunctionBegin;
31952849c42SDave May   if (L) {*L = db->L;}
32052849c42SDave May   if (buffer) {*buffer = db->buffer;}
32152849c42SDave May   if (allocated) {*allocated = db->allocated;}
3227fbf63aeSDave May   PetscFunctionReturn(0);
32352849c42SDave May }
32452849c42SDave May 
3257fbf63aeSDave May PetscErrorCode DataBucketGetGlobalSizes(MPI_Comm comm,DataBucket db,PetscInt *L,PetscInt *buffer,PetscInt *allocated)
32652849c42SDave May {
3275c18a9d6SDave May   PetscInt _L,_buffer,_allocated;
3285c18a9d6SDave May   PetscInt ierr;
32952849c42SDave May 
330521f74f9SMatthew G. Knepley   PetscFunctionBegin;
3315c18a9d6SDave May   _L = db->L;
3325c18a9d6SDave May   _buffer = db->buffer;
3335c18a9d6SDave May   _allocated = db->allocated;
33452849c42SDave May 
33533564166SDave May   if (L) {         ierr = MPI_Allreduce(&_L,L,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); }
33633564166SDave May   if (buffer) {    ierr = MPI_Allreduce(&_buffer,buffer,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); }
33733564166SDave May   if (allocated) { ierr = MPI_Allreduce(&_allocated,allocated,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); }
3387fbf63aeSDave May   PetscFunctionReturn(0);
33952849c42SDave May }
34052849c42SDave May 
3417fbf63aeSDave May PetscErrorCode DataBucketGetDataFields(DataBucket db,PetscInt *L,DataField *fields[])
34252849c42SDave May {
343521f74f9SMatthew G. Knepley   PetscFunctionBegin;
34452849c42SDave May   if (L)      {*L      = db->nfields;}
34552849c42SDave May   if (fields) {*fields = db->field;}
3467fbf63aeSDave May   PetscFunctionReturn(0);
34752849c42SDave May }
34852849c42SDave May 
3497fbf63aeSDave May PetscErrorCode DataFieldGetAccess(const DataField gfield)
35052849c42SDave May {
351521f74f9SMatthew G. Knepley   PetscFunctionBegin;
3527fbf63aeSDave May   if (gfield->active) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is already active. You must call DataFieldRestoreAccess()",gfield->name);
35352849c42SDave May   gfield->active = PETSC_TRUE;
3547fbf63aeSDave May   PetscFunctionReturn(0);
35552849c42SDave May }
35652849c42SDave May 
3577fbf63aeSDave May PetscErrorCode DataFieldAccessPoint(const DataField gfield,const PetscInt pid,void **ctx_p)
35852849c42SDave May {
359521f74f9SMatthew G. Knepley   PetscFunctionBegin;
36072505a4dSJed Brown   *ctx_p = NULL;
36152849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
36252849c42SDave May   /* debug mode */
36384bcda08SDave May   /* check point is valid */
3647fbf63aeSDave May   if (pid < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
3657fbf63aeSDave May   if (pid >= gfield->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",gfield->L);
36684bcda08SDave 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);
36752849c42SDave May #endif
36852849c42SDave May   *ctx_p = __DATATFIELD_point_access(gfield->data,pid,gfield->atomic_size);
3697fbf63aeSDave May   PetscFunctionReturn(0);
37052849c42SDave May }
37152849c42SDave May 
3727fbf63aeSDave May PetscErrorCode DataFieldAccessPointOffset(const DataField gfield,const size_t offset,const PetscInt pid,void **ctx_p)
37352849c42SDave May {
374521f74f9SMatthew G. Knepley   PetscFunctionBegin;
37552849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
37652849c42SDave May   /* debug mode */
37784bcda08SDave May   /* check point is valid */
378521f74f9SMatthew G. Knepley   /* if( offset < 0 ) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"offset must be >= 0");*/
379521f74f9SMatthew G. Knepley   /* Note compiler realizes this can never happen with an unsigned PetscInt */
3807fbf63aeSDave May   if (offset >= gfield->atomic_size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"offset must be < %zu",gfield->atomic_size);
38184bcda08SDave May   /* check point is valid */
3827fbf63aeSDave May   if (pid < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
383a233d522SDave May   if (pid >= gfield->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",gfield->L);
384a233d522SDave 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);
38552849c42SDave May #endif
38652849c42SDave May   *ctx_p = __DATATFIELD_point_access_offset(gfield->data,pid,gfield->atomic_size,offset);
3877fbf63aeSDave May   PetscFunctionReturn(0);
38852849c42SDave May }
38952849c42SDave May 
3907fbf63aeSDave May PetscErrorCode DataFieldRestoreAccess(DataField gfield)
39152849c42SDave May {
392521f74f9SMatthew G. Knepley   PetscFunctionBegin;
3937fbf63aeSDave May   if (gfield->active == PETSC_FALSE) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is not active. You must call DataFieldGetAccess()", gfield->name);
39452849c42SDave May   gfield->active = PETSC_FALSE;
3957fbf63aeSDave May   PetscFunctionReturn(0);
39652849c42SDave May }
39752849c42SDave May 
3987fbf63aeSDave May PetscErrorCode DataFieldVerifyAccess(const DataField gfield,const size_t size)
39952849c42SDave May {
400521f74f9SMatthew G. Knepley   PetscFunctionBegin;
40152849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
402521f74f9SMatthew 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 );
40352849c42SDave May #endif
4047fbf63aeSDave May   PetscFunctionReturn(0);
40552849c42SDave May }
40652849c42SDave May 
4077fbf63aeSDave May PetscErrorCode DataFieldGetAtomicSize(const DataField gfield,size_t *size)
40852849c42SDave May {
409521f74f9SMatthew G. Knepley   PetscFunctionBegin;
41052849c42SDave May   if (size) {*size = gfield->atomic_size;}
4117fbf63aeSDave May   PetscFunctionReturn(0);
41252849c42SDave May }
41352849c42SDave May 
4147fbf63aeSDave May PetscErrorCode DataFieldGetEntries(const DataField gfield,void **data)
41552849c42SDave May {
416521f74f9SMatthew G. Knepley   PetscFunctionBegin;
417521f74f9SMatthew G. Knepley   if (data) {*data = gfield->data;}
4187fbf63aeSDave May   PetscFunctionReturn(0);
41952849c42SDave May }
42052849c42SDave May 
4217fbf63aeSDave May PetscErrorCode DataFieldRestoreEntries(const DataField gfield,void **data)
42252849c42SDave May {
423521f74f9SMatthew G. Knepley   PetscFunctionBegin;
424521f74f9SMatthew G. Knepley   if (data) {*data = NULL;}
4257fbf63aeSDave May   PetscFunctionReturn(0);
42652849c42SDave May }
42752849c42SDave May 
42852849c42SDave May /* y = x */
4297fbf63aeSDave May PetscErrorCode DataBucketCopyPoint(const DataBucket xb,const PetscInt pid_x,
4305c18a9d6SDave May                          const DataBucket yb,const PetscInt pid_y)
43152849c42SDave May {
4325c18a9d6SDave May   PetscInt f;
433dbe06d34SDave May   PetscErrorCode ierr;
434dbe06d34SDave May 
435521f74f9SMatthew G. Knepley   PetscFunctionBegin;
436521f74f9SMatthew G. Knepley   for (f = 0; f < xb->nfields; ++f) {
43752849c42SDave May     void *dest;
43852849c42SDave May     void *src;
43952849c42SDave May 
440dbe06d34SDave May     ierr = DataFieldGetAccess(xb->field[f]);CHKERRQ(ierr);
4416845f8f5SDave May     if (xb != yb) { ierr = DataFieldGetAccess( yb->field[f]);CHKERRQ(ierr); }
442dbe06d34SDave May     ierr = DataFieldAccessPoint(xb->field[f],pid_x, &src);CHKERRQ(ierr);
443dbe06d34SDave May     ierr = DataFieldAccessPoint(yb->field[f],pid_y, &dest);CHKERRQ(ierr);
444521f74f9SMatthew G. Knepley     ierr = PetscMemcpy(dest, src, xb->field[f]->atomic_size);CHKERRQ(ierr);
445dbe06d34SDave May     ierr = DataFieldRestoreAccess(xb->field[f]);CHKERRQ(ierr);
4466845f8f5SDave May     if (xb != yb) {ierr = DataFieldRestoreAccess(yb->field[f]);CHKERRQ(ierr);}
44752849c42SDave May   }
4487fbf63aeSDave May   PetscFunctionReturn(0);
44952849c42SDave May }
45052849c42SDave May 
4517fbf63aeSDave May PetscErrorCode DataBucketCreateFromSubset(DataBucket DBIn,const PetscInt N,const PetscInt list[],DataBucket *DB)
45252849c42SDave May {
4535c18a9d6SDave May   PetscInt nfields;
45452849c42SDave May   DataField *fields;
4555c18a9d6SDave May   PetscInt f,L,buffer,allocated,p;
456dbe06d34SDave May   PetscErrorCode ierr;
45752849c42SDave May 
458521f74f9SMatthew G. Knepley   PetscFunctionBegin;
459521f74f9SMatthew G. Knepley   ierr = DataBucketCreate(DB);CHKERRQ(ierr);
46052849c42SDave May   /* copy contents of DBIn */
461dbe06d34SDave May   ierr = DataBucketGetDataFields(DBIn,&nfields,&fields);CHKERRQ(ierr);
462dbe06d34SDave May   ierr = DataBucketGetSizes(DBIn,&L,&buffer,&allocated);CHKERRQ(ierr);
463521f74f9SMatthew G. Knepley   for (f = 0; f < nfields; ++f) {
464dbe06d34SDave May     ierr = DataBucketRegisterField(*DB,"DataBucketCreateFromSubset",fields[f]->name,fields[f]->atomic_size,NULL);CHKERRQ(ierr);
46552849c42SDave May   }
466dbe06d34SDave May   ierr = DataBucketFinalize(*DB);CHKERRQ(ierr);
467dbe06d34SDave May   ierr = DataBucketSetSizes(*DB,L,buffer);CHKERRQ(ierr);
46852849c42SDave May   /* now copy the desired guys from DBIn => DB */
469521f74f9SMatthew G. Knepley   for (p = 0; p < N; ++p) {
470dbe06d34SDave May     ierr = DataBucketCopyPoint(DBIn,list[p], *DB,p);CHKERRQ(ierr);
47152849c42SDave May   }
4727fbf63aeSDave May   PetscFunctionReturn(0);
47352849c42SDave May }
47452849c42SDave May 
475521f74f9SMatthew G. Knepley /* insert into an exisitng location */
4767fbf63aeSDave May PetscErrorCode DataFieldInsertPoint(const DataField field,const PetscInt index,const void *ctx)
47752849c42SDave May {
478521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
47952849c42SDave May 
480521f74f9SMatthew G. Knepley   PetscFunctionBegin;
48152849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
48284bcda08SDave May   /* check point is valid */
483a233d522SDave May   if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
484a233d522SDave May   if (index >= field->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",field->L);
48552849c42SDave May #endif
486521f74f9SMatthew G. Knepley   ierr = PetscMemcpy(__DATATFIELD_point_access(field->data,index,field->atomic_size), ctx, field->atomic_size);CHKERRQ(ierr);
4877fbf63aeSDave May   PetscFunctionReturn(0);
48852849c42SDave May }
48952849c42SDave May 
490521f74f9SMatthew G. Knepley /* remove data at index - replace with last point */
4917fbf63aeSDave May PetscErrorCode DataBucketRemovePointAtIndex(const DataBucket db,const PetscInt index)
49252849c42SDave May {
4935c18a9d6SDave May   PetscInt       f;
4940cb17e37SDave May   PetscBool      any_active_fields;
495dbe06d34SDave May   PetscErrorCode ierr;
49652849c42SDave May 
497521f74f9SMatthew G. Knepley   PetscFunctionBegin;
49852849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
49984bcda08SDave May   /* check point is valid */
500a233d522SDave May   if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
501a233d522SDave May   if (index >= db->allocated) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",db->L+db->buffer);
50252849c42SDave May #endif
5030cb17e37SDave May   ierr = DataBucketQueryForActiveFields(db,&any_active_fields);CHKERRQ(ierr);
5040cb17e37SDave 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");
505a233d522SDave May   if (index >= db->L) { /* this point is not in the list - no need to error, but I will anyway */
506a233d522SDave 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);
50752849c42SDave May   }
508a233d522SDave May   if (index != db->L-1) { /* not last point in list */
509521f74f9SMatthew G. Knepley     for (f = 0; f < db->nfields; ++f) {
51052849c42SDave May       DataField field = db->field[f];
51152849c42SDave May 
51252849c42SDave May       /* copy then remove */
513dbe06d34SDave May       ierr = DataFieldCopyPoint(db->L-1, field, index, field);CHKERRQ(ierr);
514521f74f9SMatthew G. Knepley       /* DataFieldZeroPoint(field,index); */
51552849c42SDave May     }
51652849c42SDave May   }
51752849c42SDave May   /* decrement size */
51852849c42SDave May   /* this will zero out an crap at the end of the list */
519dbe06d34SDave May   ierr = DataBucketRemovePoint(db);CHKERRQ(ierr);
5207fbf63aeSDave May   PetscFunctionReturn(0);
52152849c42SDave May }
52252849c42SDave May 
52352849c42SDave May /* copy x into y */
5247fbf63aeSDave May PetscErrorCode DataFieldCopyPoint(const PetscInt pid_x,const DataField field_x,
5255c18a9d6SDave May                         const PetscInt pid_y,const DataField field_y )
52652849c42SDave May {
527521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
52852849c42SDave May 
529521f74f9SMatthew G. Knepley   PetscFunctionBegin;
53052849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
53184bcda08SDave May   /* check point is valid */
532a233d522SDave May   if (pid_x < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"(IN) index must be >= 0");
533a233d522SDave May   if (pid_x >= field_x->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"(IN) index must be < %D",field_x->L);
534a233d522SDave May   if (pid_y < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"(OUT) index must be >= 0");
535a233d522SDave May   if (pid_y >= field_y->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"(OUT) index must be < %D",field_y->L);
536521f74f9SMatthew G. Knepley   if( field_y->atomic_size != field_x->atomic_size ) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"atomic size must match");
53752849c42SDave May #endif
538521f74f9SMatthew G. Knepley   ierr = PetscMemcpy(__DATATFIELD_point_access(field_y->data,pid_y,field_y->atomic_size),
53952849c42SDave May                      __DATATFIELD_point_access(field_x->data,pid_x,field_x->atomic_size),
540521f74f9SMatthew G. Knepley                      field_y->atomic_size);CHKERRQ(ierr);
5417fbf63aeSDave May   PetscFunctionReturn(0);
54252849c42SDave May }
54352849c42SDave May 
54452849c42SDave May 
545521f74f9SMatthew G. Knepley /* zero only the datafield at this point */
5467fbf63aeSDave May PetscErrorCode DataFieldZeroPoint(const DataField field,const PetscInt index)
54752849c42SDave May {
548521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
549521f74f9SMatthew G. Knepley 
550521f74f9SMatthew G. Knepley   PetscFunctionBegin;
55152849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
55284bcda08SDave May   /* check point is valid */
553a233d522SDave May   if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
554a233d522SDave May   if (index >= field->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",field->L);
55552849c42SDave May #endif
556521f74f9SMatthew G. Knepley   ierr = PetscMemzero(__DATATFIELD_point_access(field->data,index,field->atomic_size), field->atomic_size);CHKERRQ(ierr);
5577fbf63aeSDave May   PetscFunctionReturn(0);
55852849c42SDave May }
55952849c42SDave May 
560521f74f9SMatthew G. Knepley /* zero ALL data for this point */
5617fbf63aeSDave May PetscErrorCode DataBucketZeroPoint(const DataBucket db,const PetscInt index)
56252849c42SDave May {
5635c18a9d6SDave May   PetscInt f;
564dbe06d34SDave May   PetscErrorCode ierr;
56552849c42SDave May 
566521f74f9SMatthew G. Knepley   PetscFunctionBegin;
56784bcda08SDave May   /* check point is valid */
568a233d522SDave May   if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
569a233d522SDave May   if (index >= db->allocated) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",db->allocated);
570521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
57152849c42SDave May     DataField field = db->field[f];
572dbe06d34SDave May     ierr = DataFieldZeroPoint(field,index);CHKERRQ(ierr);
57352849c42SDave May   }
5747fbf63aeSDave May   PetscFunctionReturn(0);
57552849c42SDave May }
57652849c42SDave May 
57752849c42SDave May /* increment */
5787fbf63aeSDave May PetscErrorCode DataBucketAddPoint(DataBucket db)
57952849c42SDave May {
580dbe06d34SDave May   PetscErrorCode ierr;
581dbe06d34SDave May 
582521f74f9SMatthew G. Knepley   PetscFunctionBegin;
583dbe06d34SDave May   ierr = DataBucketSetSizes(db,db->L+1,-1);CHKERRQ(ierr);
5847fbf63aeSDave May   PetscFunctionReturn(0);
58552849c42SDave May }
58652849c42SDave May 
5877fbf63aeSDave May /* decrement */
5887fbf63aeSDave May PetscErrorCode DataBucketRemovePoint(DataBucket db)
5897fbf63aeSDave May {
590dbe06d34SDave May   PetscErrorCode ierr;
591dbe06d34SDave May 
592521f74f9SMatthew G. Knepley   PetscFunctionBegin;
593dbe06d34SDave May   ierr = DataBucketSetSizes(db,db->L-1,-1);CHKERRQ(ierr);
5947fbf63aeSDave May   PetscFunctionReturn(0);
5957fbf63aeSDave May }
5967fbf63aeSDave May 
5977fbf63aeSDave May PetscErrorCode DataBucketView_SEQ(DataBucket db,const char filename[],DataBucketViewType type)
59852849c42SDave May {
599dbe06d34SDave May   PetscErrorCode ierr;
600dbe06d34SDave May 
601521f74f9SMatthew G. Knepley   PetscFunctionBegin;
60252849c42SDave May   switch (type) {
60352849c42SDave May   case DATABUCKET_VIEW_STDOUT:
60452849c42SDave May   {
6055c18a9d6SDave May     PetscInt f;
60652849c42SDave May     double memory_usage_total = 0.0;
60752849c42SDave May 
608521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"DataBucketView(SEQ): (\"%s\")\n",filename);CHKERRQ(ierr);
609521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  L                  = %D \n", db->L);CHKERRQ(ierr);
610521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  buffer             = %D \n", db->buffer);CHKERRQ(ierr);
611521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  allocated          = %D \n", db->allocated);CHKERRQ(ierr);
612521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  nfields registered = %D \n", db->nfields);CHKERRQ(ierr);
613521f74f9SMatthew G. Knepley     for (f = 0; f < db->nfields; ++f) {
61452849c42SDave May       double memory_usage_f = (double)(db->field[f]->atomic_size * db->allocated) * 1.0e-6;
615521f74f9SMatthew 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);
616521f74f9SMatthew G. Knepley       ierr = PetscPrintf(PETSC_COMM_SELF,"           blocksize          = %D \n", db->field[f]->bs);CHKERRQ(ierr);
61752c3ed93SDave May       if (db->field[f]->bs != 1) {
618521f74f9SMatthew 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);
619521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PETSC_COMM_SELF,"           atomic size/item   = %zu \n", db->field[f]->atomic_size/db->field[f]->bs);CHKERRQ(ierr);
62052c3ed93SDave May       } else {
621521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PETSC_COMM_SELF,"           atomic size        = %zu \n", db->field[f]->atomic_size);CHKERRQ(ierr);
62252c3ed93SDave May       }
62352849c42SDave May       memory_usage_total += memory_usage_f;
62452849c42SDave May     }
625521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  Total mem. usage                                                      = %1.2e (MB) \n", memory_usage_total);CHKERRQ(ierr);
62652849c42SDave May   }
62752849c42SDave May   break;
62852849c42SDave May   case DATABUCKET_VIEW_ASCII:
629*071ce369SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for ascii output");
63052849c42SDave May     break;
63152849c42SDave May   case DATABUCKET_VIEW_BINARY:
632*071ce369SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for binary output");
63352849c42SDave May     break;
63452849c42SDave May   case DATABUCKET_VIEW_HDF5:
635*071ce369SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for HDF5 output");
63652849c42SDave May     break;
637521f74f9SMatthew G. Knepley   default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer method requested");
63852849c42SDave May   }
6397fbf63aeSDave May   PetscFunctionReturn(0);
64052849c42SDave May }
64152849c42SDave May 
6427fbf63aeSDave May PetscErrorCode DataBucketView_MPI(MPI_Comm comm,DataBucket db,const char filename[],DataBucketViewType type)
64352849c42SDave May {
644997fa542SDave May   PetscErrorCode ierr;
645997fa542SDave May 
646521f74f9SMatthew G. Knepley   PetscFunctionBegin;
64752849c42SDave May   switch (type) {
64852849c42SDave May   case DATABUCKET_VIEW_STDOUT:
64952849c42SDave May   {
6505c18a9d6SDave May     PetscInt f;
6515c18a9d6SDave May     PetscInt L,buffer,allocated;
65252849c42SDave May     double memory_usage_total,memory_usage_total_local = 0.0;
6535c18a9d6SDave May     PetscMPIInt rank;
65452849c42SDave May 
655997fa542SDave May     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
656dbe06d34SDave May     ierr = DataBucketGetGlobalSizes(comm,db,&L,&buffer,&allocated);CHKERRQ(ierr);
657521f74f9SMatthew G. Knepley     for (f = 0; f < db->nfields; ++f) {
65852849c42SDave May       double memory_usage_f = (double)(db->field[f]->atomic_size * db->allocated) * 1.0e-6;
65952849c42SDave May       memory_usage_total_local += memory_usage_f;
66052849c42SDave May     }
661dbe06d34SDave May     ierr = MPI_Allreduce(&memory_usage_total_local,&memory_usage_total,1,MPI_DOUBLE,MPI_SUM,comm);CHKERRQ(ierr);
662521f74f9SMatthew G. Knepley     ierr = PetscPrintf(comm,"DataBucketView(MPI): (\"%s\")\n",filename);CHKERRQ(ierr);
663521f74f9SMatthew G. Knepley     ierr = PetscPrintf(comm,"  L                  = %D \n", L);CHKERRQ(ierr);
664521f74f9SMatthew G. Knepley     ierr = PetscPrintf(comm,"  buffer (max)       = %D \n", buffer);CHKERRQ(ierr);
665521f74f9SMatthew G. Knepley     ierr = PetscPrintf(comm,"  allocated          = %D \n", allocated);CHKERRQ(ierr);
666521f74f9SMatthew G. Knepley     ierr = PetscPrintf(comm,"  nfields registered = %D \n", db->nfields);CHKERRQ(ierr);
66752849c42SDave May     for (f=0; f<db->nfields; f++) {
66852849c42SDave May       double memory_usage_f = (double)(db->field[f]->atomic_size * db->allocated) * 1.0e-6;
669521f74f9SMatthew 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);
67052849c42SDave May     }
671521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  Total mem. usage                                                      = %1.2e (MB) : collective\n", memory_usage_total);CHKERRQ(ierr);
67252849c42SDave May   }
67352849c42SDave May   break;
67452849c42SDave May   case DATABUCKET_VIEW_ASCII:
675*071ce369SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for ascii output");
67652849c42SDave May   break;
67752849c42SDave May   case DATABUCKET_VIEW_BINARY:
678*071ce369SDave May       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for binary output");
67952849c42SDave May   break;
68052849c42SDave May   case DATABUCKET_VIEW_HDF5:
681*071ce369SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for HDF5 output");
68252849c42SDave May   break;
683521f74f9SMatthew G. Knepley   default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer method requested");
68452849c42SDave May   }
6857fbf63aeSDave May   PetscFunctionReturn(0);
68652849c42SDave May }
68752849c42SDave May 
6887fbf63aeSDave May PetscErrorCode DataBucketView(MPI_Comm comm,DataBucket db,const char filename[],DataBucketViewType type)
68952849c42SDave May {
6905c18a9d6SDave May   PetscMPIInt nproc;
691997fa542SDave May   PetscErrorCode ierr;
69252849c42SDave May 
693521f74f9SMatthew G. Knepley   PetscFunctionBegin;
694997fa542SDave May   ierr = MPI_Comm_size(comm,&nproc);CHKERRQ(ierr);
69552849c42SDave May   if (nproc == 1) {
696dbe06d34SDave May     ierr = DataBucketView_SEQ(db,filename,type);CHKERRQ(ierr);
69752849c42SDave May   } else {
698dbe06d34SDave May     ierr = DataBucketView_MPI(comm,db,filename,type);CHKERRQ(ierr);
69952849c42SDave May   }
7007fbf63aeSDave May   PetscFunctionReturn(0);
70152849c42SDave May }
70252849c42SDave May 
7037fbf63aeSDave May PetscErrorCode DataBucketDuplicateFields(DataBucket dbA,DataBucket *dbB)
70452849c42SDave May {
70552849c42SDave May   DataBucket db2;
7065c18a9d6SDave May   PetscInt f;
707dbe06d34SDave May   PetscErrorCode ierr;
70852849c42SDave May 
709521f74f9SMatthew G. Knepley   PetscFunctionBegin;
710dbe06d34SDave May   ierr = DataBucketCreate(&db2);CHKERRQ(ierr);
71152849c42SDave May   /* copy contents from dbA into db2 */
712521f74f9SMatthew G. Knepley   for (f = 0; f < dbA->nfields; ++f) {
71352849c42SDave May     DataField field;
71452849c42SDave May     size_t    atomic_size;
71552849c42SDave May     char      *name;
71652849c42SDave May 
71752849c42SDave May     field = dbA->field[f];
71852849c42SDave May     atomic_size = field->atomic_size;
71952849c42SDave May     name        = field->name;
720dbe06d34SDave May     ierr = DataBucketRegisterField(db2,"DataBucketDuplicateFields",name,atomic_size,NULL);CHKERRQ(ierr);
72152849c42SDave May   }
722dbe06d34SDave May   ierr = DataBucketFinalize(db2);CHKERRQ(ierr);
723dbe06d34SDave May   ierr = DataBucketSetInitialSizes(db2,0,1000);CHKERRQ(ierr);
72452849c42SDave May   *dbB = db2;
7257fbf63aeSDave May   PetscFunctionReturn(0);
72652849c42SDave May }
72752849c42SDave May 
72852849c42SDave May /*
72952849c42SDave May  Insert points from db2 into db1
73052849c42SDave May  db1 <<== db2
73152849c42SDave May  */
7327fbf63aeSDave May PetscErrorCode DataBucketInsertValues(DataBucket db1,DataBucket db2)
73352849c42SDave May {
7345c18a9d6SDave May   PetscInt n_mp_points1,n_mp_points2;
7355c18a9d6SDave May   PetscInt n_mp_points1_new,p;
736dbe06d34SDave May   PetscErrorCode ierr;
73752849c42SDave May 
738521f74f9SMatthew G. Knepley   PetscFunctionBegin;
739dbe06d34SDave May   ierr = DataBucketGetSizes(db1,&n_mp_points1,0,0);CHKERRQ(ierr);
740dbe06d34SDave May   ierr = DataBucketGetSizes(db2,&n_mp_points2,0,0);CHKERRQ(ierr);
74152849c42SDave May   n_mp_points1_new = n_mp_points1 + n_mp_points2;
742dbe06d34SDave May   ierr = DataBucketSetSizes(db1,n_mp_points1_new,-1);CHKERRQ(ierr);
743521f74f9SMatthew G. Knepley   for (p = 0; p < n_mp_points2; ++p) {
744521f74f9SMatthew G. Knepley     /* db1 <<== db2 */
745dbe06d34SDave May     ierr = DataBucketCopyPoint(db2,p, db1,(n_mp_points1 + p));CHKERRQ(ierr);
74652849c42SDave May   }
7477fbf63aeSDave May   PetscFunctionReturn(0);
74852849c42SDave May }
74952849c42SDave May 
75052849c42SDave May /* helpers for parallel send/recv */
7517fbf63aeSDave May PetscErrorCode DataBucketCreatePackedArray(DataBucket db,size_t *bytes,void **buf)
75252849c42SDave May {
7535c18a9d6SDave May   PetscInt       f;
75452849c42SDave May   size_t         sizeof_marker_contents;
75552849c42SDave May   void          *buffer;
756521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
75752849c42SDave May 
758521f74f9SMatthew G. Knepley   PetscFunctionBegin;
75952849c42SDave May   sizeof_marker_contents = 0;
760521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
76152849c42SDave May     DataField df = db->field[f];
76252849c42SDave May     sizeof_marker_contents += df->atomic_size;
76352849c42SDave May   }
764521f74f9SMatthew G. Knepley   ierr = PetscMalloc(sizeof_marker_contents, &buffer);CHKERRQ(ierr);
765521f74f9SMatthew G. Knepley   ierr = PetscMemzero(buffer, sizeof_marker_contents);CHKERRQ(ierr);
76652849c42SDave May   if (bytes) {*bytes = sizeof_marker_contents;}
76752849c42SDave May   if (buf)   {*buf   = buffer;}
7687fbf63aeSDave May   PetscFunctionReturn(0);
76952849c42SDave May }
77052849c42SDave May 
7717fbf63aeSDave May PetscErrorCode DataBucketDestroyPackedArray(DataBucket db,void **buf)
77252849c42SDave May {
773521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
774521f74f9SMatthew G. Knepley 
775521f74f9SMatthew G. Knepley   PetscFunctionBegin;
77652849c42SDave May   if (buf) {
777521f74f9SMatthew G. Knepley     ierr = PetscFree(*buf);CHKERRQ(ierr);
77852849c42SDave May     *buf = NULL;
77952849c42SDave May   }
7807fbf63aeSDave May   PetscFunctionReturn(0);
78152849c42SDave May }
78252849c42SDave May 
7837fbf63aeSDave May PetscErrorCode DataBucketFillPackedArray(DataBucket db,const PetscInt index,void *buf)
78452849c42SDave May {
7855c18a9d6SDave May   PetscInt       f;
78652849c42SDave May   void          *data, *data_p;
78752849c42SDave May   size_t         asize, offset;
788521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
78952849c42SDave May 
790521f74f9SMatthew G. Knepley   PetscFunctionBegin;
79152849c42SDave May   offset = 0;
792521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
79352849c42SDave May     DataField df = db->field[f];
79452849c42SDave May 
79552849c42SDave May     asize = df->atomic_size;
79652849c42SDave May     data = (void*)( df->data );
79752849c42SDave May     data_p = (void*)( (char*)data + index*asize );
798521f74f9SMatthew G. Knepley     ierr = PetscMemcpy((void*)((char*)buf + offset), data_p, asize);CHKERRQ(ierr);
79952849c42SDave May     offset = offset + asize;
80052849c42SDave May   }
8017fbf63aeSDave May   PetscFunctionReturn(0);
80252849c42SDave May }
80352849c42SDave May 
8047fbf63aeSDave May PetscErrorCode DataBucketInsertPackedArray(DataBucket db,const PetscInt idx,void *data)
80552849c42SDave May {
8065c18a9d6SDave May   PetscInt f;
80752849c42SDave May   void *data_p;
80852849c42SDave May   size_t offset;
809dbe06d34SDave May   PetscErrorCode ierr;
81052849c42SDave May 
811521f74f9SMatthew G. Knepley   PetscFunctionBegin;
81252849c42SDave May   offset = 0;
813521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
81452849c42SDave May     DataField df = db->field[f];
81552849c42SDave May 
81652849c42SDave May     data_p = (void*)( (char*)data + offset );
817dbe06d34SDave May     ierr = DataFieldInsertPoint(df, idx, (void*)data_p);CHKERRQ(ierr);
81852849c42SDave May     offset = offset + df->atomic_size;
81952849c42SDave May   }
8207fbf63aeSDave May   PetscFunctionReturn(0);
82152849c42SDave May }
822