xref: /petsc/src/dm/impls/swarm/data_bucket.c (revision fc2c8c6ab10fa0cecf029e6ef74b247b4e841624)
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;
15452849c42SDave May   DataField *field,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 */
169521f74f9SMatthew G. Knepley   field = (DataField *) realloc(db->field, sizeof(DataField)*(db->nfields+1));
17052849c42SDave May   db->field = field;
17152849c42SDave May   /* add field */
172dbe06d34SDave May   ierr = DataFieldCreate(registeration_function, field_name, atomic_size, db->allocated, &fp);CHKERRQ(ierr);
17352849c42SDave May   db->field[db->nfields] = fp;
17452849c42SDave May   db->nfields++;
17552849c42SDave May   if (_gfield != NULL) {
17652849c42SDave May     *_gfield = fp;
17752849c42SDave May   }
1782eac95f8SDave May   PetscFunctionReturn(0);
17952849c42SDave May }
18052849c42SDave May 
18152849c42SDave May /*
18252849c42SDave May  #define DataBucketRegisterField(db,name,size,k) {\
18352849c42SDave May  char *location;\
18452849c42SDave May  asprintf(&location,"Registered by %s() at line %d within file %s", __FUNCTION__, __LINE__, __FILE__);\
18552849c42SDave May  _DataBucketRegisterField( (db), location, (name), (size), (k) );\
186521f74f9SMatthew G. Knepley  ierr = PetscFree(location);\
18752849c42SDave May  }
18852849c42SDave May  */
18952849c42SDave May 
1902eac95f8SDave May #undef __FUNCT__
1912eac95f8SDave May #define __FUNCT__ "DataBucketGetDataFieldByName"
1922eac95f8SDave May PetscErrorCode DataBucketGetDataFieldByName(DataBucket db,const char name[],DataField *gfield)
19352849c42SDave May {
1945c18a9d6SDave May   PetscInt       idx;
19552849c42SDave May   PetscBool      found;
196521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
19752849c42SDave May 
198521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1992635f519SDave May   ierr = StringInList(name,db->nfields,(const DataField*)db->field,&found);CHKERRQ(ierr);
2002eac95f8SDave May   if (!found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot find DataField with name %s",name);
2012635f519SDave May   ierr = StringFindInList(name,db->nfields,(const DataField*)db->field,&idx);CHKERRQ(ierr);
20252849c42SDave May   *gfield = db->field[idx];
2032eac95f8SDave May   PetscFunctionReturn(0);
20452849c42SDave May }
20552849c42SDave May 
2067fbf63aeSDave May #undef __FUNCT__
2077fbf63aeSDave May #define __FUNCT__ "DataBucketQueryDataFieldByName"
2087fbf63aeSDave May PetscErrorCode DataBucketQueryDataFieldByName(DataBucket db,const char name[],PetscBool *found)
20952849c42SDave May {
2102635f519SDave May   PetscErrorCode ierr;
211521f74f9SMatthew G. Knepley 
212521f74f9SMatthew G. Knepley   PetscFunctionBegin;
21352849c42SDave May   *found = PETSC_FALSE;
2142635f519SDave May   ierr = StringInList(name,db->nfields,(const DataField*)db->field,found);CHKERRQ(ierr);
2157fbf63aeSDave May   PetscFunctionReturn(0);
21652849c42SDave May }
21752849c42SDave May 
2187fbf63aeSDave May #undef __FUNCT__
2197fbf63aeSDave May #define __FUNCT__ "DataBucketFinalize"
2207fbf63aeSDave May PetscErrorCode DataBucketFinalize(DataBucket db)
22152849c42SDave May {
222521f74f9SMatthew G. Knepley   PetscFunctionBegin;
22352849c42SDave May   db->finalised = PETSC_TRUE;
2247fbf63aeSDave May   PetscFunctionReturn(0);
22552849c42SDave May }
22652849c42SDave May 
2277fbf63aeSDave May #undef __FUNCT__
2287fbf63aeSDave May #define __FUNCT__ "DataFieldGetNumEntries"
2297fbf63aeSDave May PetscErrorCode DataFieldGetNumEntries(DataField df,PetscInt *sum)
23052849c42SDave May {
231521f74f9SMatthew G. Knepley   PetscFunctionBegin;
23252849c42SDave May   *sum = df->L;
2337fbf63aeSDave May   PetscFunctionReturn(0);
23452849c42SDave May }
23552849c42SDave May 
2367fbf63aeSDave May #undef __FUNCT__
23752c3ed93SDave May #define __FUNCT__ "DataFieldSetBlockSize"
23852c3ed93SDave May PetscErrorCode DataFieldSetBlockSize(DataField df,PetscInt blocksize)
23952c3ed93SDave May {
240521f74f9SMatthew G. Knepley   PetscFunctionBegin;
24152c3ed93SDave May   df->bs = blocksize;
24252c3ed93SDave May   PetscFunctionReturn(0);
24352c3ed93SDave May }
24452c3ed93SDave May 
24552c3ed93SDave May #undef __FUNCT__
2467fbf63aeSDave May #define __FUNCT__ "DataFieldSetSize"
2477fbf63aeSDave May PetscErrorCode DataFieldSetSize(DataField df,const PetscInt new_L)
24852849c42SDave May {
24952849c42SDave May   void          *tmp_data;
250521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
25152849c42SDave May 
252521f74f9SMatthew G. Knepley   PetscFunctionBegin;
253a233d522SDave May   if (new_L <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot set size of DataField to be <= 0");
2547fbf63aeSDave May   if (new_L == df->L) PetscFunctionReturn(0);
25552849c42SDave May   if (new_L > df->L) {
25652849c42SDave May     tmp_data = realloc( df->data, df->atomic_size * (new_L) );
25752849c42SDave May     df->data = tmp_data;
25852849c42SDave May     /* init new contents */
259521f74f9SMatthew G. Knepley     ierr = PetscMemzero(( ((char*)df->data)+df->L*df->atomic_size), (new_L-df->L)*df->atomic_size);CHKERRQ(ierr);
2607fbf63aeSDave May   } else {
26152849c42SDave May     /* reallocate pointer list, add +1 in case new_L = 0 */
26252849c42SDave May     tmp_data = realloc( df->data, df->atomic_size * (new_L+1) );
26352849c42SDave May     df->data = tmp_data;
26452849c42SDave May   }
26552849c42SDave May   df->L = new_L;
2667fbf63aeSDave May   PetscFunctionReturn(0);
26752849c42SDave May }
26852849c42SDave May 
2697fbf63aeSDave May #undef __FUNCT__
2707fbf63aeSDave May #define __FUNCT__ "DataFieldZeroBlock"
2717fbf63aeSDave May PetscErrorCode DataFieldZeroBlock(DataField df,const PetscInt start,const PetscInt end)
27252849c42SDave May {
273521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
274521f74f9SMatthew G. Knepley 
275521f74f9SMatthew G. Knepley   PetscFunctionBegin;
2767fbf63aeSDave May   if (start > end) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot zero a block of entries if start(%D) > end(%D)",start,end);
2777fbf63aeSDave May   if (start < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot zero a block of entries if start(%D) < 0",start);
278a233d522SDave 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);
279521f74f9SMatthew G. Knepley   ierr = PetscMemzero((((char*)df->data)+start*df->atomic_size), (end-start)*df->atomic_size);CHKERRQ(ierr);
2807fbf63aeSDave May   PetscFunctionReturn(0);
28152849c42SDave May }
28252849c42SDave May 
28352849c42SDave May /*
28452849c42SDave May  A negative buffer value will simply be ignored and the old buffer value will be used.
28552849c42SDave May  */
2867fbf63aeSDave May #undef __FUNCT__
2877fbf63aeSDave May #define __FUNCT__ "DataBucketSetSizes"
2887fbf63aeSDave May PetscErrorCode DataBucketSetSizes(DataBucket db,const PetscInt L,const PetscInt buffer)
28952849c42SDave May {
2905c18a9d6SDave May   PetscInt       current_allocated,new_used,new_unused,new_buffer,new_allocated,f;
2910cb17e37SDave May   PetscBool      any_active_fields;
292dbe06d34SDave May   PetscErrorCode ierr;
29352849c42SDave May 
294521f74f9SMatthew G. Knepley   PetscFunctionBegin;
2957fbf63aeSDave May   if (db->finalised == PETSC_FALSE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"You must call DataBucketFinalize() before DataBucketSetSizes()");
2960cb17e37SDave May   ierr = DataBucketQueryForActiveFields(db,&any_active_fields);CHKERRQ(ierr);
2970cb17e37SDave 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");
2980cb17e37SDave May 
29952849c42SDave May   current_allocated = db->allocated;
30052849c42SDave May   new_used   = L;
30152849c42SDave May   new_unused = current_allocated - new_used;
30252849c42SDave May   new_buffer = db->buffer;
30352849c42SDave May   if (buffer >= 0) { /* update the buffer value */
30452849c42SDave May     new_buffer = buffer;
30552849c42SDave May   }
30652849c42SDave May   new_allocated = new_used + new_buffer;
30752849c42SDave May   /* action */
30852849c42SDave May   if (new_allocated > current_allocated) {
30952849c42SDave May     /* increase size to new_used + new_buffer */
31052849c42SDave May     for (f=0; f<db->nfields; f++) {
311dbe06d34SDave May       ierr = DataFieldSetSize(db->field[f], new_allocated);CHKERRQ(ierr);
31252849c42SDave May     }
31352849c42SDave May     db->L         = new_used;
31452849c42SDave May     db->buffer    = new_buffer;
31552849c42SDave May     db->allocated = new_used + new_buffer;
316521f74f9SMatthew G. Knepley   } else {
31752849c42SDave May     if (new_unused > 2 * new_buffer) {
31852849c42SDave May       /* shrink array to new_used + new_buffer */
319521f74f9SMatthew G. Knepley       for (f = 0; f < db->nfields; ++f) {
320dbe06d34SDave May         ierr = DataFieldSetSize(db->field[f], new_allocated);CHKERRQ(ierr);
32152849c42SDave May       }
32252849c42SDave May       db->L         = new_used;
32352849c42SDave May       db->buffer    = new_buffer;
32452849c42SDave May       db->allocated = new_used + new_buffer;
325521f74f9SMatthew G. Knepley     } else {
32652849c42SDave May       db->L      = new_used;
32752849c42SDave May       db->buffer = new_buffer;
32852849c42SDave May     }
32952849c42SDave May   }
33052849c42SDave May   /* zero all entries from db->L to db->allocated */
331521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
33252849c42SDave May     DataField field = db->field[f];
333dbe06d34SDave May     ierr = DataFieldZeroBlock(field, db->L,db->allocated);CHKERRQ(ierr);
33452849c42SDave May   }
3357fbf63aeSDave May   PetscFunctionReturn(0);
33652849c42SDave May }
33752849c42SDave May 
3387fbf63aeSDave May #undef __FUNCT__
3397fbf63aeSDave May #define __FUNCT__ "DataBucketSetInitialSizes"
3407fbf63aeSDave May PetscErrorCode DataBucketSetInitialSizes(DataBucket db,const PetscInt L,const PetscInt buffer)
34152849c42SDave May {
3425c18a9d6SDave May   PetscInt       f;
343dbe06d34SDave May   PetscErrorCode ierr;
344dbe06d34SDave May 
345521f74f9SMatthew G. Knepley   PetscFunctionBegin;
346dbe06d34SDave May   ierr = DataBucketSetSizes(db,L,buffer);CHKERRQ(ierr);
347521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
34852849c42SDave May     DataField field = db->field[f];
349dbe06d34SDave May     ierr = DataFieldZeroBlock(field,0,db->allocated);CHKERRQ(ierr);
35052849c42SDave May   }
3517fbf63aeSDave May   PetscFunctionReturn(0);
35252849c42SDave May }
35352849c42SDave May 
3547fbf63aeSDave May #undef __FUNCT__
3557fbf63aeSDave May #define __FUNCT__ "DataBucketGetSizes"
3567fbf63aeSDave May PetscErrorCode DataBucketGetSizes(DataBucket db,PetscInt *L,PetscInt *buffer,PetscInt *allocated)
35752849c42SDave May {
358521f74f9SMatthew G. Knepley   PetscFunctionBegin;
35952849c42SDave May   if (L) {*L = db->L;}
36052849c42SDave May   if (buffer) {*buffer = db->buffer;}
36152849c42SDave May   if (allocated) {*allocated = db->allocated;}
3627fbf63aeSDave May   PetscFunctionReturn(0);
36352849c42SDave May }
36452849c42SDave May 
3657fbf63aeSDave May #undef __FUNCT__
3667fbf63aeSDave May #define __FUNCT__ "DataBucketGetGlobalSizes"
3677fbf63aeSDave May PetscErrorCode DataBucketGetGlobalSizes(MPI_Comm comm,DataBucket db,PetscInt *L,PetscInt *buffer,PetscInt *allocated)
36852849c42SDave May {
3695c18a9d6SDave May   PetscInt _L,_buffer,_allocated;
3705c18a9d6SDave May   PetscInt ierr;
37152849c42SDave May 
372521f74f9SMatthew G. Knepley   PetscFunctionBegin;
3735c18a9d6SDave May   _L = db->L;
3745c18a9d6SDave May   _buffer = db->buffer;
3755c18a9d6SDave May   _allocated = db->allocated;
37652849c42SDave May 
37733564166SDave May   if (L) {         ierr = MPI_Allreduce(&_L,L,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); }
37833564166SDave May   if (buffer) {    ierr = MPI_Allreduce(&_buffer,buffer,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); }
37933564166SDave May   if (allocated) { ierr = MPI_Allreduce(&_allocated,allocated,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); }
3807fbf63aeSDave May   PetscFunctionReturn(0);
38152849c42SDave May }
38252849c42SDave May 
3837fbf63aeSDave May #undef __FUNCT__
38489884300SDave May #define __FUNCT__ "DataBucketGetDataFields"
3857fbf63aeSDave May PetscErrorCode DataBucketGetDataFields(DataBucket db,PetscInt *L,DataField *fields[])
38652849c42SDave May {
387521f74f9SMatthew G. Knepley   PetscFunctionBegin;
38852849c42SDave May   if (L)      {*L      = db->nfields;}
38952849c42SDave May   if (fields) {*fields = db->field;}
3907fbf63aeSDave May   PetscFunctionReturn(0);
39152849c42SDave May }
39252849c42SDave May 
3937fbf63aeSDave May #undef __FUNCT__
3947fbf63aeSDave May #define __FUNCT__ "DataFieldGetAccess"
3957fbf63aeSDave May PetscErrorCode DataFieldGetAccess(const DataField gfield)
39652849c42SDave May {
397521f74f9SMatthew G. Knepley   PetscFunctionBegin;
3987fbf63aeSDave May   if (gfield->active) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is already active. You must call DataFieldRestoreAccess()",gfield->name);
39952849c42SDave May   gfield->active = PETSC_TRUE;
4007fbf63aeSDave May   PetscFunctionReturn(0);
40152849c42SDave May }
40252849c42SDave May 
4037fbf63aeSDave May #undef __FUNCT__
4047fbf63aeSDave May #define __FUNCT__ "DataFieldAccessPoint"
4057fbf63aeSDave May PetscErrorCode DataFieldAccessPoint(const DataField gfield,const PetscInt pid,void **ctx_p)
40652849c42SDave May {
407521f74f9SMatthew G. Knepley   PetscFunctionBegin;
40852849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
40952849c42SDave May   /* debug mode */
41084bcda08SDave May   /* check point is valid */
4117fbf63aeSDave May   if (pid < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
4127fbf63aeSDave May   if (pid >= gfield->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",gfield->L);
41384bcda08SDave 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);
41452849c42SDave May #endif
41552849c42SDave May   *ctx_p = __DATATFIELD_point_access(gfield->data,pid,gfield->atomic_size);
4167fbf63aeSDave May   PetscFunctionReturn(0);
41752849c42SDave May }
41852849c42SDave May 
4197fbf63aeSDave May #undef __FUNCT__
4207fbf63aeSDave May #define __FUNCT__ "DataFieldAccessPointOffset"
4217fbf63aeSDave May PetscErrorCode DataFieldAccessPointOffset(const DataField gfield,const size_t offset,const PetscInt pid,void **ctx_p)
42252849c42SDave May {
423521f74f9SMatthew G. Knepley   PetscFunctionBegin;
42452849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
42552849c42SDave May   /* debug mode */
42684bcda08SDave May   /* check point is valid */
427521f74f9SMatthew G. Knepley   /* if( offset < 0 ) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"offset must be >= 0");*/
428521f74f9SMatthew G. Knepley   /* Note compiler realizes this can never happen with an unsigned PetscInt */
4297fbf63aeSDave May   if (offset >= gfield->atomic_size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"offset must be < %zu",gfield->atomic_size);
43084bcda08SDave May   /* check point is valid */
4317fbf63aeSDave May   if (pid < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
432a233d522SDave May   if (pid >= gfield->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",gfield->L);
433a233d522SDave 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);
43452849c42SDave May #endif
43552849c42SDave May   *ctx_p = __DATATFIELD_point_access_offset(gfield->data,pid,gfield->atomic_size,offset);
4367fbf63aeSDave May   PetscFunctionReturn(0);
43752849c42SDave May }
43852849c42SDave May 
4397fbf63aeSDave May #undef __FUNCT__
44089884300SDave May #define __FUNCT__ "DataFieldRestoreAccess"
4417fbf63aeSDave May PetscErrorCode DataFieldRestoreAccess(DataField gfield)
44252849c42SDave May {
443521f74f9SMatthew G. Knepley   PetscFunctionBegin;
4447fbf63aeSDave May   if (gfield->active == PETSC_FALSE) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is not active. You must call DataFieldGetAccess()", gfield->name);
44552849c42SDave May   gfield->active = PETSC_FALSE;
4467fbf63aeSDave May   PetscFunctionReturn(0);
44752849c42SDave May }
44852849c42SDave May 
4497fbf63aeSDave May #undef __FUNCT__
4507fbf63aeSDave May #define __FUNCT__ "DataFieldVerifyAccess"
4517fbf63aeSDave May PetscErrorCode DataFieldVerifyAccess(const DataField gfield,const size_t size)
45252849c42SDave May {
453521f74f9SMatthew G. Knepley   PetscFunctionBegin;
45452849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
455521f74f9SMatthew 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 );
45652849c42SDave May #endif
4577fbf63aeSDave May   PetscFunctionReturn(0);
45852849c42SDave May }
45952849c42SDave May 
4607fbf63aeSDave May #undef __FUNCT__
4617fbf63aeSDave May #define __FUNCT__ "DataFieldGetAtomicSize"
4627fbf63aeSDave May PetscErrorCode DataFieldGetAtomicSize(const DataField gfield,size_t *size)
46352849c42SDave May {
464521f74f9SMatthew G. Knepley   PetscFunctionBegin;
46552849c42SDave May   if (size) {*size = gfield->atomic_size;}
4667fbf63aeSDave May   PetscFunctionReturn(0);
46752849c42SDave May }
46852849c42SDave May 
4697fbf63aeSDave May #undef __FUNCT__
4707fbf63aeSDave May #define __FUNCT__ "DataFieldGetEntries"
4717fbf63aeSDave May PetscErrorCode DataFieldGetEntries(const DataField gfield,void **data)
47252849c42SDave May {
473521f74f9SMatthew G. Knepley   PetscFunctionBegin;
474521f74f9SMatthew G. Knepley   if (data) {*data = gfield->data;}
4757fbf63aeSDave May   PetscFunctionReturn(0);
47652849c42SDave May }
47752849c42SDave May 
4787fbf63aeSDave May #undef __FUNCT__
4797fbf63aeSDave May #define __FUNCT__ "DataFieldRestoreEntries"
4807fbf63aeSDave May PetscErrorCode DataFieldRestoreEntries(const DataField gfield,void **data)
48152849c42SDave May {
482521f74f9SMatthew G. Knepley   PetscFunctionBegin;
483521f74f9SMatthew G. Knepley   if (data) {*data = NULL;}
4847fbf63aeSDave May   PetscFunctionReturn(0);
48552849c42SDave May }
48652849c42SDave May 
48752849c42SDave May /* y = x */
4887fbf63aeSDave May #undef __FUNCT__
4897fbf63aeSDave May #define __FUNCT__ "DataBucketCopyPoint"
4907fbf63aeSDave May PetscErrorCode DataBucketCopyPoint(const DataBucket xb,const PetscInt pid_x,
4915c18a9d6SDave May                          const DataBucket yb,const PetscInt pid_y)
49252849c42SDave May {
4935c18a9d6SDave May   PetscInt f;
494dbe06d34SDave May   PetscErrorCode ierr;
495dbe06d34SDave May 
496521f74f9SMatthew G. Knepley   PetscFunctionBegin;
497521f74f9SMatthew G. Knepley   for (f = 0; f < xb->nfields; ++f) {
49852849c42SDave May     void *dest;
49952849c42SDave May     void *src;
50052849c42SDave May 
501dbe06d34SDave May     ierr = DataFieldGetAccess(xb->field[f]);CHKERRQ(ierr);
5026845f8f5SDave May     if (xb != yb) { ierr = DataFieldGetAccess( yb->field[f]);CHKERRQ(ierr); }
503dbe06d34SDave May     ierr = DataFieldAccessPoint(xb->field[f],pid_x, &src);CHKERRQ(ierr);
504dbe06d34SDave May     ierr = DataFieldAccessPoint(yb->field[f],pid_y, &dest);CHKERRQ(ierr);
505521f74f9SMatthew G. Knepley     ierr = PetscMemcpy(dest, src, xb->field[f]->atomic_size);CHKERRQ(ierr);
506dbe06d34SDave May     ierr = DataFieldRestoreAccess(xb->field[f]);CHKERRQ(ierr);
5076845f8f5SDave May     if (xb != yb) {ierr = DataFieldRestoreAccess(yb->field[f]);CHKERRQ(ierr);}
50852849c42SDave May   }
5097fbf63aeSDave May   PetscFunctionReturn(0);
51052849c42SDave May }
51152849c42SDave May 
5127fbf63aeSDave May #undef __FUNCT__
5137fbf63aeSDave May #define __FUNCT__ "DataBucketCreateFromSubset"
5147fbf63aeSDave May PetscErrorCode DataBucketCreateFromSubset(DataBucket DBIn,const PetscInt N,const PetscInt list[],DataBucket *DB)
51552849c42SDave May {
5165c18a9d6SDave May   PetscInt nfields;
51752849c42SDave May   DataField *fields;
5185c18a9d6SDave May   PetscInt f,L,buffer,allocated,p;
519dbe06d34SDave May   PetscErrorCode ierr;
52052849c42SDave May 
521521f74f9SMatthew G. Knepley   PetscFunctionBegin;
522521f74f9SMatthew G. Knepley   ierr = DataBucketCreate(DB);CHKERRQ(ierr);
52352849c42SDave May   /* copy contents of DBIn */
524dbe06d34SDave May   ierr = DataBucketGetDataFields(DBIn,&nfields,&fields);CHKERRQ(ierr);
525dbe06d34SDave May   ierr = DataBucketGetSizes(DBIn,&L,&buffer,&allocated);CHKERRQ(ierr);
526521f74f9SMatthew G. Knepley   for (f = 0; f < nfields; ++f) {
527dbe06d34SDave May     ierr = DataBucketRegisterField(*DB,"DataBucketCreateFromSubset",fields[f]->name,fields[f]->atomic_size,NULL);CHKERRQ(ierr);
52852849c42SDave May   }
529dbe06d34SDave May   ierr = DataBucketFinalize(*DB);CHKERRQ(ierr);
530dbe06d34SDave May   ierr = DataBucketSetSizes(*DB,L,buffer);CHKERRQ(ierr);
53152849c42SDave May   /* now copy the desired guys from DBIn => DB */
532521f74f9SMatthew G. Knepley   for (p = 0; p < N; ++p) {
533dbe06d34SDave May     ierr = DataBucketCopyPoint(DBIn,list[p], *DB,p);CHKERRQ(ierr);
53452849c42SDave May   }
5357fbf63aeSDave May   PetscFunctionReturn(0);
53652849c42SDave May }
53752849c42SDave May 
538521f74f9SMatthew G. Knepley /* insert into an exisitng location */
5397fbf63aeSDave May #undef __FUNCT__
5407fbf63aeSDave May #define __FUNCT__ "DataFieldInsertPoint"
5417fbf63aeSDave May PetscErrorCode DataFieldInsertPoint(const DataField field,const PetscInt index,const void *ctx)
54252849c42SDave May {
543521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
54452849c42SDave May 
545521f74f9SMatthew G. Knepley   PetscFunctionBegin;
54652849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
54784bcda08SDave May   /* check point is valid */
548a233d522SDave May   if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
549a233d522SDave May   if (index >= field->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",field->L);
55052849c42SDave May #endif
551521f74f9SMatthew G. Knepley   ierr = PetscMemcpy(__DATATFIELD_point_access(field->data,index,field->atomic_size), ctx, field->atomic_size);CHKERRQ(ierr);
5527fbf63aeSDave May   PetscFunctionReturn(0);
55352849c42SDave May }
55452849c42SDave May 
555521f74f9SMatthew G. Knepley /* remove data at index - replace with last point */
556a233d522SDave May #undef __FUNCT__
557a233d522SDave May #define __FUNCT__ "DataBucketRemovePointAtIndex"
5587fbf63aeSDave May PetscErrorCode DataBucketRemovePointAtIndex(const DataBucket db,const PetscInt index)
55952849c42SDave May {
5605c18a9d6SDave May   PetscInt       f;
5610cb17e37SDave May   PetscBool      any_active_fields;
562dbe06d34SDave May   PetscErrorCode ierr;
56352849c42SDave May 
564521f74f9SMatthew G. Knepley   PetscFunctionBegin;
56552849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
56684bcda08SDave May   /* check point is valid */
567a233d522SDave May   if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
568a233d522SDave May   if (index >= db->allocated) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",db->L+db->buffer);
56952849c42SDave May #endif
5700cb17e37SDave May   ierr = DataBucketQueryForActiveFields(db,&any_active_fields);CHKERRQ(ierr);
5710cb17e37SDave 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");
572a233d522SDave May   if (index >= db->L) { /* this point is not in the list - no need to error, but I will anyway */
573a233d522SDave 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);
57452849c42SDave May   }
575a233d522SDave May   if (index != db->L-1) { /* not last point in list */
576521f74f9SMatthew G. Knepley     for (f = 0; f < db->nfields; ++f) {
57752849c42SDave May       DataField field = db->field[f];
57852849c42SDave May 
57952849c42SDave May       /* copy then remove */
580dbe06d34SDave May       ierr = DataFieldCopyPoint(db->L-1, field, index, field);CHKERRQ(ierr);
581521f74f9SMatthew G. Knepley       /* DataFieldZeroPoint(field,index); */
58252849c42SDave May     }
58352849c42SDave May   }
58452849c42SDave May   /* decrement size */
58552849c42SDave May   /* this will zero out an crap at the end of the list */
586dbe06d34SDave May   ierr = DataBucketRemovePoint(db);CHKERRQ(ierr);
5877fbf63aeSDave May   PetscFunctionReturn(0);
58852849c42SDave May }
58952849c42SDave May 
59052849c42SDave May /* copy x into y */
5917fbf63aeSDave May #undef __FUNCT__
5927fbf63aeSDave May #define __FUNCT__ "DataFieldCopyPoint"
5937fbf63aeSDave May PetscErrorCode DataFieldCopyPoint(const PetscInt pid_x,const DataField field_x,
5945c18a9d6SDave May                         const PetscInt pid_y,const DataField field_y )
59552849c42SDave May {
596521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
59752849c42SDave May 
598521f74f9SMatthew G. Knepley   PetscFunctionBegin;
59952849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
60084bcda08SDave May   /* check point is valid */
601a233d522SDave May   if (pid_x < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"(IN) index must be >= 0");
602a233d522SDave May   if (pid_x >= field_x->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"(IN) index must be < %D",field_x->L);
603a233d522SDave May   if (pid_y < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"(OUT) index must be >= 0");
604a233d522SDave May   if (pid_y >= field_y->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"(OUT) index must be < %D",field_y->L);
605521f74f9SMatthew G. Knepley   if( field_y->atomic_size != field_x->atomic_size ) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"atomic size must match");
60652849c42SDave May #endif
607521f74f9SMatthew G. Knepley   ierr = PetscMemcpy(__DATATFIELD_point_access(field_y->data,pid_y,field_y->atomic_size),
60852849c42SDave May                      __DATATFIELD_point_access(field_x->data,pid_x,field_x->atomic_size),
609521f74f9SMatthew G. Knepley                      field_y->atomic_size);CHKERRQ(ierr);
6107fbf63aeSDave May   PetscFunctionReturn(0);
61152849c42SDave May }
61252849c42SDave May 
61352849c42SDave May 
614521f74f9SMatthew G. Knepley /* zero only the datafield at this point */
6157fbf63aeSDave May #undef __FUNCT__
6167fbf63aeSDave May #define __FUNCT__ "DataFieldZeroPoint"
6177fbf63aeSDave May PetscErrorCode DataFieldZeroPoint(const DataField field,const PetscInt index)
61852849c42SDave May {
619521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
620521f74f9SMatthew G. Knepley 
621521f74f9SMatthew G. Knepley   PetscFunctionBegin;
62252849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
62384bcda08SDave May   /* check point is valid */
624a233d522SDave May   if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
625a233d522SDave May   if (index >= field->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",field->L);
62652849c42SDave May #endif
627521f74f9SMatthew G. Knepley   ierr = PetscMemzero(__DATATFIELD_point_access(field->data,index,field->atomic_size), field->atomic_size);CHKERRQ(ierr);
6287fbf63aeSDave May   PetscFunctionReturn(0);
62952849c42SDave May }
63052849c42SDave May 
631521f74f9SMatthew G. Knepley /* zero ALL data for this point */
6327fbf63aeSDave May #undef __FUNCT__
6337fbf63aeSDave May #define __FUNCT__ "DataBucketZeroPoint"
6347fbf63aeSDave May PetscErrorCode DataBucketZeroPoint(const DataBucket db,const PetscInt index)
63552849c42SDave May {
6365c18a9d6SDave May   PetscInt f;
637dbe06d34SDave May   PetscErrorCode ierr;
63852849c42SDave May 
639521f74f9SMatthew G. Knepley   PetscFunctionBegin;
64084bcda08SDave May   /* check point is valid */
641a233d522SDave May   if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
642a233d522SDave May   if (index >= db->allocated) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",db->allocated);
643521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
64452849c42SDave May     DataField field = db->field[f];
645dbe06d34SDave May     ierr = DataFieldZeroPoint(field,index);CHKERRQ(ierr);
64652849c42SDave May   }
6477fbf63aeSDave May   PetscFunctionReturn(0);
64852849c42SDave May }
64952849c42SDave May 
65052849c42SDave May /* increment */
6517fbf63aeSDave May #undef __FUNCT__
6527fbf63aeSDave May #define __FUNCT__ "DataBucketAddPoint"
6537fbf63aeSDave May PetscErrorCode DataBucketAddPoint(DataBucket db)
65452849c42SDave May {
655dbe06d34SDave May   PetscErrorCode ierr;
656dbe06d34SDave May 
657521f74f9SMatthew G. Knepley   PetscFunctionBegin;
658dbe06d34SDave May   ierr = DataBucketSetSizes(db,db->L+1,-1);CHKERRQ(ierr);
6597fbf63aeSDave May   PetscFunctionReturn(0);
66052849c42SDave May }
66152849c42SDave May 
6627fbf63aeSDave May /* decrement */
6637fbf63aeSDave May #undef __FUNCT__
6647fbf63aeSDave May #define __FUNCT__ "DataBucketRemovePoint"
6657fbf63aeSDave May PetscErrorCode DataBucketRemovePoint(DataBucket db)
6667fbf63aeSDave May {
667dbe06d34SDave May   PetscErrorCode ierr;
668dbe06d34SDave May 
669521f74f9SMatthew G. Knepley   PetscFunctionBegin;
670dbe06d34SDave May   ierr = DataBucketSetSizes(db,db->L-1,-1);CHKERRQ(ierr);
6717fbf63aeSDave May   PetscFunctionReturn(0);
6727fbf63aeSDave May }
6737fbf63aeSDave May 
6747fbf63aeSDave May #undef __FUNCT__
6757fbf63aeSDave May #define __FUNCT__ "_DataFieldViewBinary"
6767fbf63aeSDave May PetscErrorCode _DataFieldViewBinary(DataField field,FILE *fp)
67752849c42SDave May {
678521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
67952849c42SDave May 
680521f74f9SMatthew G. Knepley   PetscFunctionBegin;
681521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF, fp,"<DataField>\n");CHKERRQ(ierr);
682521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF, fp,"%D\n", field->L);CHKERRQ(ierr);
683521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF, fp,"%zu\n",field->atomic_size);CHKERRQ(ierr);
684521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF, fp,"%s\n", field->registeration_function);CHKERRQ(ierr);
685521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF, fp,"%s\n", field->name);CHKERRQ(ierr);
68652849c42SDave May   fwrite(field->data, field->atomic_size, field->L, fp);
687521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF, fp,"\n</DataField>\n");CHKERRQ(ierr);
6887fbf63aeSDave May   PetscFunctionReturn(0);
68952849c42SDave May }
69052849c42SDave May 
6917fbf63aeSDave May #undef __FUNCT__
6927fbf63aeSDave May #define __FUNCT__ "_DataBucketRegisterFieldFromFile"
6937fbf63aeSDave May PetscErrorCode _DataBucketRegisterFieldFromFile(FILE *fp,DataBucket db)
69452849c42SDave May {
69552849c42SDave May   PetscBool      val;
69652849c42SDave May   DataField     *field;
69752849c42SDave May   DataField      gfield;
69852849c42SDave May   char           dummy[100];
69952849c42SDave May   char           registeration_function[5000];
70052849c42SDave May   char           field_name[5000];
7015c18a9d6SDave May   PetscInt       L;
70252849c42SDave May   size_t         atomic_size,strL;
703dbe06d34SDave May   PetscErrorCode ierr;
70452849c42SDave May 
705521f74f9SMatthew G. Knepley   PetscFunctionBegin;
70652849c42SDave May   /* check we haven't finalised the registration of fields */
70752849c42SDave May   /*
70852849c42SDave May    if(db->finalised==PETSC_TRUE) {
70952849c42SDave May    printf("ERROR: DataBucketFinalize() has been called. Cannot register more fields\n");
71052849c42SDave May    ERROR();
71152849c42SDave May    }
71252849c42SDave May    */
71352849c42SDave May   /* read file contents */
714521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
715*fc2c8c6aSSatish Balay   fscanf(fp, "%" PetscInt_FMT "\n",&L);
716521f74f9SMatthew G. Knepley   fscanf(fp, "%zu\n",&atomic_size);
717521f74f9SMatthew G. Knepley   fgets(registeration_function,4999,fp);
71852849c42SDave May   strL = strlen(registeration_function);
71952849c42SDave May   if (strL > 1) {
72052849c42SDave May     registeration_function[strL-1] = 0;
72152849c42SDave May   }
722521f74f9SMatthew G. Knepley   fgets(field_name,4999,fp);
72352849c42SDave May   strL = strlen(field_name);
72452849c42SDave May   if (strL > 1) {
72552849c42SDave May     field_name[strL-1] = 0;
72652849c42SDave May   }
72752849c42SDave May 
7284b46c5e1SDave May #ifdef DATA_BUCKET_LOG
729521f74f9SMatthew 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);
73052849c42SDave May #endif
73152849c42SDave May   /* check for repeated name */
7322635f519SDave May   ierr = StringInList( field_name, db->nfields, (const DataField*)db->field, &val );CHKERRQ(ierr);
733a233d522SDave May   if (val == PETSC_TRUE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot add same field twice");
73452849c42SDave May   /* create new space for data */
735521f74f9SMatthew G. Knepley   field = (DataField *) realloc( db->field,     sizeof(DataField)*(db->nfields+1));
73652849c42SDave May   db->field     = field;
73752849c42SDave May   /* add field */
738dbe06d34SDave May   ierr = DataFieldCreate( registeration_function, field_name, atomic_size, L, &gfield );CHKERRQ(ierr);
73952849c42SDave May   /* copy contents of file */
74052849c42SDave May   fread(gfield->data, gfield->atomic_size, gfield->L, fp);
7414b46c5e1SDave May #ifdef DATA_BUCKET_LOG
742521f74f9SMatthew G. Knepley   ierr = PetscPrintf(PETSC_COMM_SELF,"  ** read %zu bytes for DataField \"%s\" \n", gfield->atomic_size * gfield->L, field_name);CHKERRQ(ierr);
74352849c42SDave May #endif
74452849c42SDave May   /* finish reading meta data */
745521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
746521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
74752849c42SDave May   db->field[db->nfields] = gfield;
74852849c42SDave May   db->nfields++;
7497fbf63aeSDave May   PetscFunctionReturn(0);
75052849c42SDave May }
75152849c42SDave May 
7527fbf63aeSDave May #undef __FUNCT__
7537fbf63aeSDave May #define __FUNCT__ "_DataBucketViewAscii_HeaderWrite_v00"
7547fbf63aeSDave May PetscErrorCode _DataBucketViewAscii_HeaderWrite_v00(FILE *fp)
75552849c42SDave May {
756521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
757521f74f9SMatthew G. Knepley 
758521f74f9SMatthew G. Knepley   PetscFunctionBegin;
759521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"<DataBucketHeader>\n");CHKERRQ(ierr);
760521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"type=DataBucket\n");CHKERRQ(ierr);
761521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"format=ascii\n");CHKERRQ(ierr);
762521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"version=0.0\n");CHKERRQ(ierr);
763521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"options=\n");CHKERRQ(ierr);
764521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"</DataBucketHeader>\n");CHKERRQ(ierr);
7657fbf63aeSDave May   PetscFunctionReturn(0);
76652849c42SDave May }
7677fbf63aeSDave May 
7687fbf63aeSDave May #undef __FUNCT__
7697fbf63aeSDave May #define __FUNCT__ "_DataBucketViewAscii_HeaderRead_v00"
7707fbf63aeSDave May PetscErrorCode _DataBucketViewAscii_HeaderRead_v00(FILE *fp)
77152849c42SDave May {
77252849c42SDave May   char           dummy[100];
77352849c42SDave May   size_t         strL;
774521f74f9SMatthew G. Knepley   PetscBool      flg;
775521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
77652849c42SDave May 
777521f74f9SMatthew G. Knepley   PetscFunctionBegin;
778521f74f9SMatthew G. Knepley   /* header open */
779521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
78052849c42SDave May 
781521f74f9SMatthew G. Knepley   /* type */
782521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
78352849c42SDave May   strL = strlen(dummy);
78452849c42SDave May   if (strL > 1) {dummy[strL-1] = 0;}
785521f74f9SMatthew G. Knepley   ierr = PetscStrcmp(dummy, "type=DataBucket", &flg);CHKERRQ(ierr);
786521f74f9SMatthew G. Knepley   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Data file doesn't contain a DataBucket type");
787521f74f9SMatthew G. Knepley   /* format */
788521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
789521f74f9SMatthew G. Knepley   /* version */
790521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
79152849c42SDave May   strL = strlen(dummy);
79252849c42SDave May   if (strL > 1) { dummy[strL-1] = 0; }
793521f74f9SMatthew G. Knepley   ierr = PetscStrcmp(dummy, "version=0.0", &flg);CHKERRQ(ierr);
794521f74f9SMatthew G. Knepley   if (!flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"DataBucket file must be parsed with version=0.0 : You tried %s", dummy);
795521f74f9SMatthew G. Knepley   /* options */
796521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
797521f74f9SMatthew G. Knepley   /* header close */
798521f74f9SMatthew G. Knepley   fgets(dummy,99,fp);
7997fbf63aeSDave May   PetscFunctionReturn(0);
80052849c42SDave May }
80152849c42SDave May 
8027fbf63aeSDave May #undef __FUNCT__
8037fbf63aeSDave May #define __FUNCT__ "_DataBucketLoadFromFileBinary_SEQ"
8047fbf63aeSDave May PetscErrorCode _DataBucketLoadFromFileBinary_SEQ(const char filename[],DataBucket *_db)
80552849c42SDave May {
80652849c42SDave May   DataBucket db;
80752849c42SDave May   FILE *fp;
8085c18a9d6SDave May   PetscInt L,buffer,f,nfields;
809dbe06d34SDave May   PetscErrorCode ierr;
81052849c42SDave May 
811521f74f9SMatthew G. Knepley   PetscFunctionBegin;
8124b46c5e1SDave May #ifdef DATA_BUCKET_LOG
813521f74f9SMatthew G. Knepley   ierr = PetscPrintf(PETSC_COMM_SELF,"** DataBucketLoadFromFile **\n");CHKERRQ(ierr);
81452849c42SDave May #endif
81552849c42SDave May   /* open file */
81652849c42SDave May   fp = fopen(filename,"rb");
817521f74f9SMatthew G. Knepley   if (fp == NULL) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file with name %s", filename);
81852849c42SDave May   /* read header */
819dbe06d34SDave May   ierr = _DataBucketViewAscii_HeaderRead_v00(fp);CHKERRQ(ierr);
820*fc2c8c6aSSatish Balay   fscanf(fp,"%" PetscInt_FMT "\n%" PetscInt_FMT "\n%" PetscInt_FMT "\n",&L,&buffer,&nfields);
821dbe06d34SDave May   ierr = DataBucketCreate(&db);CHKERRQ(ierr);
822521f74f9SMatthew G. Knepley   for (f = 0; f < nfields; ++f) {
823dbe06d34SDave May     ierr = _DataBucketRegisterFieldFromFile(fp,db);CHKERRQ(ierr);
82452849c42SDave May   }
82552849c42SDave May   fclose(fp);
826dbe06d34SDave May   ierr = DataBucketFinalize(db);CHKERRQ(ierr);
82752849c42SDave May   /*
82852849c42SDave May    DataBucketSetSizes(db,L,buffer);
82952849c42SDave May    */
83052849c42SDave May   db->L = L;
83152849c42SDave May   db->buffer = buffer;
83252849c42SDave May   db->allocated = L + buffer;
83352849c42SDave May   *_db = db;
8347fbf63aeSDave May   PetscFunctionReturn(0);
83552849c42SDave May }
83652849c42SDave May 
8377fbf63aeSDave May #undef __FUNCT__
8387fbf63aeSDave May #define __FUNCT__ "DataBucketLoadFromFile"
8397fbf63aeSDave May PetscErrorCode DataBucketLoadFromFile(MPI_Comm comm,const char filename[],DataBucketViewType type,DataBucket *db)
84052849c42SDave May {
8415c18a9d6SDave May   PetscMPIInt    nproc,rank;
842997fa542SDave May   PetscErrorCode ierr;
84352849c42SDave May 
844521f74f9SMatthew G. Knepley   PetscFunctionBegin;
845997fa542SDave May   ierr = MPI_Comm_size(comm,&nproc);CHKERRQ(ierr);
846997fa542SDave May   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
8474b46c5e1SDave May #ifdef DATA_BUCKET_LOG
848521f74f9SMatthew G. Knepley   ierr = PetscPrintf(PETSC_COMM_SELF,"** DataBucketLoadFromFile **\n");CHKERRQ(ierr);
84952849c42SDave May #endif
85052849c42SDave May   if (type == DATABUCKET_VIEW_STDOUT) {
85152849c42SDave May   } else if (type == DATABUCKET_VIEW_ASCII) {
852a233d522SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot be implemented as we don't know the underlying particle data structure");
85352849c42SDave May   } else if (type == DATABUCKET_VIEW_BINARY) {
85452849c42SDave May     if (nproc == 1) {
855dbe06d34SDave May       ierr = _DataBucketLoadFromFileBinary_SEQ(filename,db);CHKERRQ(ierr);
85652849c42SDave May     } else {
857521f74f9SMatthew G. Knepley       char name[PETSC_MAX_PATH_LEN];
85852849c42SDave May 
859521f74f9SMatthew G. Knepley       ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "%s_p%1.5d", filename, rank);CHKERRQ(ierr);
860dbe06d34SDave May       ierr = _DataBucketLoadFromFileBinary_SEQ(name, db);CHKERRQ(ierr);
86152849c42SDave May     }
862521f74f9SMatthew G. Knepley   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unknown viewer requested");
8637fbf63aeSDave May   PetscFunctionReturn(0);
86452849c42SDave May }
86552849c42SDave May 
8667fbf63aeSDave May #undef __FUNCT__
8677fbf63aeSDave May #define __FUNCT__ "_DataBucketViewBinary"
8687fbf63aeSDave May PetscErrorCode _DataBucketViewBinary(DataBucket db,const char filename[])
86952849c42SDave May {
87052849c42SDave May   FILE          *fp = NULL;
8715c18a9d6SDave May   PetscInt       f;
872dbe06d34SDave May   PetscErrorCode ierr;
87352849c42SDave May 
874521f74f9SMatthew G. Knepley   PetscFunctionBegin;
87552849c42SDave May   fp = fopen(filename,"wb");
876a233d522SDave May   if (fp == NULL) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot open file with name %s", filename);
87752849c42SDave May   /* db header */
878dbe06d34SDave May   ierr =_DataBucketViewAscii_HeaderWrite_v00(fp);CHKERRQ(ierr);
87952849c42SDave May   /* meta-data */
880521f74f9SMatthew G. Knepley   ierr = PetscFPrintf(PETSC_COMM_SELF, fp, "%D\n%D\n%D\n", db->L,db->buffer,db->nfields);CHKERRQ(ierr);
88152849c42SDave May   /* load datafields */
882521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
883dbe06d34SDave May     ierr = _DataFieldViewBinary(db->field[f],fp);CHKERRQ(ierr);
88452849c42SDave May   }
88552849c42SDave May   fclose(fp);
8867fbf63aeSDave May   PetscFunctionReturn(0);
88752849c42SDave May }
88852849c42SDave May 
8897fbf63aeSDave May #undef __FUNCT__
8907fbf63aeSDave May #define __FUNCT__ "DataBucketView_SEQ"
8917fbf63aeSDave May PetscErrorCode DataBucketView_SEQ(DataBucket db,const char filename[],DataBucketViewType type)
89252849c42SDave May {
893dbe06d34SDave May   PetscErrorCode ierr;
894dbe06d34SDave May 
895521f74f9SMatthew G. Knepley   PetscFunctionBegin;
89652849c42SDave May   switch (type) {
89752849c42SDave May   case DATABUCKET_VIEW_STDOUT:
89852849c42SDave May   {
8995c18a9d6SDave May     PetscInt f;
90052849c42SDave May     double memory_usage_total = 0.0;
90152849c42SDave May 
902521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"DataBucketView(SEQ): (\"%s\")\n",filename);CHKERRQ(ierr);
903521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  L                  = %D \n", db->L);CHKERRQ(ierr);
904521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  buffer             = %D \n", db->buffer);CHKERRQ(ierr);
905521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  allocated          = %D \n", db->allocated);CHKERRQ(ierr);
906521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  nfields registered = %D \n", db->nfields);CHKERRQ(ierr);
907521f74f9SMatthew G. Knepley     for (f = 0; f < db->nfields; ++f) {
90852849c42SDave May       double memory_usage_f = (double)(db->field[f]->atomic_size * db->allocated) * 1.0e-6;
909521f74f9SMatthew 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);
910521f74f9SMatthew G. Knepley       ierr = PetscPrintf(PETSC_COMM_SELF,"           blocksize          = %D \n", db->field[f]->bs);CHKERRQ(ierr);
91152c3ed93SDave May       if (db->field[f]->bs != 1) {
912521f74f9SMatthew 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);
913521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PETSC_COMM_SELF,"           atomic size/item   = %zu \n", db->field[f]->atomic_size/db->field[f]->bs);CHKERRQ(ierr);
91452c3ed93SDave May       } else {
915521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PETSC_COMM_SELF,"           atomic size        = %zu \n", db->field[f]->atomic_size);CHKERRQ(ierr);
91652c3ed93SDave May       }
91752849c42SDave May       memory_usage_total += memory_usage_f;
91852849c42SDave May     }
919521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  Total mem. usage                                                      = %1.2e (MB) \n", memory_usage_total);CHKERRQ(ierr);
92052849c42SDave May   }
92152849c42SDave May   break;
92252849c42SDave May   case DATABUCKET_VIEW_ASCII:
92352849c42SDave May   {
924a233d522SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot be implemented as we don't know the underlying particle data structure");
92552849c42SDave May   }
92652849c42SDave May   break;
92752849c42SDave May   case DATABUCKET_VIEW_BINARY:
92852849c42SDave May   {
929dbe06d34SDave May     ierr = _DataBucketViewBinary(db,filename);CHKERRQ(ierr);
93052849c42SDave May   }
93152849c42SDave May   break;
93252849c42SDave May   case DATABUCKET_VIEW_HDF5:
93352849c42SDave May   {
934a233d522SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No HDF5 support");
93552849c42SDave May   }
93652849c42SDave May   break;
937521f74f9SMatthew G. Knepley   default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer method requested");
93852849c42SDave May   }
9397fbf63aeSDave May   PetscFunctionReturn(0);
94052849c42SDave May }
94152849c42SDave May 
9427fbf63aeSDave May #undef __FUNCT__
9437fbf63aeSDave May #define __FUNCT__ "DataBucketView_MPI"
9447fbf63aeSDave May PetscErrorCode DataBucketView_MPI(MPI_Comm comm,DataBucket db,const char filename[],DataBucketViewType type)
94552849c42SDave May {
946997fa542SDave May   PetscErrorCode ierr;
947997fa542SDave May 
948521f74f9SMatthew G. Knepley   PetscFunctionBegin;
94952849c42SDave May   switch (type) {
95052849c42SDave May   case DATABUCKET_VIEW_STDOUT:
95152849c42SDave May   {
9525c18a9d6SDave May     PetscInt f;
9535c18a9d6SDave May     PetscInt L,buffer,allocated;
95452849c42SDave May     double memory_usage_total,memory_usage_total_local = 0.0;
9555c18a9d6SDave May     PetscMPIInt rank;
95652849c42SDave May 
957997fa542SDave May     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
958dbe06d34SDave May     ierr = DataBucketGetGlobalSizes(comm,db,&L,&buffer,&allocated);CHKERRQ(ierr);
959521f74f9SMatthew G. Knepley     for (f = 0; f < db->nfields; ++f) {
96052849c42SDave May       double memory_usage_f = (double)(db->field[f]->atomic_size * db->allocated) * 1.0e-6;
96152849c42SDave May       memory_usage_total_local += memory_usage_f;
96252849c42SDave May     }
963dbe06d34SDave May     ierr = MPI_Allreduce(&memory_usage_total_local,&memory_usage_total,1,MPI_DOUBLE,MPI_SUM,comm);CHKERRQ(ierr);
964521f74f9SMatthew G. Knepley     ierr = PetscPrintf(comm,"DataBucketView(MPI): (\"%s\")\n",filename);CHKERRQ(ierr);
965521f74f9SMatthew G. Knepley     ierr = PetscPrintf(comm,"  L                  = %D \n", L);CHKERRQ(ierr);
966521f74f9SMatthew G. Knepley     ierr = PetscPrintf(comm,"  buffer (max)       = %D \n", buffer);CHKERRQ(ierr);
967521f74f9SMatthew G. Knepley     ierr = PetscPrintf(comm,"  allocated          = %D \n", allocated);CHKERRQ(ierr);
968521f74f9SMatthew G. Knepley     ierr = PetscPrintf(comm,"  nfields registered = %D \n", db->nfields);CHKERRQ(ierr);
96952849c42SDave May     for (f=0; f<db->nfields; f++) {
97052849c42SDave May       double memory_usage_f = (double)(db->field[f]->atomic_size * db->allocated) * 1.0e-6;
971521f74f9SMatthew 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);
97252849c42SDave May     }
973521f74f9SMatthew G. Knepley     ierr = PetscPrintf(PETSC_COMM_SELF,"  Total mem. usage                                                      = %1.2e (MB) : collective\n", memory_usage_total);CHKERRQ(ierr);
97452849c42SDave May   }
97552849c42SDave May   break;
97652849c42SDave May   case DATABUCKET_VIEW_ASCII:
97752849c42SDave May   {
978a233d522SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot be implemented as we don't know the underlying data structure");
97952849c42SDave May   }
98052849c42SDave May   break;
98152849c42SDave May   case DATABUCKET_VIEW_BINARY:
98252849c42SDave May   {
983521f74f9SMatthew G. Knepley     char        name[PETSC_MAX_PATH_LEN];
9845c18a9d6SDave May     PetscMPIInt rank;
98552849c42SDave May 
98652849c42SDave May     /* create correct extension */
987997fa542SDave May     ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
988521f74f9SMatthew G. Knepley     ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "%s_p%1.5d", filename, rank);CHKERRQ(ierr);
989dbe06d34SDave May     ierr = _DataBucketViewBinary(db, name);CHKERRQ(ierr);
99052849c42SDave May   }
99152849c42SDave May   break;
99252849c42SDave May   case DATABUCKET_VIEW_HDF5:
99352849c42SDave May   {
994a233d522SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for HDF5");
99552849c42SDave May   }
99652849c42SDave May   break;
997521f74f9SMatthew G. Knepley   default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer method requested");
99852849c42SDave May   }
9997fbf63aeSDave May   PetscFunctionReturn(0);
100052849c42SDave May }
100152849c42SDave May 
10027fbf63aeSDave May #undef __FUNCT__
10037fbf63aeSDave May #define __FUNCT__ "DataBucketView"
10047fbf63aeSDave May PetscErrorCode DataBucketView(MPI_Comm comm,DataBucket db,const char filename[],DataBucketViewType type)
100552849c42SDave May {
10065c18a9d6SDave May   PetscMPIInt nproc;
1007997fa542SDave May   PetscErrorCode ierr;
100852849c42SDave May 
1009521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1010997fa542SDave May   ierr = MPI_Comm_size(comm,&nproc);CHKERRQ(ierr);
101152849c42SDave May   if (nproc == 1) {
1012dbe06d34SDave May     ierr = DataBucketView_SEQ(db,filename,type);CHKERRQ(ierr);
101352849c42SDave May   } else {
1014dbe06d34SDave May     ierr = DataBucketView_MPI(comm,db,filename,type);CHKERRQ(ierr);
101552849c42SDave May   }
10167fbf63aeSDave May   PetscFunctionReturn(0);
101752849c42SDave May }
101852849c42SDave May 
10197fbf63aeSDave May #undef __FUNCT__
10207fbf63aeSDave May #define __FUNCT__ "DataBucketDuplicateFields"
10217fbf63aeSDave May PetscErrorCode DataBucketDuplicateFields(DataBucket dbA,DataBucket *dbB)
102252849c42SDave May {
102352849c42SDave May   DataBucket db2;
10245c18a9d6SDave May   PetscInt f;
1025dbe06d34SDave May   PetscErrorCode ierr;
102652849c42SDave May 
1027521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1028dbe06d34SDave May   ierr = DataBucketCreate(&db2);CHKERRQ(ierr);
102952849c42SDave May   /* copy contents from dbA into db2 */
1030521f74f9SMatthew G. Knepley   for (f = 0; f < dbA->nfields; ++f) {
103152849c42SDave May     DataField field;
103252849c42SDave May     size_t    atomic_size;
103352849c42SDave May     char      *name;
103452849c42SDave May 
103552849c42SDave May     field = dbA->field[f];
103652849c42SDave May     atomic_size = field->atomic_size;
103752849c42SDave May     name        = field->name;
1038dbe06d34SDave May     ierr = DataBucketRegisterField(db2,"DataBucketDuplicateFields",name,atomic_size,NULL);CHKERRQ(ierr);
103952849c42SDave May   }
1040dbe06d34SDave May   ierr = DataBucketFinalize(db2);CHKERRQ(ierr);
1041dbe06d34SDave May   ierr = DataBucketSetInitialSizes(db2,0,1000);CHKERRQ(ierr);
104252849c42SDave May   *dbB = db2;
10437fbf63aeSDave May   PetscFunctionReturn(0);
104452849c42SDave May }
104552849c42SDave May 
104652849c42SDave May /*
104752849c42SDave May  Insert points from db2 into db1
104852849c42SDave May  db1 <<== db2
104952849c42SDave May  */
10507fbf63aeSDave May #undef __FUNCT__
10517fbf63aeSDave May #define __FUNCT__ "DataBucketInsertValues"
10527fbf63aeSDave May PetscErrorCode DataBucketInsertValues(DataBucket db1,DataBucket db2)
105352849c42SDave May {
10545c18a9d6SDave May   PetscInt n_mp_points1,n_mp_points2;
10555c18a9d6SDave May   PetscInt n_mp_points1_new,p;
1056dbe06d34SDave May   PetscErrorCode ierr;
105752849c42SDave May 
1058521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1059dbe06d34SDave May   ierr = DataBucketGetSizes(db1,&n_mp_points1,0,0);CHKERRQ(ierr);
1060dbe06d34SDave May   ierr = DataBucketGetSizes(db2,&n_mp_points2,0,0);CHKERRQ(ierr);
106152849c42SDave May   n_mp_points1_new = n_mp_points1 + n_mp_points2;
1062dbe06d34SDave May   ierr = DataBucketSetSizes(db1,n_mp_points1_new,-1);CHKERRQ(ierr);
1063521f74f9SMatthew G. Knepley   for (p = 0; p < n_mp_points2; ++p) {
1064521f74f9SMatthew G. Knepley     /* db1 <<== db2 */
1065dbe06d34SDave May     ierr = DataBucketCopyPoint(db2,p, db1,(n_mp_points1 + p));CHKERRQ(ierr);
106652849c42SDave May   }
10677fbf63aeSDave May   PetscFunctionReturn(0);
106852849c42SDave May }
106952849c42SDave May 
107052849c42SDave May /* helpers for parallel send/recv */
10717fbf63aeSDave May #undef __FUNCT__
10727fbf63aeSDave May #define __FUNCT__ "DataBucketCreatePackedArray"
10737fbf63aeSDave May PetscErrorCode DataBucketCreatePackedArray(DataBucket db,size_t *bytes,void **buf)
107452849c42SDave May {
10755c18a9d6SDave May   PetscInt       f;
107652849c42SDave May   size_t         sizeof_marker_contents;
107752849c42SDave May   void          *buffer;
1078521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
107952849c42SDave May 
1080521f74f9SMatthew G. Knepley   PetscFunctionBegin;
108152849c42SDave May   sizeof_marker_contents = 0;
1082521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
108352849c42SDave May     DataField df = db->field[f];
108452849c42SDave May     sizeof_marker_contents += df->atomic_size;
108552849c42SDave May   }
1086521f74f9SMatthew G. Knepley   ierr = PetscMalloc(sizeof_marker_contents, &buffer);CHKERRQ(ierr);
1087521f74f9SMatthew G. Knepley   ierr = PetscMemzero(buffer, sizeof_marker_contents);CHKERRQ(ierr);
108852849c42SDave May   if (bytes) {*bytes = sizeof_marker_contents;}
108952849c42SDave May   if (buf)   {*buf   = buffer;}
10907fbf63aeSDave May   PetscFunctionReturn(0);
109152849c42SDave May }
109252849c42SDave May 
10937fbf63aeSDave May #undef __FUNCT__
10947fbf63aeSDave May #define __FUNCT__ "DataBucketDestroyPackedArray"
10957fbf63aeSDave May PetscErrorCode DataBucketDestroyPackedArray(DataBucket db,void **buf)
109652849c42SDave May {
1097521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
1098521f74f9SMatthew G. Knepley 
1099521f74f9SMatthew G. Knepley   PetscFunctionBegin;
110052849c42SDave May   if (buf) {
1101521f74f9SMatthew G. Knepley     ierr = PetscFree(*buf);CHKERRQ(ierr);
110252849c42SDave May     *buf = NULL;
110352849c42SDave May   }
11047fbf63aeSDave May   PetscFunctionReturn(0);
110552849c42SDave May }
110652849c42SDave May 
11077fbf63aeSDave May #undef __FUNCT__
11087fbf63aeSDave May #define __FUNCT__ "DataBucketFillPackedArray"
11097fbf63aeSDave May PetscErrorCode DataBucketFillPackedArray(DataBucket db,const PetscInt index,void *buf)
111052849c42SDave May {
11115c18a9d6SDave May   PetscInt       f;
111252849c42SDave May   void          *data, *data_p;
111352849c42SDave May   size_t         asize, offset;
1114521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
111552849c42SDave May 
1116521f74f9SMatthew G. Knepley   PetscFunctionBegin;
111752849c42SDave May   offset = 0;
1118521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
111952849c42SDave May     DataField df = db->field[f];
112052849c42SDave May 
112152849c42SDave May     asize = df->atomic_size;
112252849c42SDave May     data = (void*)( df->data );
112352849c42SDave May     data_p = (void*)( (char*)data + index*asize );
1124521f74f9SMatthew G. Knepley     ierr = PetscMemcpy((void*)((char*)buf + offset), data_p, asize);CHKERRQ(ierr);
112552849c42SDave May     offset = offset + asize;
112652849c42SDave May   }
11277fbf63aeSDave May   PetscFunctionReturn(0);
112852849c42SDave May }
112952849c42SDave May 
11307fbf63aeSDave May #undef __FUNCT__
11317fbf63aeSDave May #define __FUNCT__ "DataBucketInsertPackedArray"
11327fbf63aeSDave May PetscErrorCode DataBucketInsertPackedArray(DataBucket db,const PetscInt idx,void *data)
113352849c42SDave May {
11345c18a9d6SDave May   PetscInt f;
113552849c42SDave May   void *data_p;
113652849c42SDave May   size_t offset;
1137dbe06d34SDave May   PetscErrorCode ierr;
113852849c42SDave May 
1139521f74f9SMatthew G. Knepley   PetscFunctionBegin;
114052849c42SDave May   offset = 0;
1141521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
114252849c42SDave May     DataField df = db->field[f];
114352849c42SDave May 
114452849c42SDave May     data_p = (void*)( (char*)data + offset );
1145dbe06d34SDave May     ierr = DataFieldInsertPoint(df, idx, (void*)data_p);CHKERRQ(ierr);
114652849c42SDave May     offset = offset + df->atomic_size;
114752849c42SDave May   }
11487fbf63aeSDave May   PetscFunctionReturn(0);
114952849c42SDave May }
1150