xref: /petsc/src/dm/impls/swarm/data_bucket.c (revision 5627991adfa0dae03dda7a34b1ec5f8d16d5e5f7)
1279f676cSBarry Smith #include "../src/dm/impls/swarm/data_bucket.h"
252849c42SDave May 
352849c42SDave May /* string helpers */
477048351SPatrick Sanan PetscErrorCode DMSwarmDataFieldStringInList(const char name[],const PetscInt N,const DMSwarmDataField gfield[],PetscBool *val)
552849c42SDave May {
65c18a9d6SDave May   PetscInt       i;
7521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
852849c42SDave May 
9521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1052849c42SDave May   *val = PETSC_FALSE;
11521f74f9SMatthew G. Knepley   for (i = 0; i < N; ++i) {
12521f74f9SMatthew G. Knepley     PetscBool flg;
13521f74f9SMatthew G. Knepley     ierr = PetscStrcmp(name, gfield[i]->name, &flg);CHKERRQ(ierr);
14521f74f9SMatthew G. Knepley     if (flg) {
1552849c42SDave May       *val = PETSC_TRUE;
162eac95f8SDave May       PetscFunctionReturn(0);
1752849c42SDave May     }
1852849c42SDave May   }
192eac95f8SDave May   PetscFunctionReturn(0);
2052849c42SDave May }
2152849c42SDave May 
2277048351SPatrick Sanan PetscErrorCode DMSwarmDataFieldStringFindInList(const char name[],const PetscInt N,const DMSwarmDataField gfield[],PetscInt *index)
2352849c42SDave May {
245c18a9d6SDave May   PetscInt       i;
25521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
2652849c42SDave May 
27521f74f9SMatthew G. Knepley   PetscFunctionBegin;
2852849c42SDave May   *index = -1;
29521f74f9SMatthew G. Knepley   for (i = 0; i < N; ++i) {
30521f74f9SMatthew G. Knepley     PetscBool flg;
31521f74f9SMatthew G. Knepley     ierr = PetscStrcmp(name, gfield[i]->name, &flg);CHKERRQ(ierr);
32521f74f9SMatthew G. Knepley     if (flg) {
3352849c42SDave May       *index = i;
342eac95f8SDave May       PetscFunctionReturn(0);
3552849c42SDave May     }
3652849c42SDave May   }
372eac95f8SDave May   PetscFunctionReturn(0);
3852849c42SDave May }
3952849c42SDave May 
40ee71fbaeSPatrick Sanan PetscErrorCode DMSwarmDataFieldCreate(const char registration_function[],const char name[],const size_t size,const PetscInt L,DMSwarmDataField *DF)
4152849c42SDave May {
4277048351SPatrick Sanan   DMSwarmDataField df;
43521f74f9SMatthew G. Knepley   PetscErrorCode   ierr;
4452849c42SDave May 
45521f74f9SMatthew G. Knepley   PetscFunctionBegin;
46*5627991aSBarry Smith   ierr = PetscNew(&df);CHKERRQ(ierr);
47ee71fbaeSPatrick Sanan   ierr = PetscStrallocpy(registration_function, &df->registration_function);CHKERRQ(ierr);
48521f74f9SMatthew G. Knepley   ierr = PetscStrallocpy(name, &df->name);CHKERRQ(ierr);
4952849c42SDave May   df->atomic_size = size;
5052849c42SDave May   df->L  = L;
5152c3ed93SDave May   df->bs = 1;
52521f74f9SMatthew G. Knepley   /* allocate something so we don't have to reallocate */
53521f74f9SMatthew G. Knepley   ierr = PetscMalloc(size * L, &df->data);CHKERRQ(ierr);
54521f74f9SMatthew G. Knepley   ierr = PetscMemzero(df->data, size * L);CHKERRQ(ierr);
5552849c42SDave May   *DF = df;
562eac95f8SDave May   PetscFunctionReturn(0);
5752849c42SDave May }
5852849c42SDave May 
5977048351SPatrick Sanan PetscErrorCode DMSwarmDataFieldDestroy(DMSwarmDataField *DF)
6052849c42SDave May {
6177048351SPatrick Sanan   DMSwarmDataField df = *DF;
62521f74f9SMatthew G. Knepley   PetscErrorCode   ierr;
6352849c42SDave May 
64521f74f9SMatthew G. Knepley   PetscFunctionBegin;
65ee71fbaeSPatrick Sanan   ierr = PetscFree(df->registration_function);CHKERRQ(ierr);
66521f74f9SMatthew G. Knepley   ierr = PetscFree(df->name);CHKERRQ(ierr);
67521f74f9SMatthew G. Knepley   ierr = PetscFree(df->data);CHKERRQ(ierr);
68521f74f9SMatthew G. Knepley   ierr = PetscFree(df);CHKERRQ(ierr);
6952849c42SDave May   *DF  = NULL;
702eac95f8SDave May   PetscFunctionReturn(0);
7152849c42SDave May }
7252849c42SDave May 
7352849c42SDave May /* data bucket */
7477048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketCreate(DMSwarmDataBucket *DB)
7552849c42SDave May {
7677048351SPatrick Sanan   DMSwarmDataBucket db;
77521f74f9SMatthew G. Knepley   PetscErrorCode    ierr;
7852849c42SDave May 
79521f74f9SMatthew G. Knepley   PetscFunctionBegin;
80*5627991aSBarry Smith   ierr = PetscNew(&db);CHKERRQ(ierr);
8152849c42SDave May 
8252849c42SDave May   db->finalised = PETSC_FALSE;
8352849c42SDave May   /* create empty spaces for fields */
843454631fSDave May   db->L         = -1;
8552849c42SDave May   db->buffer    = 1;
8652849c42SDave May   db->allocated = 1;
8752849c42SDave May   db->nfields   = 0;
88521f74f9SMatthew G. Knepley   ierr = PetscMalloc1(1, &db->field);CHKERRQ(ierr);
8952849c42SDave May   *DB  = db;
902eac95f8SDave May   PetscFunctionReturn(0);
9152849c42SDave May }
9252849c42SDave May 
9377048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketDestroy(DMSwarmDataBucket *DB)
9452849c42SDave May {
9577048351SPatrick Sanan   DMSwarmDataBucket db = *DB;
965c18a9d6SDave May   PetscInt          f;
97dbe06d34SDave May   PetscErrorCode    ierr;
9852849c42SDave May 
99521f74f9SMatthew G. Knepley   PetscFunctionBegin;
10052849c42SDave May   /* release fields */
101521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
10277048351SPatrick Sanan     ierr = DMSwarmDataFieldDestroy(&db->field[f]);CHKERRQ(ierr);
10352849c42SDave May   }
10452849c42SDave May   /* this will catch the initially allocated objects in the event that no fields are registered */
10552849c42SDave May   if (db->field != NULL) {
106521f74f9SMatthew G. Knepley     ierr = PetscFree(db->field);CHKERRQ(ierr);
10752849c42SDave May   }
108521f74f9SMatthew G. Knepley   ierr = PetscFree(db);CHKERRQ(ierr);
10952849c42SDave May   *DB = NULL;
1102eac95f8SDave May   PetscFunctionReturn(0);
11152849c42SDave May }
11252849c42SDave May 
11377048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketQueryForActiveFields(DMSwarmDataBucket db,PetscBool *any_active_fields)
1140cb17e37SDave May {
1150cb17e37SDave May   PetscInt f;
116521f74f9SMatthew G. Knepley 
117521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1180cb17e37SDave May   *any_active_fields = PETSC_FALSE;
119521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
1200cb17e37SDave May     if (db->field[f]->active) {
1210cb17e37SDave May       *any_active_fields = PETSC_TRUE;
1220cb17e37SDave May       PetscFunctionReturn(0);
1230cb17e37SDave May     }
1240cb17e37SDave May   }
1250cb17e37SDave May   PetscFunctionReturn(0);
1260cb17e37SDave May }
1270cb17e37SDave May 
128*5627991aSBarry Smith PetscErrorCode DMSwarmDataBucketRegisterField(DMSwarmDataBucket db,const char registration_function[],const char field_name[],size_t atomic_size, DMSwarmDataField *_gfield)
12952849c42SDave May {
13052849c42SDave May   PetscBool        val;
13177048351SPatrick Sanan   DMSwarmDataField fp;
132dbe06d34SDave May   PetscErrorCode   ierr;
13352849c42SDave May 
134521f74f9SMatthew G. Knepley   PetscFunctionBegin;
13552849c42SDave May   /* check we haven't finalised the registration of fields */
13652849c42SDave May         /*
13752849c42SDave May    if (db->finalised==PETSC_TRUE) {
13877048351SPatrick Sanan    printf("ERROR: DMSwarmDataBucketFinalize() has been called. Cannot register more fields\n");
13952849c42SDave May    ERROR();
14052849c42SDave May    }
14152849c42SDave May   */
14252849c42SDave May   /* check for repeated name */
14377048351SPatrick Sanan   ierr = DMSwarmDataFieldStringInList(field_name, db->nfields, (const DMSwarmDataField*) db->field, &val);CHKERRQ(ierr);
1442eac95f8SDave May   if (val == PETSC_TRUE) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field %s already exists. Cannot add same field twice",field_name);
14552849c42SDave May   /* create new space for data */
14677048351SPatrick Sanan   ierr = PetscRealloc(sizeof(DMSwarmDataField)*(db->nfields+1), &db->field);CHKERRQ(ierr);
14752849c42SDave May   /* add field */
148ee71fbaeSPatrick Sanan   ierr = DMSwarmDataFieldCreate(registration_function, field_name, atomic_size, db->allocated, &fp);CHKERRQ(ierr);
14952849c42SDave May   db->field[db->nfields] = fp;
15052849c42SDave May   db->nfields++;
15152849c42SDave May   if (_gfield != NULL) {
15252849c42SDave May     *_gfield = fp;
15352849c42SDave May   }
1542eac95f8SDave May   PetscFunctionReturn(0);
15552849c42SDave May }
15652849c42SDave May 
15752849c42SDave May /*
15877048351SPatrick Sanan  #define DMSwarmDataBucketRegisterField(db,name,size,k) {\
15952849c42SDave May  char *location;\
16052849c42SDave May  asprintf(&location,"Registered by %s() at line %d within file %s", __FUNCTION__, __LINE__, __FILE__);\
16177048351SPatrick Sanan  _DMSwarmDataBucketRegisterField( (db), location, (name), (size), (k));\
162521f74f9SMatthew G. Knepley  ierr = PetscFree(location);\
16352849c42SDave May  }
16452849c42SDave May  */
16552849c42SDave May 
16677048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketGetDMSwarmDataFieldByName(DMSwarmDataBucket db,const char name[],DMSwarmDataField *gfield)
16752849c42SDave May {
1685c18a9d6SDave May   PetscInt       idx;
16952849c42SDave May   PetscBool      found;
170521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
17152849c42SDave May 
172521f74f9SMatthew G. Knepley   PetscFunctionBegin;
17377048351SPatrick Sanan   ierr = DMSwarmDataFieldStringInList(name,db->nfields,(const DMSwarmDataField*)db->field,&found);CHKERRQ(ierr);
17477048351SPatrick Sanan   if (!found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot find DMSwarmDataField with name %s",name);
17577048351SPatrick Sanan   ierr = DMSwarmDataFieldStringFindInList(name,db->nfields,(const DMSwarmDataField*)db->field,&idx);CHKERRQ(ierr);
17652849c42SDave May   *gfield = db->field[idx];
1772eac95f8SDave May   PetscFunctionReturn(0);
17852849c42SDave May }
17952849c42SDave May 
18077048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketQueryDMSwarmDataFieldByName(DMSwarmDataBucket db,const char name[],PetscBool *found)
18152849c42SDave May {
1822635f519SDave May   PetscErrorCode ierr;
183521f74f9SMatthew G. Knepley 
184521f74f9SMatthew G. Knepley   PetscFunctionBegin;
18552849c42SDave May   *found = PETSC_FALSE;
18677048351SPatrick Sanan   ierr = DMSwarmDataFieldStringInList(name,db->nfields,(const DMSwarmDataField*)db->field,found);CHKERRQ(ierr);
1877fbf63aeSDave May   PetscFunctionReturn(0);
18852849c42SDave May }
18952849c42SDave May 
19077048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketFinalize(DMSwarmDataBucket db)
19152849c42SDave May {
192521f74f9SMatthew G. Knepley   PetscFunctionBegin;
19352849c42SDave May   db->finalised = PETSC_TRUE;
1947fbf63aeSDave May   PetscFunctionReturn(0);
19552849c42SDave May }
19652849c42SDave May 
19777048351SPatrick Sanan PetscErrorCode DMSwarmDataFieldGetNumEntries(DMSwarmDataField df,PetscInt *sum)
19852849c42SDave May {
199521f74f9SMatthew G. Knepley   PetscFunctionBegin;
20052849c42SDave May   *sum = df->L;
2017fbf63aeSDave May   PetscFunctionReturn(0);
20252849c42SDave May }
20352849c42SDave May 
20477048351SPatrick Sanan PetscErrorCode DMSwarmDataFieldSetBlockSize(DMSwarmDataField df,PetscInt blocksize)
20552c3ed93SDave May {
206521f74f9SMatthew G. Knepley   PetscFunctionBegin;
20752c3ed93SDave May   df->bs = blocksize;
20852c3ed93SDave May   PetscFunctionReturn(0);
20952c3ed93SDave May }
21052c3ed93SDave May 
21177048351SPatrick Sanan PetscErrorCode DMSwarmDataFieldSetSize(DMSwarmDataField df,const PetscInt new_L)
21252849c42SDave May {
213521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
21452849c42SDave May 
215521f74f9SMatthew G. Knepley   PetscFunctionBegin;
21677048351SPatrick Sanan   if (new_L < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot set size of DMSwarmDataField to be < 0");
2177fbf63aeSDave May   if (new_L == df->L) PetscFunctionReturn(0);
21852849c42SDave May   if (new_L > df->L) {
2194be7464cSMatthew G. Knepley     ierr = PetscRealloc(df->atomic_size * (new_L), &df->data);CHKERRQ(ierr);
22052849c42SDave May     /* init new contents */
221521f74f9SMatthew G. Knepley     ierr = PetscMemzero(( ((char*)df->data)+df->L*df->atomic_size), (new_L-df->L)*df->atomic_size);CHKERRQ(ierr);
2227fbf63aeSDave May   } else {
22352849c42SDave May     /* reallocate pointer list, add +1 in case new_L = 0 */
2244be7464cSMatthew G. Knepley     ierr = PetscRealloc(df->atomic_size * (new_L+1), &df->data);CHKERRQ(ierr);
22552849c42SDave May   }
22652849c42SDave May   df->L = new_L;
2277fbf63aeSDave May   PetscFunctionReturn(0);
22852849c42SDave May }
22952849c42SDave May 
23077048351SPatrick Sanan PetscErrorCode DMSwarmDataFieldZeroBlock(DMSwarmDataField df,const PetscInt start,const PetscInt end)
23152849c42SDave May {
232521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
233521f74f9SMatthew G. Knepley 
234521f74f9SMatthew G. Knepley   PetscFunctionBegin;
2357fbf63aeSDave May   if (start > end) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot zero a block of entries if start(%D) > end(%D)",start,end);
2367fbf63aeSDave May   if (start < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot zero a block of entries if start(%D) < 0",start);
237a233d522SDave 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);
238521f74f9SMatthew G. Knepley   ierr = PetscMemzero((((char*)df->data)+start*df->atomic_size), (end-start)*df->atomic_size);CHKERRQ(ierr);
2397fbf63aeSDave May   PetscFunctionReturn(0);
24052849c42SDave May }
24152849c42SDave May 
24252849c42SDave May /*
24352849c42SDave May  A negative buffer value will simply be ignored and the old buffer value will be used.
24452849c42SDave May  */
24577048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketSetSizes(DMSwarmDataBucket db,const PetscInt L,const PetscInt buffer)
24652849c42SDave May {
2475c18a9d6SDave May   PetscInt       current_allocated,new_used,new_unused,new_buffer,new_allocated,f;
2480cb17e37SDave May   PetscBool      any_active_fields;
249dbe06d34SDave May   PetscErrorCode ierr;
25052849c42SDave May 
251521f74f9SMatthew G. Knepley   PetscFunctionBegin;
25277048351SPatrick Sanan   if (db->finalised == PETSC_FALSE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"You must call DMSwarmDataBucketFinalize() before DMSwarmDataBucketSetSizes()");
25377048351SPatrick Sanan   ierr = DMSwarmDataBucketQueryForActiveFields(db,&any_active_fields);CHKERRQ(ierr);
25477048351SPatrick Sanan   if (any_active_fields) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot safely re-size as at least one DMSwarmDataField is currently being accessed");
2550cb17e37SDave May 
25652849c42SDave May   current_allocated = db->allocated;
25752849c42SDave May   new_used   = L;
25852849c42SDave May   new_unused = current_allocated - new_used;
25952849c42SDave May   new_buffer = db->buffer;
26052849c42SDave May   if (buffer >= 0) { /* update the buffer value */
26152849c42SDave May     new_buffer = buffer;
26252849c42SDave May   }
26352849c42SDave May   new_allocated = new_used + new_buffer;
26452849c42SDave May   /* action */
26552849c42SDave May   if (new_allocated > current_allocated) {
26652849c42SDave May     /* increase size to new_used + new_buffer */
26752849c42SDave May     for (f=0; f<db->nfields; f++) {
26877048351SPatrick Sanan       ierr = DMSwarmDataFieldSetSize(db->field[f], new_allocated);CHKERRQ(ierr);
26952849c42SDave May     }
27052849c42SDave May     db->L         = new_used;
27152849c42SDave May     db->buffer    = new_buffer;
27252849c42SDave May     db->allocated = new_used + new_buffer;
273521f74f9SMatthew G. Knepley   } else {
27452849c42SDave May     if (new_unused > 2 * new_buffer) {
27552849c42SDave May       /* shrink array to new_used + new_buffer */
276521f74f9SMatthew G. Knepley       for (f = 0; f < db->nfields; ++f) {
27777048351SPatrick Sanan         ierr = DMSwarmDataFieldSetSize(db->field[f], new_allocated);CHKERRQ(ierr);
27852849c42SDave May       }
27952849c42SDave May       db->L         = new_used;
28052849c42SDave May       db->buffer    = new_buffer;
28152849c42SDave May       db->allocated = new_used + new_buffer;
282521f74f9SMatthew G. Knepley     } else {
28352849c42SDave May       db->L      = new_used;
28452849c42SDave May       db->buffer = new_buffer;
28552849c42SDave May     }
28652849c42SDave May   }
28752849c42SDave May   /* zero all entries from db->L to db->allocated */
288521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
28977048351SPatrick Sanan     DMSwarmDataField field = db->field[f];
29077048351SPatrick Sanan     ierr = DMSwarmDataFieldZeroBlock(field, db->L,db->allocated);CHKERRQ(ierr);
29152849c42SDave May   }
2927fbf63aeSDave May   PetscFunctionReturn(0);
29352849c42SDave May }
29452849c42SDave May 
29577048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketSetInitialSizes(DMSwarmDataBucket db,const PetscInt L,const PetscInt buffer)
29652849c42SDave May {
2975c18a9d6SDave May   PetscInt       f;
298dbe06d34SDave May   PetscErrorCode ierr;
299dbe06d34SDave May 
300521f74f9SMatthew G. Knepley   PetscFunctionBegin;
30177048351SPatrick Sanan   ierr = DMSwarmDataBucketSetSizes(db,L,buffer);CHKERRQ(ierr);
302521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
30377048351SPatrick Sanan     DMSwarmDataField field = db->field[f];
30477048351SPatrick Sanan     ierr = DMSwarmDataFieldZeroBlock(field,0,db->allocated);CHKERRQ(ierr);
30552849c42SDave May   }
3067fbf63aeSDave May   PetscFunctionReturn(0);
30752849c42SDave May }
30852849c42SDave May 
30977048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketGetSizes(DMSwarmDataBucket db,PetscInt *L,PetscInt *buffer,PetscInt *allocated)
31052849c42SDave May {
311521f74f9SMatthew G. Knepley   PetscFunctionBegin;
31252849c42SDave May   if (L) {*L = db->L;}
31352849c42SDave May   if (buffer) {*buffer = db->buffer;}
31452849c42SDave May   if (allocated) {*allocated = db->allocated;}
3157fbf63aeSDave May   PetscFunctionReturn(0);
31652849c42SDave May }
31752849c42SDave May 
31877048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketGetGlobalSizes(MPI_Comm comm,DMSwarmDataBucket db,PetscInt *L,PetscInt *buffer,PetscInt *allocated)
31952849c42SDave May {
3205c18a9d6SDave May   PetscInt ierr;
32152849c42SDave May 
322521f74f9SMatthew G. Knepley   PetscFunctionBegin;
323ffc4695bSBarry Smith   if (L) {ierr = MPI_Allreduce(&db->L,L,1,MPIU_INT,MPI_SUM,comm);CHKERRMPI(ierr);}
324ffc4695bSBarry Smith   if (buffer) {ierr = MPI_Allreduce(&db->buffer,buffer,1,MPIU_INT,MPI_SUM,comm);CHKERRMPI(ierr);}
325ffc4695bSBarry Smith   if (allocated) {ierr = MPI_Allreduce(&db->allocated,allocated,1,MPIU_INT,MPI_SUM,comm);CHKERRMPI(ierr);}
3267fbf63aeSDave May   PetscFunctionReturn(0);
32752849c42SDave May }
32852849c42SDave May 
32977048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketGetDMSwarmDataFields(DMSwarmDataBucket db,PetscInt *L,DMSwarmDataField *fields[])
33052849c42SDave May {
331521f74f9SMatthew G. Knepley   PetscFunctionBegin;
33252849c42SDave May   if (L)      {*L      = db->nfields;}
33352849c42SDave May   if (fields) {*fields = db->field;}
3347fbf63aeSDave May   PetscFunctionReturn(0);
33552849c42SDave May }
33652849c42SDave May 
33777048351SPatrick Sanan PetscErrorCode DMSwarmDataFieldGetAccess(const DMSwarmDataField gfield)
33852849c42SDave May {
339521f74f9SMatthew G. Knepley   PetscFunctionBegin;
34077048351SPatrick Sanan   if (gfield->active) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is already active. You must call DMSwarmDataFieldRestoreAccess()",gfield->name);
34152849c42SDave May   gfield->active = PETSC_TRUE;
3427fbf63aeSDave May   PetscFunctionReturn(0);
34352849c42SDave May }
34452849c42SDave May 
34577048351SPatrick Sanan PetscErrorCode DMSwarmDataFieldAccessPoint(const DMSwarmDataField gfield,const PetscInt pid,void **ctx_p)
34652849c42SDave May {
347521f74f9SMatthew G. Knepley   PetscFunctionBegin;
34872505a4dSJed Brown   *ctx_p = NULL;
349497880caSRichard Tran Mills #if defined(DMSWARM_DATAFIELD_POINT_ACCESS_GUARD)
35052849c42SDave May   /* debug mode */
35184bcda08SDave May   /* check point is valid */
3527fbf63aeSDave May   if (pid < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
3537fbf63aeSDave May   if (pid >= gfield->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",gfield->L);
35477048351SPatrick Sanan   if (gfield->active == PETSC_FALSE) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is not active. You must call DMSwarmDataFieldGetAccess() before point data can be retrivied",gfield->name);
35552849c42SDave May #endif
35677048351SPatrick Sanan   *ctx_p = DMSWARM_DATAFIELD_point_access(gfield->data,pid,gfield->atomic_size);
3577fbf63aeSDave May   PetscFunctionReturn(0);
35852849c42SDave May }
35952849c42SDave May 
36077048351SPatrick Sanan PetscErrorCode DMSwarmDataFieldAccessPointOffset(const DMSwarmDataField gfield,const size_t offset,const PetscInt pid,void **ctx_p)
36152849c42SDave May {
362521f74f9SMatthew G. Knepley   PetscFunctionBegin;
363497880caSRichard Tran Mills #if defined(DMSWARM_DATAFIELD_POINT_ACCESS_GUARD)
36452849c42SDave May   /* debug mode */
36584bcda08SDave May   /* check point is valid */
366521f74f9SMatthew G. Knepley   /* if (offset < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"offset must be >= 0");*/
367521f74f9SMatthew G. Knepley   /* Note compiler realizes this can never happen with an unsigned PetscInt */
3687fbf63aeSDave May   if (offset >= gfield->atomic_size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"offset must be < %zu",gfield->atomic_size);
36984bcda08SDave May   /* check point is valid */
3707fbf63aeSDave May   if (pid < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
371a233d522SDave May   if (pid >= gfield->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",gfield->L);
37277048351SPatrick Sanan   if (gfield->active == PETSC_FALSE) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is not active. You must call DMSwarmDataFieldGetAccess() before point data can be retrivied",gfield->name);
37352849c42SDave May #endif
37477048351SPatrick Sanan   *ctx_p = DMSWARM_DATAFIELD_point_access_offset(gfield->data,pid,gfield->atomic_size,offset);
3757fbf63aeSDave May   PetscFunctionReturn(0);
37652849c42SDave May }
37752849c42SDave May 
37877048351SPatrick Sanan PetscErrorCode DMSwarmDataFieldRestoreAccess(DMSwarmDataField gfield)
37952849c42SDave May {
380521f74f9SMatthew G. Knepley   PetscFunctionBegin;
38177048351SPatrick Sanan   if (gfield->active == PETSC_FALSE) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is not active. You must call DMSwarmDataFieldGetAccess()", gfield->name);
38252849c42SDave May   gfield->active = PETSC_FALSE;
3837fbf63aeSDave May   PetscFunctionReturn(0);
38452849c42SDave May }
38552849c42SDave May 
38677048351SPatrick Sanan PetscErrorCode DMSwarmDataFieldVerifyAccess(const DMSwarmDataField gfield,const size_t size)
38752849c42SDave May {
388521f74f9SMatthew G. Knepley   PetscFunctionBegin;
389497880caSRichard Tran Mills #if defined(DMSWARM_DATAFIELD_POINT_ACCESS_GUARD)
390521f74f9SMatthew 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);
39152849c42SDave May #endif
3927fbf63aeSDave May   PetscFunctionReturn(0);
39352849c42SDave May }
39452849c42SDave May 
39577048351SPatrick Sanan PetscErrorCode DMSwarmDataFieldGetAtomicSize(const DMSwarmDataField gfield,size_t *size)
39652849c42SDave May {
397521f74f9SMatthew G. Knepley   PetscFunctionBegin;
39852849c42SDave May   if (size) {*size = gfield->atomic_size;}
3997fbf63aeSDave May   PetscFunctionReturn(0);
40052849c42SDave May }
40152849c42SDave May 
40277048351SPatrick Sanan PetscErrorCode DMSwarmDataFieldGetEntries(const DMSwarmDataField gfield,void **data)
40352849c42SDave May {
404521f74f9SMatthew G. Knepley   PetscFunctionBegin;
405521f74f9SMatthew G. Knepley   if (data) {*data = gfield->data;}
4067fbf63aeSDave May   PetscFunctionReturn(0);
40752849c42SDave May }
40852849c42SDave May 
40977048351SPatrick Sanan PetscErrorCode DMSwarmDataFieldRestoreEntries(const DMSwarmDataField gfield,void **data)
41052849c42SDave May {
411521f74f9SMatthew G. Knepley   PetscFunctionBegin;
412521f74f9SMatthew G. Knepley   if (data) {*data = NULL;}
4137fbf63aeSDave May   PetscFunctionReturn(0);
41452849c42SDave May }
41552849c42SDave May 
41652849c42SDave May /* y = x */
417*5627991aSBarry Smith PetscErrorCode DMSwarmDataBucketCopyPoint(const DMSwarmDataBucket xb,const PetscInt pid_x,const DMSwarmDataBucket yb,const PetscInt pid_y)
41852849c42SDave May {
4195c18a9d6SDave May   PetscInt       f;
420dbe06d34SDave May   PetscErrorCode ierr;
421dbe06d34SDave May 
422521f74f9SMatthew G. Knepley   PetscFunctionBegin;
423521f74f9SMatthew G. Knepley   for (f = 0; f < xb->nfields; ++f) {
42452849c42SDave May     void *dest;
42552849c42SDave May     void *src;
42652849c42SDave May 
42777048351SPatrick Sanan     ierr = DMSwarmDataFieldGetAccess(xb->field[f]);CHKERRQ(ierr);
42877048351SPatrick Sanan     if (xb != yb) { ierr = DMSwarmDataFieldGetAccess( yb->field[f]);CHKERRQ(ierr); }
42977048351SPatrick Sanan     ierr = DMSwarmDataFieldAccessPoint(xb->field[f],pid_x, &src);CHKERRQ(ierr);
43077048351SPatrick Sanan     ierr = DMSwarmDataFieldAccessPoint(yb->field[f],pid_y, &dest);CHKERRQ(ierr);
431521f74f9SMatthew G. Knepley     ierr = PetscMemcpy(dest, src, xb->field[f]->atomic_size);CHKERRQ(ierr);
43277048351SPatrick Sanan     ierr = DMSwarmDataFieldRestoreAccess(xb->field[f]);CHKERRQ(ierr);
43377048351SPatrick Sanan     if (xb != yb) {ierr = DMSwarmDataFieldRestoreAccess(yb->field[f]);CHKERRQ(ierr);}
43452849c42SDave May   }
4357fbf63aeSDave May   PetscFunctionReturn(0);
43652849c42SDave May }
43752849c42SDave May 
43877048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketCreateFromSubset(DMSwarmDataBucket DBIn,const PetscInt N,const PetscInt list[],DMSwarmDataBucket *DB)
43952849c42SDave May {
4405c18a9d6SDave May   PetscInt         nfields;
44177048351SPatrick Sanan   DMSwarmDataField *fields;
4425c18a9d6SDave May   PetscInt         f,L,buffer,allocated,p;
443dbe06d34SDave May   PetscErrorCode   ierr;
44452849c42SDave May 
445521f74f9SMatthew G. Knepley   PetscFunctionBegin;
44677048351SPatrick Sanan   ierr = DMSwarmDataBucketCreate(DB);CHKERRQ(ierr);
44752849c42SDave May   /* copy contents of DBIn */
44877048351SPatrick Sanan   ierr = DMSwarmDataBucketGetDMSwarmDataFields(DBIn,&nfields,&fields);CHKERRQ(ierr);
44977048351SPatrick Sanan   ierr = DMSwarmDataBucketGetSizes(DBIn,&L,&buffer,&allocated);CHKERRQ(ierr);
450521f74f9SMatthew G. Knepley   for (f = 0; f < nfields; ++f) {
45177048351SPatrick Sanan     ierr = DMSwarmDataBucketRegisterField(*DB,"DMSwarmDataBucketCreateFromSubset",fields[f]->name,fields[f]->atomic_size,NULL);CHKERRQ(ierr);
45252849c42SDave May   }
45377048351SPatrick Sanan   ierr = DMSwarmDataBucketFinalize(*DB);CHKERRQ(ierr);
45477048351SPatrick Sanan   ierr = DMSwarmDataBucketSetSizes(*DB,L,buffer);CHKERRQ(ierr);
45552849c42SDave May   /* now copy the desired guys from DBIn => DB */
456521f74f9SMatthew G. Knepley   for (p = 0; p < N; ++p) {
457d0c080abSJoseph Pusztay     ierr = DMSwarmDataBucketCopyPoint(DBIn,list[p], *DB,list[p]);CHKERRQ(ierr);
45852849c42SDave May   }
4597fbf63aeSDave May   PetscFunctionReturn(0);
46052849c42SDave May }
46152849c42SDave May 
462521f74f9SMatthew G. Knepley /* insert into an exisitng location */
46377048351SPatrick Sanan PetscErrorCode DMSwarmDataFieldInsertPoint(const DMSwarmDataField field,const PetscInt index,const void *ctx)
46452849c42SDave May {
465521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
46652849c42SDave May 
467521f74f9SMatthew G. Knepley   PetscFunctionBegin;
468497880caSRichard Tran Mills #if defined(DMSWARM_DATAFIELD_POINT_ACCESS_GUARD)
46984bcda08SDave May   /* check point is valid */
470a233d522SDave May   if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
471a233d522SDave May   if (index >= field->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",field->L);
47252849c42SDave May #endif
47377048351SPatrick Sanan   ierr = PetscMemcpy(DMSWARM_DATAFIELD_point_access(field->data,index,field->atomic_size), ctx, field->atomic_size);CHKERRQ(ierr);
4747fbf63aeSDave May   PetscFunctionReturn(0);
47552849c42SDave May }
47652849c42SDave May 
477521f74f9SMatthew G. Knepley /* remove data at index - replace with last point */
47877048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketRemovePointAtIndex(const DMSwarmDataBucket db,const PetscInt index)
47952849c42SDave May {
4805c18a9d6SDave May   PetscInt       f;
4810cb17e37SDave May   PetscBool      any_active_fields;
482dbe06d34SDave May   PetscErrorCode ierr;
48352849c42SDave May 
484521f74f9SMatthew G. Knepley   PetscFunctionBegin;
485497880caSRichard Tran Mills #if defined(DMSWARM_DATAFIELD_POINT_ACCESS_GUARD)
48684bcda08SDave May   /* check point is valid */
487a233d522SDave May   if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
488a233d522SDave May   if (index >= db->allocated) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",db->L+db->buffer);
48952849c42SDave May #endif
49077048351SPatrick Sanan   ierr = DMSwarmDataBucketQueryForActiveFields(db,&any_active_fields);CHKERRQ(ierr);
49177048351SPatrick Sanan   if (any_active_fields) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot safely remove point as at least one DMSwarmDataField is currently being accessed");
492a233d522SDave May   if (index >= db->L) { /* this point is not in the list - no need to error, but I will anyway */
493a233d522SDave 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);
49452849c42SDave May   }
495a233d522SDave May   if (index != db->L-1) { /* not last point in list */
496521f74f9SMatthew G. Knepley     for (f = 0; f < db->nfields; ++f) {
49777048351SPatrick Sanan       DMSwarmDataField field = db->field[f];
49852849c42SDave May 
49952849c42SDave May       /* copy then remove */
50077048351SPatrick Sanan       ierr = DMSwarmDataFieldCopyPoint(db->L-1, field, index, field);CHKERRQ(ierr);
50177048351SPatrick Sanan       /* DMSwarmDataFieldZeroPoint(field,index); */
50252849c42SDave May     }
50352849c42SDave May   }
50452849c42SDave May   /* decrement size */
50552849c42SDave May   /* this will zero out an crap at the end of the list */
50677048351SPatrick Sanan   ierr = DMSwarmDataBucketRemovePoint(db);CHKERRQ(ierr);
5077fbf63aeSDave May   PetscFunctionReturn(0);
50852849c42SDave May }
50952849c42SDave May 
51052849c42SDave May /* copy x into y */
511*5627991aSBarry Smith PetscErrorCode DMSwarmDataFieldCopyPoint(const PetscInt pid_x,const DMSwarmDataField field_x,const PetscInt pid_y,const DMSwarmDataField field_y)
51252849c42SDave May {
513521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
51452849c42SDave May 
515521f74f9SMatthew G. Knepley   PetscFunctionBegin;
516497880caSRichard Tran Mills #if defined(DMSWARM_DATAFIELD_POINT_ACCESS_GUARD)
51784bcda08SDave May   /* check point is valid */
518a233d522SDave May   if (pid_x < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"(IN) index must be >= 0");
519a233d522SDave May   if (pid_x >= field_x->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"(IN) index must be < %D",field_x->L);
520a233d522SDave May   if (pid_y < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"(OUT) index must be >= 0");
521a233d522SDave May   if (pid_y >= field_y->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"(OUT) index must be < %D",field_y->L);
522521f74f9SMatthew G. Knepley   if (field_y->atomic_size != field_x->atomic_size) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"atomic size must match");
52352849c42SDave May #endif
52477048351SPatrick Sanan   ierr = PetscMemcpy(DMSWARM_DATAFIELD_point_access(field_y->data,pid_y,field_y->atomic_size),DMSWARM_DATAFIELD_point_access(field_x->data,pid_x,field_x->atomic_size),field_y->atomic_size);CHKERRQ(ierr);
5257fbf63aeSDave May   PetscFunctionReturn(0);
52652849c42SDave May }
52752849c42SDave May 
528521f74f9SMatthew G. Knepley /* zero only the datafield at this point */
52977048351SPatrick Sanan PetscErrorCode DMSwarmDataFieldZeroPoint(const DMSwarmDataField field,const PetscInt index)
53052849c42SDave May {
531521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
532521f74f9SMatthew G. Knepley 
533521f74f9SMatthew G. Knepley   PetscFunctionBegin;
534497880caSRichard Tran Mills #if defined(DMSWARM_DATAFIELD_POINT_ACCESS_GUARD)
53584bcda08SDave May   /* check point is valid */
536a233d522SDave May   if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
537a233d522SDave May   if (index >= field->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",field->L);
53852849c42SDave May #endif
53977048351SPatrick Sanan   ierr = PetscMemzero(DMSWARM_DATAFIELD_point_access(field->data,index,field->atomic_size), field->atomic_size);CHKERRQ(ierr);
5407fbf63aeSDave May   PetscFunctionReturn(0);
54152849c42SDave May }
54252849c42SDave May 
543521f74f9SMatthew G. Knepley /* zero ALL data for this point */
54477048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketZeroPoint(const DMSwarmDataBucket db,const PetscInt index)
54552849c42SDave May {
5465c18a9d6SDave May   PetscInt       f;
547dbe06d34SDave May   PetscErrorCode ierr;
54852849c42SDave May 
549521f74f9SMatthew G. Knepley   PetscFunctionBegin;
55084bcda08SDave May   /* check point is valid */
551a233d522SDave May   if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
552a233d522SDave May   if (index >= db->allocated) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",db->allocated);
553521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
55477048351SPatrick Sanan     DMSwarmDataField field = db->field[f];
55577048351SPatrick Sanan     ierr = DMSwarmDataFieldZeroPoint(field,index);CHKERRQ(ierr);
55652849c42SDave May   }
5577fbf63aeSDave May   PetscFunctionReturn(0);
55852849c42SDave May }
55952849c42SDave May 
56052849c42SDave May /* increment */
56177048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketAddPoint(DMSwarmDataBucket db)
56252849c42SDave May {
563dbe06d34SDave May   PetscErrorCode ierr;
564dbe06d34SDave May 
565521f74f9SMatthew G. Knepley   PetscFunctionBegin;
56677048351SPatrick Sanan   ierr = DMSwarmDataBucketSetSizes(db,db->L+1,DMSWARM_DATA_BUCKET_BUFFER_DEFAULT);CHKERRQ(ierr);
5677fbf63aeSDave May   PetscFunctionReturn(0);
56852849c42SDave May }
56952849c42SDave May 
5707fbf63aeSDave May /* decrement */
57177048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketRemovePoint(DMSwarmDataBucket db)
5727fbf63aeSDave May {
573dbe06d34SDave May   PetscErrorCode ierr;
574dbe06d34SDave May 
575521f74f9SMatthew G. Knepley   PetscFunctionBegin;
57677048351SPatrick Sanan   ierr = DMSwarmDataBucketSetSizes(db,db->L-1,DMSWARM_DATA_BUCKET_BUFFER_DEFAULT);CHKERRQ(ierr);
5777fbf63aeSDave May   PetscFunctionReturn(0);
5787fbf63aeSDave May }
5797fbf63aeSDave May 
580*5627991aSBarry Smith /*  Should be redone to user PetscViewer */
58177048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketView_stdout(MPI_Comm comm,DMSwarmDataBucket db)
582ab2be9a3SDave May {
583ab2be9a3SDave May   PetscInt       f;
584ab2be9a3SDave May   double         memory_usage_total,memory_usage_total_local = 0.0;
585ab2be9a3SDave May   PetscErrorCode ierr;
586ab2be9a3SDave May 
587ab2be9a3SDave May   PetscFunctionBegin;
58877048351SPatrick Sanan   ierr = PetscPrintf(comm,"DMSwarmDataBucketView: \n");CHKERRQ(ierr);
589ab2be9a3SDave May   ierr = PetscPrintf(comm,"  L                  = %D \n", db->L);CHKERRQ(ierr);
590ab2be9a3SDave May   ierr = PetscPrintf(comm,"  buffer             = %D \n", db->buffer);CHKERRQ(ierr);
591ab2be9a3SDave May   ierr = PetscPrintf(comm,"  allocated          = %D \n", db->allocated);CHKERRQ(ierr);
592ab2be9a3SDave May   ierr = PetscPrintf(comm,"  nfields registered = %D \n", db->nfields);CHKERRQ(ierr);
593ab2be9a3SDave May 
594ab2be9a3SDave May   for (f = 0; f < db->nfields; ++f) {
595ab2be9a3SDave May     double memory_usage_f = (double)(db->field[f]->atomic_size * db->allocated) * 1.0e-6;
596ab2be9a3SDave May     memory_usage_total_local += memory_usage_f;
597ab2be9a3SDave May   }
598ffc4695bSBarry Smith   ierr = MPI_Allreduce(&memory_usage_total_local,&memory_usage_total,1,MPI_DOUBLE,MPI_SUM,comm);CHKERRMPI(ierr);
599ab2be9a3SDave May 
600ab2be9a3SDave May   for (f = 0; f < db->nfields; ++f) {
601ab2be9a3SDave May     double memory_usage_f = (double)(db->field[f]->atomic_size * db->allocated) * 1.0e-6;
602ab2be9a3SDave May     ierr = PetscPrintf(comm,"    [%3D] %15s : Mem. usage       = %1.2e (MB) [rank0]\n", f, db->field[f]->name, memory_usage_f);CHKERRQ(ierr);
603ab2be9a3SDave May     ierr = PetscPrintf(comm,"                            blocksize        = %D \n", db->field[f]->bs);CHKERRQ(ierr);
604ab2be9a3SDave May     if (db->field[f]->bs != 1) {
605ab2be9a3SDave May       ierr = PetscPrintf(comm,"                            atomic size      = %zu [full block, bs=%D]\n", db->field[f]->atomic_size,db->field[f]->bs);CHKERRQ(ierr);
606ab2be9a3SDave May       ierr = PetscPrintf(comm,"                            atomic size/item = %zu \n", db->field[f]->atomic_size/db->field[f]->bs);CHKERRQ(ierr);
607ab2be9a3SDave May     } else {
608ab2be9a3SDave May       ierr = PetscPrintf(comm,"                            atomic size      = %zu \n", db->field[f]->atomic_size);CHKERRQ(ierr);
609ab2be9a3SDave May     }
610ab2be9a3SDave May   }
611ab2be9a3SDave May   ierr = PetscPrintf(comm,"  Total mem. usage                           = %1.2e (MB) (collective)\n", memory_usage_total);CHKERRQ(ierr);
612ab2be9a3SDave May   PetscFunctionReturn(0);
613ab2be9a3SDave May }
614ab2be9a3SDave May 
615*5627991aSBarry Smith PetscErrorCode DMSwarmDataBucketView_Seq(MPI_Comm comm,DMSwarmDataBucket db,const char filename[],DMSwarmDataBucketViewType type)
61652849c42SDave May {
617dbe06d34SDave May   PetscErrorCode ierr;
618dbe06d34SDave May 
619521f74f9SMatthew G. Knepley   PetscFunctionBegin;
62052849c42SDave May   switch (type) {
62152849c42SDave May   case DATABUCKET_VIEW_STDOUT:
62277048351SPatrick Sanan     ierr = DMSwarmDataBucketView_stdout(PETSC_COMM_SELF,db);CHKERRQ(ierr);
62352849c42SDave May     break;
62452849c42SDave May   case DATABUCKET_VIEW_ASCII:
625071ce369SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for ascii output");
62652849c42SDave May   case DATABUCKET_VIEW_BINARY:
627071ce369SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for binary output");
62852849c42SDave May   case DATABUCKET_VIEW_HDF5:
629071ce369SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for HDF5 output");
630521f74f9SMatthew G. Knepley   default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer method requested");
63152849c42SDave May   }
6327fbf63aeSDave May   PetscFunctionReturn(0);
63352849c42SDave May }
63452849c42SDave May 
63577048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketView_MPI(MPI_Comm comm,DMSwarmDataBucket db,const char filename[],DMSwarmDataBucketViewType type)
63652849c42SDave May {
637997fa542SDave May   PetscErrorCode ierr;
638997fa542SDave May 
639521f74f9SMatthew G. Knepley   PetscFunctionBegin;
64052849c42SDave May   switch (type) {
64152849c42SDave May   case DATABUCKET_VIEW_STDOUT:
64277048351SPatrick Sanan     ierr = DMSwarmDataBucketView_stdout(comm,db);CHKERRQ(ierr);
64352849c42SDave May     break;
64452849c42SDave May   case DATABUCKET_VIEW_ASCII:
645071ce369SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for ascii output");
64652849c42SDave May   case DATABUCKET_VIEW_BINARY:
647071ce369SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for binary output");
64852849c42SDave May   case DATABUCKET_VIEW_HDF5:
649071ce369SDave May     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for HDF5 output");
650521f74f9SMatthew G. Knepley   default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer method requested");
65152849c42SDave May   }
6527fbf63aeSDave May   PetscFunctionReturn(0);
65352849c42SDave May }
65452849c42SDave May 
65577048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketView(MPI_Comm comm,DMSwarmDataBucket db,const char filename[],DMSwarmDataBucketViewType type)
65652849c42SDave May {
657d7d19db6SBarry Smith   PetscMPIInt    size;
658997fa542SDave May   PetscErrorCode ierr;
65952849c42SDave May 
660521f74f9SMatthew G. Knepley   PetscFunctionBegin;
661ffc4695bSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr);
662d7d19db6SBarry Smith   if (size == 1) {
663*5627991aSBarry Smith     ierr = DMSwarmDataBucketView_Seq(comm,db,filename,type);CHKERRQ(ierr);
66452849c42SDave May   } else {
66577048351SPatrick Sanan     ierr = DMSwarmDataBucketView_MPI(comm,db,filename,type);CHKERRQ(ierr);
66652849c42SDave May   }
6677fbf63aeSDave May   PetscFunctionReturn(0);
66852849c42SDave May }
66952849c42SDave May 
67077048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketDuplicateFields(DMSwarmDataBucket dbA,DMSwarmDataBucket *dbB)
67152849c42SDave May {
67277048351SPatrick Sanan   DMSwarmDataBucket db2;
6735c18a9d6SDave May   PetscInt          f;
674dbe06d34SDave May   PetscErrorCode    ierr;
67552849c42SDave May 
676521f74f9SMatthew G. Knepley   PetscFunctionBegin;
67777048351SPatrick Sanan   ierr = DMSwarmDataBucketCreate(&db2);CHKERRQ(ierr);
67852849c42SDave May   /* copy contents from dbA into db2 */
679521f74f9SMatthew G. Knepley   for (f = 0; f < dbA->nfields; ++f) {
68077048351SPatrick Sanan     DMSwarmDataField field;
68152849c42SDave May     size_t           atomic_size;
68252849c42SDave May     char             *name;
68352849c42SDave May 
68452849c42SDave May     field = dbA->field[f];
68552849c42SDave May     atomic_size = field->atomic_size;
68652849c42SDave May     name        = field->name;
68777048351SPatrick Sanan     ierr = DMSwarmDataBucketRegisterField(db2,"DMSwarmDataBucketDuplicateFields",name,atomic_size,NULL);CHKERRQ(ierr);
68852849c42SDave May   }
68977048351SPatrick Sanan   ierr = DMSwarmDataBucketFinalize(db2);CHKERRQ(ierr);
69077048351SPatrick Sanan   ierr = DMSwarmDataBucketSetInitialSizes(db2,0,1000);CHKERRQ(ierr);
69152849c42SDave May   *dbB = db2;
6927fbf63aeSDave May   PetscFunctionReturn(0);
69352849c42SDave May }
69452849c42SDave May 
69552849c42SDave May /*
69652849c42SDave May  Insert points from db2 into db1
69752849c42SDave May  db1 <<== db2
69852849c42SDave May  */
69977048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketInsertValues(DMSwarmDataBucket db1,DMSwarmDataBucket db2)
70052849c42SDave May {
7015c18a9d6SDave May   PetscInt       n_mp_points1,n_mp_points2;
7025c18a9d6SDave May   PetscInt       n_mp_points1_new,p;
703dbe06d34SDave May   PetscErrorCode ierr;
70452849c42SDave May 
705521f74f9SMatthew G. Knepley   PetscFunctionBegin;
706ea78f98cSLisandro Dalcin   ierr = DMSwarmDataBucketGetSizes(db1,&n_mp_points1,NULL,NULL);CHKERRQ(ierr);
707ea78f98cSLisandro Dalcin   ierr = DMSwarmDataBucketGetSizes(db2,&n_mp_points2,NULL,NULL);CHKERRQ(ierr);
70852849c42SDave May   n_mp_points1_new = n_mp_points1 + n_mp_points2;
70977048351SPatrick Sanan   ierr = DMSwarmDataBucketSetSizes(db1,n_mp_points1_new,DMSWARM_DATA_BUCKET_BUFFER_DEFAULT);CHKERRQ(ierr);
710521f74f9SMatthew G. Knepley   for (p = 0; p < n_mp_points2; ++p) {
711521f74f9SMatthew G. Knepley     /* db1 <<== db2 */
71277048351SPatrick Sanan     ierr = DMSwarmDataBucketCopyPoint(db2,p, db1,(n_mp_points1 + p));CHKERRQ(ierr);
71352849c42SDave May   }
7147fbf63aeSDave May   PetscFunctionReturn(0);
71552849c42SDave May }
71652849c42SDave May 
71752849c42SDave May /* helpers for parallel send/recv */
71877048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketCreatePackedArray(DMSwarmDataBucket db,size_t *bytes,void **buf)
71952849c42SDave May {
7205c18a9d6SDave May   PetscInt       f;
72152849c42SDave May   size_t         sizeof_marker_contents;
72252849c42SDave May   void          *buffer;
723521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
72452849c42SDave May 
725521f74f9SMatthew G. Knepley   PetscFunctionBegin;
72652849c42SDave May   sizeof_marker_contents = 0;
727521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
72877048351SPatrick Sanan     DMSwarmDataField df = db->field[f];
72952849c42SDave May     sizeof_marker_contents += df->atomic_size;
73052849c42SDave May   }
731521f74f9SMatthew G. Knepley   ierr = PetscMalloc(sizeof_marker_contents, &buffer);CHKERRQ(ierr);
732521f74f9SMatthew G. Knepley   ierr = PetscMemzero(buffer, sizeof_marker_contents);CHKERRQ(ierr);
73352849c42SDave May   if (bytes) {*bytes = sizeof_marker_contents;}
73452849c42SDave May   if (buf)   {*buf   = buffer;}
7357fbf63aeSDave May   PetscFunctionReturn(0);
73652849c42SDave May }
73752849c42SDave May 
73877048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketDestroyPackedArray(DMSwarmDataBucket db,void **buf)
73952849c42SDave May {
740521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
741521f74f9SMatthew G. Knepley 
742521f74f9SMatthew G. Knepley   PetscFunctionBegin;
74352849c42SDave May   if (buf) {
744521f74f9SMatthew G. Knepley     ierr = PetscFree(*buf);CHKERRQ(ierr);
74552849c42SDave May     *buf = NULL;
74652849c42SDave May   }
7477fbf63aeSDave May   PetscFunctionReturn(0);
74852849c42SDave May }
74952849c42SDave May 
75077048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketFillPackedArray(DMSwarmDataBucket db,const PetscInt index,void *buf)
75152849c42SDave May {
7525c18a9d6SDave May   PetscInt       f;
75352849c42SDave May   void          *data, *data_p;
75452849c42SDave May   size_t         asize, offset;
755521f74f9SMatthew G. Knepley   PetscErrorCode ierr;
75652849c42SDave May 
757521f74f9SMatthew G. Knepley   PetscFunctionBegin;
75852849c42SDave May   offset = 0;
759521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
76077048351SPatrick Sanan     DMSwarmDataField df = db->field[f];
76152849c42SDave May 
76252849c42SDave May     asize = df->atomic_size;
76352849c42SDave May     data = (void*)( df->data);
76452849c42SDave May     data_p = (void*)( (char*)data + index*asize);
765521f74f9SMatthew G. Knepley     ierr = PetscMemcpy((void*)((char*)buf + offset), data_p, asize);CHKERRQ(ierr);
76652849c42SDave May     offset = offset + asize;
76752849c42SDave May   }
7687fbf63aeSDave May   PetscFunctionReturn(0);
76952849c42SDave May }
77052849c42SDave May 
77177048351SPatrick Sanan PetscErrorCode DMSwarmDataBucketInsertPackedArray(DMSwarmDataBucket db,const PetscInt idx,void *data)
77252849c42SDave May {
7735c18a9d6SDave May   PetscInt       f;
77452849c42SDave May   void           *data_p;
77552849c42SDave May   size_t         offset;
776dbe06d34SDave May   PetscErrorCode ierr;
77752849c42SDave May 
778521f74f9SMatthew G. Knepley   PetscFunctionBegin;
77952849c42SDave May   offset = 0;
780521f74f9SMatthew G. Knepley   for (f = 0; f < db->nfields; ++f) {
78177048351SPatrick Sanan     DMSwarmDataField df = db->field[f];
78252849c42SDave May 
78352849c42SDave May     data_p = (void*)( (char*)data + offset);
78477048351SPatrick Sanan     ierr = DMSwarmDataFieldInsertPoint(df, idx, (void*)data_p);CHKERRQ(ierr);
78552849c42SDave May     offset = offset + df->atomic_size;
78652849c42SDave May   }
7877fbf63aeSDave May   PetscFunctionReturn(0);
78852849c42SDave May }
789