xref: /petsc/src/dm/impls/swarm/data_bucket.c (revision 0cb17e37a3ec31518ab962587da9e1c07acd61d2)
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;
1052849c42SDave May 
1152849c42SDave May 	*val = PETSC_FALSE;
1252849c42SDave May 	for (i=0; i<N; i++) {
1352849c42SDave May 		if (strcmp( name, gfield[i]->name) == 0 ) {
1452849c42SDave May 			*val = PETSC_TRUE;
152eac95f8SDave May       PetscFunctionReturn(0);
1652849c42SDave May 		}
1752849c42SDave May 	}
182eac95f8SDave May   PetscFunctionReturn(0);
1952849c42SDave May }
2052849c42SDave May 
212635f519SDave May #undef __FUNCT__
222635f519SDave May #define __FUNCT__ "StringFindInList"
232eac95f8SDave May PetscErrorCode StringFindInList(const char name[],const PetscInt N,const DataField gfield[],PetscInt *index)
2452849c42SDave May {
255c18a9d6SDave May 	PetscInt i;
2652849c42SDave May 
2752849c42SDave May 	*index = -1;
2852849c42SDave May 	for (i=0; i<N; i++) {
2952849c42SDave May 		if (strcmp( name, gfield[i]->name ) == 0) {
3052849c42SDave May 			*index = i;
312eac95f8SDave May       PetscFunctionReturn(0);
3252849c42SDave May 		}
3352849c42SDave May 	}
342eac95f8SDave May   PetscFunctionReturn(0);
3552849c42SDave May }
3652849c42SDave May 
372eac95f8SDave May #undef __FUNCT__
382eac95f8SDave May #define __FUNCT__ "DataFieldCreate"
392eac95f8SDave May PetscErrorCode DataFieldCreate(const char registeration_function[],const char name[],const size_t size,const PetscInt L,DataField *DF)
4052849c42SDave May {
4152849c42SDave May 	DataField df;
4252849c42SDave May 
4352849c42SDave May 	df = malloc( sizeof(struct _p_DataField) );
4452849c42SDave May 	memset( df, 0, sizeof(struct _p_DataField) );
4552849c42SDave May 
4652849c42SDave May 
4752849c42SDave May 	asprintf( &df->registeration_function, "%s", registeration_function );
4852849c42SDave May 	asprintf( &df->name, "%s", name );
4952849c42SDave May 	df->atomic_size = size;
5052849c42SDave May 	df->L = L;
5152c3ed93SDave May   df->bs = 1;
5252849c42SDave May 
5352849c42SDave May 	df->data = malloc( size * L ); /* allocate something so we don't have to reallocate */
5452849c42SDave May 	memset( df->data, 0, size * L );
5552849c42SDave May 
5652849c42SDave May 	*DF = df;
572eac95f8SDave May   PetscFunctionReturn(0);
5852849c42SDave May }
5952849c42SDave May 
602eac95f8SDave May #undef __FUNCT__
612eac95f8SDave May #define __FUNCT__ "DataFieldDestroy"
622eac95f8SDave May PetscErrorCode DataFieldDestroy(DataField *DF)
6352849c42SDave May {
6452849c42SDave May 	DataField df = *DF;
6552849c42SDave May 
6652849c42SDave May 	free(df->registeration_function);
6752849c42SDave May 	free(df->name);
6852849c42SDave May 	free(df->data);
6952849c42SDave May 	free(df);
7052849c42SDave May 
7152849c42SDave May 	*DF = NULL;
722eac95f8SDave May   PetscFunctionReturn(0);
7352849c42SDave May }
7452849c42SDave May 
7552849c42SDave May /* data bucket */
762eac95f8SDave May #undef __FUNCT__
772eac95f8SDave May #define __FUNCT__ "DataBucketCreate"
782eac95f8SDave May PetscErrorCode DataBucketCreate(DataBucket *DB)
7952849c42SDave May {
8052849c42SDave May 	DataBucket db;
8152849c42SDave May 
8252849c42SDave May 
8352849c42SDave May 	db = malloc( sizeof(struct _p_DataBucket) );
8452849c42SDave May 	memset( db, 0, sizeof(struct _p_DataBucket) );
8552849c42SDave May 
8652849c42SDave May 	db->finalised = PETSC_FALSE;
8752849c42SDave May 
8852849c42SDave May 	/* create empty spaces for fields */
893454631fSDave May 	db->L         = -1;
9052849c42SDave May 	db->buffer    = 1;
9152849c42SDave May 	db->allocated = 1;
9252849c42SDave May 
9352849c42SDave May 	db->nfields   = 0;
9452849c42SDave May 	db->field     = malloc(sizeof(DataField));
9552849c42SDave May 
9652849c42SDave May 	*DB = db;
972eac95f8SDave May   PetscFunctionReturn(0);
9852849c42SDave May }
9952849c42SDave May 
1002eac95f8SDave May #undef __FUNCT__
1012eac95f8SDave May #define __FUNCT__ "DataBucketDestroy"
1022eac95f8SDave May PetscErrorCode DataBucketDestroy(DataBucket *DB)
10352849c42SDave May {
10452849c42SDave May 	DataBucket db = *DB;
1055c18a9d6SDave May 	PetscInt f;
106dbe06d34SDave May 	PetscErrorCode ierr;
10752849c42SDave May 
10852849c42SDave May 	/* release fields */
10952849c42SDave May 	for (f=0; f<db->nfields; f++) {
110dbe06d34SDave May 		ierr = DataFieldDestroy(&db->field[f]);CHKERRQ(ierr);
11152849c42SDave May 	}
11252849c42SDave May 
11352849c42SDave May 	/* this will catch the initially allocated objects in the event that no fields are registered */
11452849c42SDave May 	if (db->field != NULL) {
11552849c42SDave May 		free(db->field);
11652849c42SDave May 	}
11752849c42SDave May 
11852849c42SDave May 	free(db);
11952849c42SDave May 
12052849c42SDave May 	*DB = NULL;
1212eac95f8SDave May   PetscFunctionReturn(0);
12252849c42SDave May }
12352849c42SDave May 
1242eac95f8SDave May #undef __FUNCT__
125*0cb17e37SDave May #define __FUNCT__ "DataBucketQueryForActiveFields"
126*0cb17e37SDave May PetscErrorCode DataBucketQueryForActiveFields(DataBucket db,PetscBool *any_active_fields)
127*0cb17e37SDave May {
128*0cb17e37SDave May   PetscInt f;
129*0cb17e37SDave May   *any_active_fields = PETSC_FALSE;
130*0cb17e37SDave May   for (f=0; f<db->nfields; f++) {
131*0cb17e37SDave May     if (db->field[f]->active) {
132*0cb17e37SDave May       *any_active_fields = PETSC_TRUE;
133*0cb17e37SDave May       PetscFunctionReturn(0);
134*0cb17e37SDave May     }
135*0cb17e37SDave May   }
136*0cb17e37SDave May   PetscFunctionReturn(0);
137*0cb17e37SDave May }
138*0cb17e37SDave May 
139*0cb17e37SDave May #undef __FUNCT__
1402eac95f8SDave May #define __FUNCT__ "DataBucketRegisterField"
1412eac95f8SDave May PetscErrorCode DataBucketRegisterField(
14252849c42SDave May                               DataBucket db,
14352849c42SDave May                               const char registeration_function[],
14452849c42SDave May                               const char field_name[],
14552849c42SDave May                               size_t atomic_size, DataField *_gfield)
14652849c42SDave May {
14752849c42SDave May 	PetscBool val;
14852849c42SDave May 	DataField *field,fp;
149dbe06d34SDave May 	PetscErrorCode ierr;
15052849c42SDave May 
15152849c42SDave May 	/* check we haven't finalised the registration of fields */
15252849c42SDave May 	/*
15352849c42SDave May    if(db->finalised==PETSC_TRUE) {
15452849c42SDave May    printf("ERROR: DataBucketFinalize() has been called. Cannot register more fields\n");
15552849c42SDave May    ERROR();
15652849c42SDave May    }
15752849c42SDave May    */
15852849c42SDave May 
15952849c42SDave May 	/* check for repeated name */
1602635f519SDave May 	ierr = StringInList( field_name, db->nfields, (const DataField*)db->field, &val );CHKERRQ(ierr);
1612eac95f8SDave May 	if (val == PETSC_TRUE) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field %s already exists. Cannot add same field twice",field_name);
16252849c42SDave May 
16352849c42SDave May 	/* create new space for data */
16452849c42SDave May 	field = realloc( db->field,     sizeof(DataField)*(db->nfields+1));
16552849c42SDave May 	db->field     = field;
16652849c42SDave May 
16752849c42SDave May 	/* add field */
168dbe06d34SDave May 	ierr = DataFieldCreate( registeration_function, field_name, atomic_size, db->allocated, &fp );CHKERRQ(ierr);
16952849c42SDave May 	db->field[ db->nfields ] = fp;
17052849c42SDave May 
17152849c42SDave May 	db->nfields++;
17252849c42SDave May 
17352849c42SDave May 	if (_gfield != NULL) {
17452849c42SDave May 		*_gfield = fp;
17552849c42SDave May 	}
1762eac95f8SDave May   PetscFunctionReturn(0);
17752849c42SDave May }
17852849c42SDave May 
17952849c42SDave May /*
18052849c42SDave May  #define DataBucketRegisterField(db,name,size,k) {\
18152849c42SDave May  char *location;\
18252849c42SDave May  asprintf(&location,"Registered by %s() at line %d within file %s", __FUNCTION__, __LINE__, __FILE__);\
18352849c42SDave May  _DataBucketRegisterField( (db), location, (name), (size), (k) );\
18452849c42SDave May  free(location);\
18552849c42SDave May  }
18652849c42SDave May  */
18752849c42SDave May 
1882eac95f8SDave May #undef __FUNCT__
1892eac95f8SDave May #define __FUNCT__ "DataBucketGetDataFieldByName"
1902eac95f8SDave May PetscErrorCode DataBucketGetDataFieldByName(DataBucket db,const char name[],DataField *gfield)
19152849c42SDave May {
1922635f519SDave May   PetscErrorCode ierr;
1935c18a9d6SDave May 	PetscInt idx;
19452849c42SDave May 	PetscBool found;
19552849c42SDave May 
1962635f519SDave May 	ierr = StringInList(name,db->nfields,(const DataField*)db->field,&found);CHKERRQ(ierr);
1972eac95f8SDave May 	if (!found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot find DataField with name %s",name);
1982eac95f8SDave May 
1992635f519SDave May 	ierr = StringFindInList(name,db->nfields,(const DataField*)db->field,&idx);CHKERRQ(ierr);
20052849c42SDave May 
20152849c42SDave May 	*gfield = db->field[idx];
2022eac95f8SDave May   PetscFunctionReturn(0);
20352849c42SDave May }
20452849c42SDave May 
2057fbf63aeSDave May #undef __FUNCT__
2067fbf63aeSDave May #define __FUNCT__ "DataBucketQueryDataFieldByName"
2077fbf63aeSDave May PetscErrorCode DataBucketQueryDataFieldByName(DataBucket db,const char name[],PetscBool *found)
20852849c42SDave May {
2092635f519SDave May   PetscErrorCode ierr;
21052849c42SDave May 	*found = PETSC_FALSE;
2112635f519SDave May 	ierr = StringInList(name,db->nfields,(const DataField*)db->field,found);CHKERRQ(ierr);
2127fbf63aeSDave May   PetscFunctionReturn(0);
21352849c42SDave May }
21452849c42SDave May 
2157fbf63aeSDave May #undef __FUNCT__
2167fbf63aeSDave May #define __FUNCT__ "DataBucketFinalize"
2177fbf63aeSDave May PetscErrorCode DataBucketFinalize(DataBucket db)
21852849c42SDave May {
21952849c42SDave May 	db->finalised = PETSC_TRUE;
2207fbf63aeSDave May   PetscFunctionReturn(0);
22152849c42SDave May }
22252849c42SDave May 
2237fbf63aeSDave May #undef __FUNCT__
2247fbf63aeSDave May #define __FUNCT__ "DataFieldGetNumEntries"
2257fbf63aeSDave May PetscErrorCode DataFieldGetNumEntries(DataField df,PetscInt *sum)
22652849c42SDave May {
22752849c42SDave May 	*sum = df->L;
2287fbf63aeSDave May   PetscFunctionReturn(0);
22952849c42SDave May }
23052849c42SDave May 
2317fbf63aeSDave May #undef __FUNCT__
23252c3ed93SDave May #define __FUNCT__ "DataFieldSetBlockSize"
23352c3ed93SDave May PetscErrorCode DataFieldSetBlockSize(DataField df,PetscInt blocksize)
23452c3ed93SDave May {
23552c3ed93SDave May 	df->bs = blocksize;
23652c3ed93SDave May   PetscFunctionReturn(0);
23752c3ed93SDave May }
23852c3ed93SDave May 
23952c3ed93SDave May #undef __FUNCT__
2407fbf63aeSDave May #define __FUNCT__ "DataFieldSetSize"
2417fbf63aeSDave May PetscErrorCode DataFieldSetSize(DataField df,const PetscInt new_L)
24252849c42SDave May {
24352849c42SDave May 	void *tmp_data;
24452849c42SDave May 
245a233d522SDave May 	if (new_L <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot set size of DataField to be <= 0");
2467fbf63aeSDave May 
2477fbf63aeSDave May 	if (new_L == df->L) PetscFunctionReturn(0);
24852849c42SDave May 
24952849c42SDave May 	if (new_L > df->L) {
25052849c42SDave May 
25152849c42SDave May 		tmp_data = realloc( df->data, df->atomic_size * (new_L) );
25252849c42SDave May 		df->data = tmp_data;
25352849c42SDave May 
25452849c42SDave May 		/* init new contents */
25552849c42SDave May 		memset( ( ((char*)df->data)+df->L*df->atomic_size), 0, (new_L-df->L)*df->atomic_size );
25652849c42SDave May 
2577fbf63aeSDave May 	} else {
25852849c42SDave May 		/* reallocate pointer list, add +1 in case new_L = 0 */
25952849c42SDave May 		tmp_data = realloc( df->data, df->atomic_size * (new_L+1) );
26052849c42SDave May 		df->data = tmp_data;
26152849c42SDave May 	}
26252849c42SDave May 
26352849c42SDave May 	df->L = new_L;
2647fbf63aeSDave May   PetscFunctionReturn(0);
26552849c42SDave May }
26652849c42SDave May 
2677fbf63aeSDave May #undef __FUNCT__
2687fbf63aeSDave May #define __FUNCT__ "DataFieldZeroBlock"
2697fbf63aeSDave May PetscErrorCode DataFieldZeroBlock(DataField df,const PetscInt start,const PetscInt end)
27052849c42SDave May {
2717fbf63aeSDave May 	if (start > end) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot zero a block of entries if start(%D) > end(%D)",start,end);
2727fbf63aeSDave May 
2737fbf63aeSDave May 	if (start < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot zero a block of entries if start(%D) < 0",start);
2747fbf63aeSDave May 
275a233d522SDave 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);
27652849c42SDave May 
27752849c42SDave May 	memset( ( ((char*)df->data)+start*df->atomic_size), 0, (end-start)*df->atomic_size );
2787fbf63aeSDave May   PetscFunctionReturn(0);
27952849c42SDave May }
28052849c42SDave May 
28152849c42SDave May /*
28252849c42SDave May  A negative buffer value will simply be ignored and the old buffer value will be used.
28352849c42SDave May  */
2847fbf63aeSDave May #undef __FUNCT__
2857fbf63aeSDave May #define __FUNCT__ "DataBucketSetSizes"
2867fbf63aeSDave May PetscErrorCode DataBucketSetSizes(DataBucket db,const PetscInt L,const PetscInt buffer)
28752849c42SDave May {
2885c18a9d6SDave May 	PetscInt current_allocated,new_used,new_unused,new_buffer,new_allocated,f;
289*0cb17e37SDave May   PetscBool any_active_fields;
290dbe06d34SDave May   PetscErrorCode ierr;
29152849c42SDave May 
2927fbf63aeSDave May 	if (db->finalised == PETSC_FALSE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"You must call DataBucketFinalize() before DataBucketSetSizes()");
29352849c42SDave May 
294*0cb17e37SDave May   ierr = DataBucketQueryForActiveFields(db,&any_active_fields);CHKERRQ(ierr);
295*0cb17e37SDave 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");
296*0cb17e37SDave May 
29752849c42SDave May 	current_allocated = db->allocated;
29852849c42SDave May 
29952849c42SDave May 	new_used   = L;
30052849c42SDave May 	new_unused = current_allocated - new_used;
30152849c42SDave May 	new_buffer = db->buffer;
30252849c42SDave May 	if (buffer >= 0) { /* update the buffer value */
30352849c42SDave May 		new_buffer = buffer;
30452849c42SDave May 	}
30552849c42SDave May 	new_allocated = new_used + new_buffer;
30652849c42SDave May 
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 
31452849c42SDave May 		db->L         = new_used;
31552849c42SDave May 		db->buffer    = new_buffer;
31652849c42SDave May 		db->allocated = new_used + new_buffer;
31752849c42SDave May 	}
31852849c42SDave May 	else {
31952849c42SDave May 		if (new_unused > 2 * new_buffer) {
32052849c42SDave May 
32152849c42SDave May 			/* shrink array to new_used + new_buffer */
32252849c42SDave May 			for (f=0; f<db->nfields; f++) {
323dbe06d34SDave May 				ierr = DataFieldSetSize( db->field[f], new_allocated );CHKERRQ(ierr);
32452849c42SDave May 			}
32552849c42SDave May 
32652849c42SDave May 			db->L         = new_used;
32752849c42SDave May 			db->buffer    = new_buffer;
32852849c42SDave May 			db->allocated = new_used + new_buffer;
32952849c42SDave May 		}
33052849c42SDave May 		else {
33152849c42SDave May 			db->L      = new_used;
33252849c42SDave May 			db->buffer = new_buffer;
33352849c42SDave May 		}
33452849c42SDave May 	}
33552849c42SDave May 
33652849c42SDave May 	/* zero all entries from db->L to db->allocated */
33752849c42SDave May 	for (f=0; f<db->nfields; f++) {
33852849c42SDave May 		DataField field = db->field[f];
339dbe06d34SDave May 		ierr = DataFieldZeroBlock(field, db->L,db->allocated);CHKERRQ(ierr);
34052849c42SDave May 	}
3417fbf63aeSDave May   PetscFunctionReturn(0);
34252849c42SDave May }
34352849c42SDave May 
3447fbf63aeSDave May #undef __FUNCT__
3457fbf63aeSDave May #define __FUNCT__ "DataBucketSetInitialSizes"
3467fbf63aeSDave May PetscErrorCode DataBucketSetInitialSizes(DataBucket db,const PetscInt L,const PetscInt buffer)
34752849c42SDave May {
3485c18a9d6SDave May 	PetscInt f;
349dbe06d34SDave May   PetscErrorCode ierr;
350dbe06d34SDave May 
351dbe06d34SDave May 	ierr = DataBucketSetSizes(db,L,buffer);CHKERRQ(ierr);
35252849c42SDave May 
35352849c42SDave May 	for (f=0; f<db->nfields; f++) {
35452849c42SDave May 		DataField field = db->field[f];
355dbe06d34SDave May 		ierr = DataFieldZeroBlock(field,0,db->allocated);CHKERRQ(ierr);
35652849c42SDave May 	}
3577fbf63aeSDave May   PetscFunctionReturn(0);
35852849c42SDave May }
35952849c42SDave May 
3607fbf63aeSDave May #undef __FUNCT__
3617fbf63aeSDave May #define __FUNCT__ "DataBucketGetSizes"
3627fbf63aeSDave May PetscErrorCode DataBucketGetSizes(DataBucket db,PetscInt *L,PetscInt *buffer,PetscInt *allocated)
36352849c42SDave May {
36452849c42SDave May 	if (L) { *L = db->L; }
36552849c42SDave May 	if (buffer) { *buffer = db->buffer; }
36652849c42SDave May 	if (allocated) { *allocated = db->allocated; }
3677fbf63aeSDave May   PetscFunctionReturn(0);
36852849c42SDave May }
36952849c42SDave May 
3707fbf63aeSDave May #undef __FUNCT__
3717fbf63aeSDave May #define __FUNCT__ "DataBucketGetGlobalSizes"
3727fbf63aeSDave May PetscErrorCode DataBucketGetGlobalSizes(MPI_Comm comm,DataBucket db,PetscInt *L,PetscInt *buffer,PetscInt *allocated)
37352849c42SDave May {
3745c18a9d6SDave May 	PetscInt _L,_buffer,_allocated;
3755c18a9d6SDave May 	PetscInt ierr;
37652849c42SDave May 
3775c18a9d6SDave May 	_L = db->L;
3785c18a9d6SDave May 	_buffer = db->buffer;
3795c18a9d6SDave May 	_allocated = db->allocated;
38052849c42SDave May 
38133564166SDave May 	if (L) {         ierr = MPI_Allreduce(&_L,L,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); }
38233564166SDave May 	if (buffer) {    ierr = MPI_Allreduce(&_buffer,buffer,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); }
38333564166SDave May 	if (allocated) { ierr = MPI_Allreduce(&_allocated,allocated,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); }
3847fbf63aeSDave May   PetscFunctionReturn(0);
38552849c42SDave May }
38652849c42SDave May 
3877fbf63aeSDave May #undef __FUNCT__
38889884300SDave May #define __FUNCT__ "DataBucketGetDataFields"
3897fbf63aeSDave May PetscErrorCode DataBucketGetDataFields(DataBucket db,PetscInt *L,DataField *fields[])
39052849c42SDave May {
39152849c42SDave May 	if (L) {      *L      = db->nfields; }
39252849c42SDave May 	if (fields) { *fields = db->field; }
3937fbf63aeSDave May   PetscFunctionReturn(0);
39452849c42SDave May }
39552849c42SDave May 
3967fbf63aeSDave May #undef __FUNCT__
3977fbf63aeSDave May #define __FUNCT__ "DataFieldGetAccess"
3987fbf63aeSDave May PetscErrorCode DataFieldGetAccess(const DataField gfield)
39952849c42SDave May {
4007fbf63aeSDave May 	if (gfield->active) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is already active. You must call DataFieldRestoreAccess()",gfield->name);
4017fbf63aeSDave May 
40252849c42SDave May 	gfield->active = PETSC_TRUE;
4037fbf63aeSDave May   PetscFunctionReturn(0);
40452849c42SDave May }
40552849c42SDave May 
4067fbf63aeSDave May #undef __FUNCT__
4077fbf63aeSDave May #define __FUNCT__ "DataFieldAccessPoint"
4087fbf63aeSDave May PetscErrorCode DataFieldAccessPoint(const DataField gfield,const PetscInt pid,void **ctx_p)
40952849c42SDave May {
41052849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
41152849c42SDave May 	/* debug mode */
41284bcda08SDave May 	/* check point is valid */
4137fbf63aeSDave May 	if (pid < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
4147fbf63aeSDave May 	if (pid >= gfield->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",gfield->L);
41552849c42SDave May 
41684bcda08SDave 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);
41752849c42SDave May #endif
41852849c42SDave May 
41952849c42SDave May 	//*ctx_p  = (void*)( ((char*)gfield->data) + pid * gfield->atomic_size);
42052849c42SDave May 	*ctx_p = __DATATFIELD_point_access(gfield->data,pid,gfield->atomic_size);
4217fbf63aeSDave May   PetscFunctionReturn(0);
42252849c42SDave May }
42352849c42SDave May 
4247fbf63aeSDave May #undef __FUNCT__
4257fbf63aeSDave May #define __FUNCT__ "DataFieldAccessPointOffset"
4267fbf63aeSDave May PetscErrorCode DataFieldAccessPointOffset(const DataField gfield,const size_t offset,const PetscInt pid,void **ctx_p)
42752849c42SDave May {
42852849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
42952849c42SDave May 	/* debug mode */
43052849c42SDave May 
43184bcda08SDave May 	/* check point is valid */
4327fbf63aeSDave May 	/* if( offset < 0 ) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"offset must be >= 0");*//* Note compiler realizes this can never happen with an unsigned PetscInt */
4337fbf63aeSDave May 	if (offset >= gfield->atomic_size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"offset must be < %zu",gfield->atomic_size);
43452849c42SDave May 
43584bcda08SDave May 	/* check point is valid */
4367fbf63aeSDave May 	if (pid < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
437a233d522SDave May 	if (pid >= gfield->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",gfield->L);
43852849c42SDave May 
439a233d522SDave 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);
44052849c42SDave May #endif
44152849c42SDave May 
44252849c42SDave May 	*ctx_p = __DATATFIELD_point_access_offset(gfield->data,pid,gfield->atomic_size,offset);
4437fbf63aeSDave May   PetscFunctionReturn(0);
44452849c42SDave May }
44552849c42SDave May 
4467fbf63aeSDave May #undef __FUNCT__
44789884300SDave May #define __FUNCT__ "DataFieldRestoreAccess"
4487fbf63aeSDave May PetscErrorCode DataFieldRestoreAccess(DataField gfield)
44952849c42SDave May {
4507fbf63aeSDave May 	if (gfield->active == PETSC_FALSE) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is not active. You must call DataFieldGetAccess()", gfield->name );
4517fbf63aeSDave May 
45252849c42SDave May 	gfield->active = PETSC_FALSE;
4537fbf63aeSDave May   PetscFunctionReturn(0);
45452849c42SDave May }
45552849c42SDave May 
4567fbf63aeSDave May #undef __FUNCT__
4577fbf63aeSDave May #define __FUNCT__ "DataFieldVerifyAccess"
4587fbf63aeSDave May PetscErrorCode DataFieldVerifyAccess(const DataField gfield,const size_t size)
45952849c42SDave May {
46052849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
4617fbf63aeSDave May 	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.",
46252849c42SDave May            gfield->name, gfield->atomic_size, size );
46352849c42SDave May #endif
4647fbf63aeSDave May   PetscFunctionReturn(0);
46552849c42SDave May }
46652849c42SDave May 
4677fbf63aeSDave May #undef __FUNCT__
4687fbf63aeSDave May #define __FUNCT__ "DataFieldGetAtomicSize"
4697fbf63aeSDave May PetscErrorCode DataFieldGetAtomicSize(const DataField gfield,size_t *size)
47052849c42SDave May {
47152849c42SDave May   if (size) { *size = gfield->atomic_size; }
4727fbf63aeSDave May   PetscFunctionReturn(0);
47352849c42SDave May }
47452849c42SDave May 
4757fbf63aeSDave May #undef __FUNCT__
4767fbf63aeSDave May #define __FUNCT__ "DataFieldGetEntries"
4777fbf63aeSDave May PetscErrorCode DataFieldGetEntries(const DataField gfield,void **data)
47852849c42SDave May {
47952849c42SDave May   if (data) {
48052849c42SDave May     *data = gfield->data;
48152849c42SDave May   }
4827fbf63aeSDave May   PetscFunctionReturn(0);
48352849c42SDave May }
48452849c42SDave May 
4857fbf63aeSDave May #undef __FUNCT__
4867fbf63aeSDave May #define __FUNCT__ "DataFieldRestoreEntries"
4877fbf63aeSDave May PetscErrorCode DataFieldRestoreEntries(const DataField gfield,void **data)
48852849c42SDave May {
48952849c42SDave May   if (data) {
49052849c42SDave May     *data = NULL;
49152849c42SDave May   }
4927fbf63aeSDave May   PetscFunctionReturn(0);
49352849c42SDave May }
49452849c42SDave May 
49552849c42SDave May /* y = x */
4967fbf63aeSDave May #undef __FUNCT__
4977fbf63aeSDave May #define __FUNCT__ "DataBucketCopyPoint"
4987fbf63aeSDave May PetscErrorCode DataBucketCopyPoint(const DataBucket xb,const PetscInt pid_x,
4995c18a9d6SDave May                          const DataBucket yb,const PetscInt pid_y)
50052849c42SDave May {
5015c18a9d6SDave May 	PetscInt f;
502dbe06d34SDave May 	PetscErrorCode ierr;
503dbe06d34SDave May 
50452849c42SDave May 	for (f=0; f<xb->nfields; f++) {
50552849c42SDave May 		void *dest;
50652849c42SDave May 		void *src;
50752849c42SDave May 
508dbe06d34SDave May 		ierr = DataFieldGetAccess( xb->field[f] );CHKERRQ(ierr);
5096845f8f5SDave May 		if (xb != yb) { ierr = DataFieldGetAccess( yb->field[f] );CHKERRQ(ierr); }
51052849c42SDave May 
511dbe06d34SDave May 		ierr = DataFieldAccessPoint( xb->field[f],pid_x, &src );CHKERRQ(ierr);
512dbe06d34SDave May 		ierr = DataFieldAccessPoint( yb->field[f],pid_y, &dest );CHKERRQ(ierr);
51352849c42SDave May 
51452849c42SDave May 		memcpy( dest, src, xb->field[f]->atomic_size );
51552849c42SDave May 
516dbe06d34SDave May 		ierr = DataFieldRestoreAccess( xb->field[f] );CHKERRQ(ierr);
5176845f8f5SDave May 		if (xb != yb) { ierr = DataFieldRestoreAccess( yb->field[f] );CHKERRQ(ierr); }
51852849c42SDave May 	}
5197fbf63aeSDave May   PetscFunctionReturn(0);
52052849c42SDave May }
52152849c42SDave May 
5227fbf63aeSDave May #undef __FUNCT__
5237fbf63aeSDave May #define __FUNCT__ "DataBucketCreateFromSubset"
5247fbf63aeSDave May PetscErrorCode DataBucketCreateFromSubset(DataBucket DBIn,const PetscInt N,const PetscInt list[],DataBucket *DB)
52552849c42SDave May {
5265c18a9d6SDave May 	PetscInt nfields;
52752849c42SDave May 	DataField *fields;
52852849c42SDave May 	DataBucketCreate(DB);
5295c18a9d6SDave May 	PetscInt f,L,buffer,allocated,p;
530dbe06d34SDave May 	PetscErrorCode ierr;
53152849c42SDave May 
53252849c42SDave May 	/* copy contents of DBIn */
533dbe06d34SDave May 	ierr = DataBucketGetDataFields(DBIn,&nfields,&fields);CHKERRQ(ierr);
534dbe06d34SDave May 	ierr = DataBucketGetSizes(DBIn,&L,&buffer,&allocated);CHKERRQ(ierr);
53552849c42SDave May 
53652849c42SDave May 	for (f=0; f<nfields; f++) {
537dbe06d34SDave May 		ierr = DataBucketRegisterField(*DB,"DataBucketCreateFromSubset",fields[f]->name,fields[f]->atomic_size,NULL);CHKERRQ(ierr);
53852849c42SDave May 	}
539dbe06d34SDave May 	ierr = DataBucketFinalize(*DB);CHKERRQ(ierr);
54052849c42SDave May 
541dbe06d34SDave May 	ierr = DataBucketSetSizes(*DB,L,buffer);CHKERRQ(ierr);
54252849c42SDave May 
54352849c42SDave May 	/* now copy the desired guys from DBIn => DB */
54452849c42SDave May 	for (p=0; p<N; p++) {
545dbe06d34SDave May 		ierr = DataBucketCopyPoint(DBIn,list[p], *DB,p);CHKERRQ(ierr);
54652849c42SDave May 	}
5477fbf63aeSDave May   PetscFunctionReturn(0);
54852849c42SDave May }
54952849c42SDave May 
55052849c42SDave May // insert into an exisitng location
5517fbf63aeSDave May #undef __FUNCT__
5527fbf63aeSDave May #define __FUNCT__ "DataFieldInsertPoint"
5537fbf63aeSDave May PetscErrorCode DataFieldInsertPoint(const DataField field,const PetscInt index,const void *ctx)
55452849c42SDave May {
55552849c42SDave May 
55652849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
55784bcda08SDave May 	/* check point is valid */
558a233d522SDave May 	if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
559a233d522SDave May 	if (index >= field->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",field->L);
56052849c42SDave May #endif
56152849c42SDave May 
56252849c42SDave May   //	memcpy( (void*)((char*)field->data + index*field->atomic_size), ctx, field->atomic_size );
56352849c42SDave May 	memcpy( __DATATFIELD_point_access(field->data,index,field->atomic_size), ctx, field->atomic_size );
5647fbf63aeSDave May   PetscFunctionReturn(0);
56552849c42SDave May }
56652849c42SDave May 
56752849c42SDave May // remove data at index - replace with last point
568a233d522SDave May #undef __FUNCT__
569a233d522SDave May #define __FUNCT__ "DataBucketRemovePointAtIndex"
5707fbf63aeSDave May PetscErrorCode DataBucketRemovePointAtIndex(const DataBucket db,const PetscInt index)
57152849c42SDave May {
5725c18a9d6SDave May 	PetscInt f;
573*0cb17e37SDave May   PetscBool any_active_fields;
574dbe06d34SDave May 	PetscErrorCode ierr;
57552849c42SDave May 
57652849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
57784bcda08SDave May 	/* check point is valid */
578a233d522SDave May 	if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
579a233d522SDave May 	if (index >= db->allocated) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",db->L+db->buffer);
58052849c42SDave May #endif
58152849c42SDave May 
582*0cb17e37SDave May   ierr = DataBucketQueryForActiveFields(db,&any_active_fields);CHKERRQ(ierr);
583*0cb17e37SDave 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");
584*0cb17e37SDave May 
585a233d522SDave May 	if (index >= db->L) { /* this point is not in the list - no need to error, but I will anyway */
586a233d522SDave 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 );
58752849c42SDave May 	}
58852849c42SDave May 
589a233d522SDave May 	if (index != db->L-1) { /* not last point in list */
59052849c42SDave May 		for (f=0; f<db->nfields; f++) {
59152849c42SDave May 			DataField field = db->field[f];
59252849c42SDave May 
59352849c42SDave May 			/* copy then remove */
594dbe06d34SDave May 			ierr = DataFieldCopyPoint( db->L-1,field, index,field );CHKERRQ(ierr);
59552849c42SDave May 
59652849c42SDave May 			//DataFieldZeroPoint(field,index);
59752849c42SDave May 		}
59852849c42SDave May 	}
59952849c42SDave May 
60052849c42SDave May 	/* decrement size */
60152849c42SDave May 	/* this will zero out an crap at the end of the list */
602dbe06d34SDave May 	ierr = DataBucketRemovePoint(db);CHKERRQ(ierr);
6037fbf63aeSDave May   PetscFunctionReturn(0);
60452849c42SDave May }
60552849c42SDave May 
60652849c42SDave May /* copy x into y */
6077fbf63aeSDave May #undef __FUNCT__
6087fbf63aeSDave May #define __FUNCT__ "DataFieldCopyPoint"
6097fbf63aeSDave May PetscErrorCode DataFieldCopyPoint(const PetscInt pid_x,const DataField field_x,
6105c18a9d6SDave May                         const PetscInt pid_y,const DataField field_y )
61152849c42SDave May {
61252849c42SDave May 
61352849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
61484bcda08SDave May 	/* check point is valid */
615a233d522SDave May 	if (pid_x < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"(IN) index must be >= 0");
616a233d522SDave May 	if (pid_x >= field_x->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"(IN) index must be < %D",field_x->L);
61752849c42SDave May 
618a233d522SDave May 	if (pid_y < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"(OUT) index must be >= 0");
619a233d522SDave May 	if (pid_y >= field_y->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"(OUT) index must be < %D",field_y->L);
62052849c42SDave May 
62152849c42SDave May 	if( field_y->atomic_size != field_x->atomic_size ) {
622a233d522SDave May 		SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"atomic size must match");
62352849c42SDave May 	}
62452849c42SDave May #endif
62552849c42SDave May 	/*
62652849c42SDave May    memcpy( (void*)((char*)field_y->data + pid_y*field_y->atomic_size),
62752849c42SDave May    (void*)((char*)field_x->data + pid_x*field_x->atomic_size),
62852849c42SDave May    field_x->atomic_size );
62952849c42SDave May    */
63052849c42SDave May 	memcpy(		__DATATFIELD_point_access(field_y->data,pid_y,field_y->atomic_size),
63152849c42SDave May          __DATATFIELD_point_access(field_x->data,pid_x,field_x->atomic_size),
63252849c42SDave May          field_y->atomic_size );
6337fbf63aeSDave May   PetscFunctionReturn(0);
63452849c42SDave May }
63552849c42SDave May 
63652849c42SDave May 
63752849c42SDave May // zero only the datafield at this point
6387fbf63aeSDave May #undef __FUNCT__
6397fbf63aeSDave May #define __FUNCT__ "DataFieldZeroPoint"
6407fbf63aeSDave May PetscErrorCode DataFieldZeroPoint(const DataField field,const PetscInt index)
64152849c42SDave May {
64252849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD
64384bcda08SDave May 	/* check point is valid */
644a233d522SDave May 	if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
645a233d522SDave May 	if (index >= field->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",field->L);
64652849c42SDave May #endif
64752849c42SDave May 
64852849c42SDave May   //	memset( (void*)((char*)field->data + index*field->atomic_size), 0, field->atomic_size );
64952849c42SDave May 	memset( __DATATFIELD_point_access(field->data,index,field->atomic_size), 0, field->atomic_size );
6507fbf63aeSDave May   PetscFunctionReturn(0);
65152849c42SDave May }
65252849c42SDave May 
65352849c42SDave May // zero ALL data for this point
6547fbf63aeSDave May #undef __FUNCT__
6557fbf63aeSDave May #define __FUNCT__ "DataBucketZeroPoint"
6567fbf63aeSDave May PetscErrorCode DataBucketZeroPoint(const DataBucket db,const PetscInt index)
65752849c42SDave May {
6585c18a9d6SDave May 	PetscInt f;
659dbe06d34SDave May 	PetscErrorCode ierr;
66052849c42SDave May 
66184bcda08SDave May 	/* check point is valid */
662a233d522SDave May 	if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0");
663a233d522SDave May 	if (index >= db->allocated) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",db->allocated);
66452849c42SDave May 
66552849c42SDave May 	for (f=0; f<db->nfields; f++) {
66652849c42SDave May 		DataField field = db->field[f];
66752849c42SDave May 
668dbe06d34SDave May 		ierr = DataFieldZeroPoint(field,index);CHKERRQ(ierr);
66952849c42SDave May 	}
6707fbf63aeSDave May   PetscFunctionReturn(0);
67152849c42SDave May }
67252849c42SDave May 
67352849c42SDave May /* increment */
6747fbf63aeSDave May #undef __FUNCT__
6757fbf63aeSDave May #define __FUNCT__ "DataBucketAddPoint"
6767fbf63aeSDave May PetscErrorCode DataBucketAddPoint(DataBucket db)
67752849c42SDave May {
678dbe06d34SDave May 	PetscErrorCode ierr;
679dbe06d34SDave May 
680dbe06d34SDave May 	ierr = DataBucketSetSizes(db,db->L+1,-1);CHKERRQ(ierr);
6817fbf63aeSDave May   PetscFunctionReturn(0);
68252849c42SDave May }
68352849c42SDave May 
6847fbf63aeSDave May /* decrement */
6857fbf63aeSDave May #undef __FUNCT__
6867fbf63aeSDave May #define __FUNCT__ "DataBucketRemovePoint"
6877fbf63aeSDave May PetscErrorCode DataBucketRemovePoint(DataBucket db)
6887fbf63aeSDave May {
689dbe06d34SDave May 	PetscErrorCode ierr;
690dbe06d34SDave May 
691dbe06d34SDave May 	ierr = DataBucketSetSizes(db,db->L-1,-1);CHKERRQ(ierr);
6927fbf63aeSDave May   PetscFunctionReturn(0);
6937fbf63aeSDave May }
6947fbf63aeSDave May 
6957fbf63aeSDave May #undef __FUNCT__
6967fbf63aeSDave May #define __FUNCT__ "_DataFieldViewBinary"
6977fbf63aeSDave May PetscErrorCode _DataFieldViewBinary(DataField field,FILE *fp)
69852849c42SDave May {
69952849c42SDave May 	fprintf(fp,"<DataField>\n");
70052849c42SDave May 	fprintf(fp,"%d\n", field->L);
70152849c42SDave May 	fprintf(fp,"%zu\n",field->atomic_size);
70252849c42SDave May 	fprintf(fp,"%s\n", field->registeration_function);
70352849c42SDave May 	fprintf(fp,"%s\n", field->name);
70452849c42SDave May 
70552849c42SDave May 	fwrite(field->data, field->atomic_size, field->L, fp);
70652849c42SDave May   /*
70752849c42SDave May    printf("  ** wrote %zu bytes for DataField \"%s\" \n", field->atomic_size * field->L, field->name );
70852849c42SDave May    */
70952849c42SDave May 	fprintf(fp,"\n</DataField>\n");
7107fbf63aeSDave May   PetscFunctionReturn(0);
71152849c42SDave May }
71252849c42SDave May 
7137fbf63aeSDave May #undef __FUNCT__
7147fbf63aeSDave May #define __FUNCT__ "_DataBucketRegisterFieldFromFile"
7157fbf63aeSDave May PetscErrorCode _DataBucketRegisterFieldFromFile(FILE *fp,DataBucket db)
71652849c42SDave May {
71752849c42SDave May 	PetscBool val;
71852849c42SDave May 	DataField *field;
71952849c42SDave May 
72052849c42SDave May 	DataField gfield;
72152849c42SDave May 	char dummy[100];
72252849c42SDave May 	char registeration_function[5000];
72352849c42SDave May 	char field_name[5000];
7245c18a9d6SDave May 	PetscInt L;
72552849c42SDave May 	size_t atomic_size,strL;
726dbe06d34SDave May 	PetscErrorCode ierr;
72752849c42SDave May 
72852849c42SDave May 	/* check we haven't finalised the registration of fields */
72952849c42SDave May 	/*
73052849c42SDave May    if(db->finalised==PETSC_TRUE) {
73152849c42SDave May    printf("ERROR: DataBucketFinalize() has been called. Cannot register more fields\n");
73252849c42SDave May    ERROR();
73352849c42SDave May    }
73452849c42SDave May    */
73552849c42SDave May 
73652849c42SDave May 
73752849c42SDave May 	/* read file contents */
73852849c42SDave May 	fgets(dummy,99,fp); //printf("read(header): %s", dummy );
73952849c42SDave May 
74052849c42SDave May 	fscanf( fp, "%d\n",&L); //printf("read(L): %d\n", L);
74152849c42SDave May 
74252849c42SDave May 	fscanf( fp, "%zu\n",&atomic_size); //printf("read(size): %zu\n",atomic_size);
74352849c42SDave May 
74452849c42SDave May 	fgets(registeration_function,4999,fp); //printf("read(reg func): %s", registeration_function );
74552849c42SDave May 	strL = strlen(registeration_function);
74652849c42SDave May 	if (strL > 1) {
74752849c42SDave May 		registeration_function[strL-1] = 0;
74852849c42SDave May 	}
74952849c42SDave May 
75052849c42SDave May 	fgets(field_name,4999,fp); //printf("read(name): %s", field_name );
75152849c42SDave May 	strL = strlen(field_name);
75252849c42SDave May 	if (strL > 1) {
75352849c42SDave May 		field_name[strL-1] = 0;
75452849c42SDave May 	}
75552849c42SDave May 
7564b46c5e1SDave May #ifdef DATA_BUCKET_LOG
757b3a122caSDave May 	PetscPrintf(PETSC_COMM_SELF,"  ** read L=%D; atomic_size=%zu; reg_func=\"%s\"; name=\"%s\" \n", L,atomic_size,registeration_function,field_name);
75852849c42SDave May #endif
75952849c42SDave May 
76052849c42SDave May 
76152849c42SDave May 	/* check for repeated name */
7622635f519SDave May 	ierr = StringInList( field_name, db->nfields, (const DataField*)db->field, &val );CHKERRQ(ierr);
763a233d522SDave May 	if (val == PETSC_TRUE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot add same field twice");
76452849c42SDave May 
76552849c42SDave May 	/* create new space for data */
76652849c42SDave May 	field = realloc( db->field,     sizeof(DataField)*(db->nfields+1));
76752849c42SDave May 	db->field     = field;
76852849c42SDave May 
76952849c42SDave May 	/* add field */
770dbe06d34SDave May 	ierr = DataFieldCreate( registeration_function, field_name, atomic_size, L, &gfield );CHKERRQ(ierr);
77152849c42SDave May 
77252849c42SDave May 	/* copy contents of file */
77352849c42SDave May 	fread(gfield->data, gfield->atomic_size, gfield->L, fp);
7744b46c5e1SDave May #ifdef DATA_BUCKET_LOG
775b3a122caSDave May 	PetscPrintf(PETSC_COMM_SELF,"  ** read %zu bytes for DataField \"%s\" \n", gfield->atomic_size * gfield->L, field_name );
77652849c42SDave May #endif
77752849c42SDave May 	/* finish reading meta data */
77852849c42SDave May 	fgets(dummy,99,fp); //printf("read(header): %s", dummy );
77952849c42SDave May 	fgets(dummy,99,fp); //printf("read(header): %s", dummy );
78052849c42SDave May 
78152849c42SDave May 	db->field[ db->nfields ] = gfield;
78252849c42SDave May 
78352849c42SDave May 	db->nfields++;
7847fbf63aeSDave May   PetscFunctionReturn(0);
78552849c42SDave May }
78652849c42SDave May 
7877fbf63aeSDave May #undef __FUNCT__
7887fbf63aeSDave May #define __FUNCT__ "_DataBucketViewAscii_HeaderWrite_v00"
7897fbf63aeSDave May PetscErrorCode _DataBucketViewAscii_HeaderWrite_v00(FILE *fp)
79052849c42SDave May {
79152849c42SDave May 	fprintf(fp,"<DataBucketHeader>\n");
79252849c42SDave May 	fprintf(fp,"type=DataBucket\n");
79352849c42SDave May 	fprintf(fp,"format=ascii\n");
79452849c42SDave May 	fprintf(fp,"version=0.0\n");
79552849c42SDave May 	fprintf(fp,"options=\n");
79652849c42SDave May 	fprintf(fp,"</DataBucketHeader>\n");
7977fbf63aeSDave May   PetscFunctionReturn(0);
79852849c42SDave May }
7997fbf63aeSDave May 
8007fbf63aeSDave May #undef __FUNCT__
8017fbf63aeSDave May #define __FUNCT__ "_DataBucketViewAscii_HeaderRead_v00"
8027fbf63aeSDave May PetscErrorCode _DataBucketViewAscii_HeaderRead_v00(FILE *fp)
80352849c42SDave May {
80452849c42SDave May 	char dummy[100];
80552849c42SDave May 	size_t strL;
80652849c42SDave May 
80752849c42SDave May 	// header open
80852849c42SDave May 	fgets(dummy,99,fp); //printf("read(header): %s", dummy );
80952849c42SDave May 
81052849c42SDave May 	// type
81152849c42SDave May 	fgets(dummy,99,fp); //printf("read(header): %s", dummy );
81252849c42SDave May 	strL = strlen(dummy);
81352849c42SDave May 	if (strL > 1) { dummy[strL-1] = 0; }
81452849c42SDave May 	if (strcmp(dummy,"type=DataBucket") != 0) {
815a233d522SDave May 		SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Data file doesn't contain a DataBucket type");
81652849c42SDave May 	}
81752849c42SDave May 
81852849c42SDave May 	// format
81952849c42SDave May 	fgets(dummy,99,fp); //printf("read(header): %s", dummy );
82052849c42SDave May 
82152849c42SDave May 	// version
82252849c42SDave May 	fgets(dummy,99,fp); //printf("read(header): %s", dummy );
82352849c42SDave May 	strL = strlen(dummy);
82452849c42SDave May 	if (strL > 1) { dummy[strL-1] = 0; }
82552849c42SDave May 	if (strcmp(dummy,"version=0.0") != 0) {
826a233d522SDave May 		SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"DataBucket file must be parsed with version=0.0 : You tried %s", dummy);
82752849c42SDave May 	}
82852849c42SDave May 
82952849c42SDave May 	// options
83052849c42SDave May 	fgets(dummy,99,fp); //printf("read(header): %s", dummy );
83152849c42SDave May 	// header close
83252849c42SDave May 	fgets(dummy,99,fp); //printf("read(header): %s", dummy );
8337fbf63aeSDave May   PetscFunctionReturn(0);
83452849c42SDave May }
83552849c42SDave May 
8367fbf63aeSDave May #undef __FUNCT__
8377fbf63aeSDave May #define __FUNCT__ "_DataBucketLoadFromFileBinary_SEQ"
8387fbf63aeSDave May PetscErrorCode _DataBucketLoadFromFileBinary_SEQ(const char filename[],DataBucket *_db)
83952849c42SDave May {
84052849c42SDave May 	DataBucket db;
84152849c42SDave May 	FILE *fp;
8425c18a9d6SDave May 	PetscInt L,buffer,f,nfields;
843dbe06d34SDave May 	PetscErrorCode ierr;
84452849c42SDave May 
84552849c42SDave May 
8464b46c5e1SDave May #ifdef DATA_BUCKET_LOG
847b3a122caSDave May 	PetscPrintf(PETSC_COMM_SELF,"** DataBucketLoadFromFile **\n");
84852849c42SDave May #endif
84952849c42SDave May 
85052849c42SDave May 	/* open file */
85152849c42SDave May 	fp = fopen(filename,"rb");
85252849c42SDave May 	if (fp == NULL) {
853a233d522SDave May 		SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file with name %s", filename);
85452849c42SDave May 	}
85552849c42SDave May 
85652849c42SDave May 	/* read header */
857dbe06d34SDave May 	ierr = _DataBucketViewAscii_HeaderRead_v00(fp);CHKERRQ(ierr);
85852849c42SDave May 
85952849c42SDave May 	fscanf(fp,"%d\n%d\n%d\n",&L,&buffer,&nfields);
86052849c42SDave May 
861dbe06d34SDave May 	ierr = DataBucketCreate(&db);CHKERRQ(ierr);
86252849c42SDave May 
86352849c42SDave May 	for (f=0; f<nfields; f++) {
864dbe06d34SDave May 		ierr = _DataBucketRegisterFieldFromFile(fp,db);CHKERRQ(ierr);
86552849c42SDave May 	}
86652849c42SDave May 	fclose(fp);
86752849c42SDave May 
868dbe06d34SDave May 	ierr = DataBucketFinalize(db);CHKERRQ(ierr);
86952849c42SDave May 
87052849c42SDave May   /*
87152849c42SDave May    DataBucketSetSizes(db,L,buffer);
87252849c42SDave May    */
87352849c42SDave May 	db->L = L;
87452849c42SDave May 	db->buffer = buffer;
87552849c42SDave May 	db->allocated = L + buffer;
87652849c42SDave May 
87752849c42SDave May 	*_db = db;
8787fbf63aeSDave May   PetscFunctionReturn(0);
87952849c42SDave May }
88052849c42SDave May 
8817fbf63aeSDave May #undef __FUNCT__
8827fbf63aeSDave May #define __FUNCT__ "DataBucketLoadFromFile"
8837fbf63aeSDave May PetscErrorCode DataBucketLoadFromFile(MPI_Comm comm,const char filename[],DataBucketViewType type,DataBucket *db)
88452849c42SDave May {
8855c18a9d6SDave May 	PetscMPIInt nproc,rank;
886997fa542SDave May 	PetscErrorCode ierr;
88752849c42SDave May 
888997fa542SDave May 	ierr = MPI_Comm_size(comm,&nproc);CHKERRQ(ierr);
889997fa542SDave May 	ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
89052849c42SDave May 
8914b46c5e1SDave May #ifdef DATA_BUCKET_LOG
892b3a122caSDave May 	PetscPrintf(PETSC_COMM_SELF,"** DataBucketLoadFromFile **\n");
89352849c42SDave May #endif
89452849c42SDave May 	if (type == DATABUCKET_VIEW_STDOUT) {
89552849c42SDave May 
89652849c42SDave May 	} else if (type == DATABUCKET_VIEW_ASCII) {
897a233d522SDave May 		SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot be implemented as we don't know the underlying particle data structure");
89852849c42SDave May 	} else if (type == DATABUCKET_VIEW_BINARY) {
89952849c42SDave May 		if (nproc == 1) {
900dbe06d34SDave May 			ierr = _DataBucketLoadFromFileBinary_SEQ(filename,db);CHKERRQ(ierr);
90152849c42SDave May 		} else {
90252849c42SDave May 			char *name;
90352849c42SDave May 
90452849c42SDave May 			asprintf(&name,"%s_p%1.5d",filename, rank );
905dbe06d34SDave May 			ierr = _DataBucketLoadFromFileBinary_SEQ(name,db);CHKERRQ(ierr);
90652849c42SDave May 			free(name);
90752849c42SDave May 		}
90852849c42SDave May 	} else {
909a233d522SDave May 		SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer requested");
91052849c42SDave May 	}
9117fbf63aeSDave May   PetscFunctionReturn(0);
91252849c42SDave May }
91352849c42SDave May 
9147fbf63aeSDave May #undef __FUNCT__
9157fbf63aeSDave May #define __FUNCT__ "_DataBucketViewBinary"
9167fbf63aeSDave May PetscErrorCode _DataBucketViewBinary(DataBucket db,const char filename[])
91752849c42SDave May {
91852849c42SDave May 	FILE *fp = NULL;
9195c18a9d6SDave May 	PetscInt f;
920dbe06d34SDave May 	PetscErrorCode ierr;
92152849c42SDave May 
92252849c42SDave May 	fp = fopen(filename,"wb");
923a233d522SDave May 	if (fp == NULL) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot open file with name %s", filename);
92452849c42SDave May 
92552849c42SDave May 	/* db header */
926dbe06d34SDave May 	ierr =_DataBucketViewAscii_HeaderWrite_v00(fp);CHKERRQ(ierr);
92752849c42SDave May 
92852849c42SDave May 	/* meta-data */
92952849c42SDave May 	fprintf(fp,"%d\n%d\n%d\n", db->L,db->buffer,db->nfields);
93052849c42SDave May 
93152849c42SDave May 	for (f=0; f<db->nfields; f++) {
93252849c42SDave May     /* load datafields */
933dbe06d34SDave May 		ierr = _DataFieldViewBinary(db->field[f],fp);CHKERRQ(ierr);
93452849c42SDave May 	}
93552849c42SDave May 
93652849c42SDave May 	fclose(fp);
9377fbf63aeSDave May   PetscFunctionReturn(0);
93852849c42SDave May }
93952849c42SDave May 
9407fbf63aeSDave May #undef __FUNCT__
9417fbf63aeSDave May #define __FUNCT__ "DataBucketView_SEQ"
9427fbf63aeSDave May PetscErrorCode DataBucketView_SEQ(DataBucket db,const char filename[],DataBucketViewType type)
94352849c42SDave May {
944dbe06d34SDave May   PetscErrorCode ierr;
945dbe06d34SDave May 
94652849c42SDave May 	switch (type) {
94752849c42SDave May 		case DATABUCKET_VIEW_STDOUT:
94852849c42SDave May 		{
9495c18a9d6SDave May 			PetscInt f;
95052849c42SDave May 			double memory_usage_total = 0.0;
95152849c42SDave May 
952b3a122caSDave May 			PetscPrintf(PETSC_COMM_SELF,"DataBucketView(SEQ): (\"%s\")\n",filename);
953b3a122caSDave May 			PetscPrintf(PETSC_COMM_SELF,"  L                  = %D \n", db->L );
954b3a122caSDave May 			PetscPrintf(PETSC_COMM_SELF,"  buffer             = %D \n", db->buffer );
955b3a122caSDave May 			PetscPrintf(PETSC_COMM_SELF,"  allocated          = %D \n", db->allocated );
95652849c42SDave May 
957b3a122caSDave May 			PetscPrintf(PETSC_COMM_SELF,"  nfields registered = %D \n", db->nfields );
95852849c42SDave May 			for (f=0; f<db->nfields; f++) {
95952849c42SDave May 				double memory_usage_f = (double)(db->field[f]->atomic_size * db->allocated) * 1.0e-6;
96052849c42SDave May 
961b3a122caSDave May 				PetscPrintf(PETSC_COMM_SELF,"    [%3D]: field name  ==>> %30s : Mem. usage = %1.2e (MB) \n", f, db->field[f]->name, memory_usage_f  );
96252c3ed93SDave May         PetscPrintf(PETSC_COMM_SELF,"           blocksize          = %D \n", db->field[f]->bs );
96352c3ed93SDave May         if (db->field[f]->bs != 1) {
964e78fc626SDave May           PetscPrintf(PETSC_COMM_SELF,"           atomic size        = %zu [full block, bs=%D]\n", db->field[f]->atomic_size,db->field[f]->bs );
96552c3ed93SDave May           PetscPrintf(PETSC_COMM_SELF,"           atomic size/item   = %zu \n", db->field[f]->atomic_size/db->field[f]->bs );
96652c3ed93SDave May         } else {
96752c3ed93SDave May           PetscPrintf(PETSC_COMM_SELF,"           atomic size        = %zu \n", db->field[f]->atomic_size );
96852c3ed93SDave May         }
96952849c42SDave May 				memory_usage_total += memory_usage_f;
97052849c42SDave May 			}
971b3a122caSDave May 			PetscPrintf(PETSC_COMM_SELF,"  Total mem. usage                                                      = %1.2e (MB) \n", memory_usage_total );
97252849c42SDave May 		}
97352849c42SDave May 			break;
97452849c42SDave May 
97552849c42SDave May 		case DATABUCKET_VIEW_ASCII:
97652849c42SDave May 		{
977a233d522SDave May 			SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot be implemented as we don't know the underlying particle data structure");
97852849c42SDave May 		}
97952849c42SDave May 			break;
98052849c42SDave May 
98152849c42SDave May 		case DATABUCKET_VIEW_BINARY:
98252849c42SDave May 		{
983dbe06d34SDave May 			ierr = _DataBucketViewBinary(db,filename);CHKERRQ(ierr);
98452849c42SDave May 		}
98552849c42SDave May 			break;
98652849c42SDave May 
98752849c42SDave May 		case DATABUCKET_VIEW_HDF5:
98852849c42SDave May 		{
989a233d522SDave May 			SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No HDF5 support");
99052849c42SDave May 		}
99152849c42SDave May 			break;
99252849c42SDave May 
99352849c42SDave May 		default:
994a233d522SDave May 			SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer method requested");
99552849c42SDave May 			break;
99652849c42SDave May 	}
9977fbf63aeSDave May   PetscFunctionReturn(0);
99852849c42SDave May }
99952849c42SDave May 
10007fbf63aeSDave May #undef __FUNCT__
10017fbf63aeSDave May #define __FUNCT__ "DataBucketView_MPI"
10027fbf63aeSDave May PetscErrorCode DataBucketView_MPI(MPI_Comm comm,DataBucket db,const char filename[],DataBucketViewType type)
100352849c42SDave May {
1004997fa542SDave May   PetscErrorCode ierr;
1005997fa542SDave May 
100652849c42SDave May 	switch (type) {
100752849c42SDave May 		case DATABUCKET_VIEW_STDOUT:
100852849c42SDave May 		{
10095c18a9d6SDave May 			PetscInt f;
10105c18a9d6SDave May 			PetscInt L,buffer,allocated;
101152849c42SDave May 			double memory_usage_total,memory_usage_total_local = 0.0;
10125c18a9d6SDave May 			PetscMPIInt rank;
101352849c42SDave May 
1014997fa542SDave May 			ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
101552849c42SDave May 
1016dbe06d34SDave May 			ierr = DataBucketGetGlobalSizes(comm,db,&L,&buffer,&allocated);CHKERRQ(ierr);
101752849c42SDave May 
101852849c42SDave May 			for (f=0; f<db->nfields; f++) {
101952849c42SDave May 				double memory_usage_f = (double)(db->field[f]->atomic_size * db->allocated) * 1.0e-6;
102052849c42SDave May 
102152849c42SDave May 				memory_usage_total_local += memory_usage_f;
102252849c42SDave May 			}
1023dbe06d34SDave May 			ierr = MPI_Allreduce(&memory_usage_total_local,&memory_usage_total,1,MPI_DOUBLE,MPI_SUM,comm);CHKERRQ(ierr);
102452849c42SDave May 
102552849c42SDave May 			if (rank == 0) {
10265c18a9d6SDave May 				PetscPrintf(comm,"DataBucketView(MPI): (\"%s\")\n",filename);
10275c18a9d6SDave May 				PetscPrintf(comm,"  L                  = %D \n", L );
10285c18a9d6SDave May 				PetscPrintf(comm,"  buffer (max)       = %D \n", buffer );
10295c18a9d6SDave May 				PetscPrintf(comm,"  allocated          = %D \n", allocated );
103052849c42SDave May 
10315c18a9d6SDave May 				PetscPrintf(comm,"  nfields registered = %D \n", db->nfields );
103252849c42SDave May 				for (f=0; f<db->nfields; f++) {
103352849c42SDave May 					double memory_usage_f = (double)(db->field[f]->atomic_size * db->allocated) * 1.0e-6;
103452849c42SDave May 
1035b3a122caSDave May 					PetscPrintf(PETSC_COMM_SELF,"    [%3D]: field name  ==>> %30s : Mem. usage = %1.2e (MB) : rank0\n", f, db->field[f]->name, memory_usage_f  );
103652849c42SDave May 				}
103752849c42SDave May 
1038b3a122caSDave May 				PetscPrintf(PETSC_COMM_SELF,"  Total mem. usage                                                      = %1.2e (MB) : collective\n", memory_usage_total );
103952849c42SDave May 			}
104052849c42SDave May 
104152849c42SDave May 		}
104252849c42SDave May 			break;
104352849c42SDave May 
104452849c42SDave May 		case DATABUCKET_VIEW_ASCII:
104552849c42SDave May 		{
1046a233d522SDave May 			SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot be implemented as we don't know the underlying data structure");
104752849c42SDave May 		}
104852849c42SDave May 			break;
104952849c42SDave May 
105052849c42SDave May 		case DATABUCKET_VIEW_BINARY:
105152849c42SDave May 		{
105252849c42SDave May 			char *name;
10535c18a9d6SDave May 			PetscMPIInt rank;
105452849c42SDave May 
105552849c42SDave May 			/* create correct extension */
1056997fa542SDave May 			ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
105752849c42SDave May 			asprintf(&name,"%s_p%1.5d",filename, rank );
105852849c42SDave May 
1059dbe06d34SDave May 			ierr = _DataBucketViewBinary(db,name);CHKERRQ(ierr);
106052849c42SDave May 
106152849c42SDave May 			free(name);
106252849c42SDave May 		}
106352849c42SDave May 			break;
106452849c42SDave May 
106552849c42SDave May 		case DATABUCKET_VIEW_HDF5:
106652849c42SDave May 		{
1067a233d522SDave May 			SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for HDF5");
106852849c42SDave May 		}
106952849c42SDave May 			break;
107052849c42SDave May 
107152849c42SDave May 		default:
1072a233d522SDave May 			SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer method requested");
107352849c42SDave May 			break;
107452849c42SDave May 	}
10757fbf63aeSDave May   PetscFunctionReturn(0);
107652849c42SDave May }
107752849c42SDave May 
10787fbf63aeSDave May #undef __FUNCT__
10797fbf63aeSDave May #define __FUNCT__ "DataBucketView"
10807fbf63aeSDave May PetscErrorCode DataBucketView(MPI_Comm comm,DataBucket db,const char filename[],DataBucketViewType type)
108152849c42SDave May {
10825c18a9d6SDave May 	PetscMPIInt nproc;
1083997fa542SDave May   PetscErrorCode ierr;
108452849c42SDave May 
1085997fa542SDave May 	ierr = MPI_Comm_size(comm,&nproc);CHKERRQ(ierr);
108652849c42SDave May 	if (nproc == 1) {
1087dbe06d34SDave May 		ierr =DataBucketView_SEQ(db,filename,type);CHKERRQ(ierr);
108852849c42SDave May 	} else {
1089dbe06d34SDave May 		ierr = DataBucketView_MPI(comm,db,filename,type);CHKERRQ(ierr);
109052849c42SDave May 	}
10917fbf63aeSDave May   PetscFunctionReturn(0);
109252849c42SDave May }
109352849c42SDave May 
10947fbf63aeSDave May #undef __FUNCT__
10957fbf63aeSDave May #define __FUNCT__ "DataBucketDuplicateFields"
10967fbf63aeSDave May PetscErrorCode DataBucketDuplicateFields(DataBucket dbA,DataBucket *dbB)
109752849c42SDave May {
109852849c42SDave May 	DataBucket db2;
10995c18a9d6SDave May 	PetscInt f;
1100dbe06d34SDave May 	PetscErrorCode ierr;
110152849c42SDave May 
1102dbe06d34SDave May 	ierr = DataBucketCreate(&db2);CHKERRQ(ierr);
110352849c42SDave May 
110452849c42SDave May 	/* copy contents from dbA into db2 */
110552849c42SDave May 	for (f=0; f<dbA->nfields; f++) {
110652849c42SDave May 		DataField field;
110752849c42SDave May 		size_t    atomic_size;
110852849c42SDave May 		char      *name;
110952849c42SDave May 
111052849c42SDave May 		field = dbA->field[f];
111152849c42SDave May 
111252849c42SDave May 		atomic_size = field->atomic_size;
111352849c42SDave May 		name        = field->name;
111452849c42SDave May 
1115dbe06d34SDave May 		ierr = DataBucketRegisterField(db2,"DataBucketDuplicateFields",name,atomic_size,NULL);CHKERRQ(ierr);
111652849c42SDave May 	}
1117dbe06d34SDave May 	ierr = DataBucketFinalize(db2);CHKERRQ(ierr);
1118dbe06d34SDave May 	ierr = DataBucketSetInitialSizes(db2,0,1000);CHKERRQ(ierr);
111952849c42SDave May 
112052849c42SDave May 	/* set pointer */
112152849c42SDave May 	*dbB = db2;
11227fbf63aeSDave May   PetscFunctionReturn(0);
112352849c42SDave May }
112452849c42SDave May 
112552849c42SDave May /*
112652849c42SDave May  Insert points from db2 into db1
112752849c42SDave May  db1 <<== db2
112852849c42SDave May  */
11297fbf63aeSDave May #undef __FUNCT__
11307fbf63aeSDave May #define __FUNCT__ "DataBucketInsertValues"
11317fbf63aeSDave May PetscErrorCode DataBucketInsertValues(DataBucket db1,DataBucket db2)
113252849c42SDave May {
11335c18a9d6SDave May 	PetscInt n_mp_points1,n_mp_points2;
11345c18a9d6SDave May 	PetscInt n_mp_points1_new,p;
1135dbe06d34SDave May 	PetscErrorCode ierr;
113652849c42SDave May 
1137dbe06d34SDave May 	ierr = DataBucketGetSizes(db1,&n_mp_points1,0,0);CHKERRQ(ierr);
1138dbe06d34SDave May 	ierr = DataBucketGetSizes(db2,&n_mp_points2,0,0);CHKERRQ(ierr);
113952849c42SDave May 
114052849c42SDave May 	n_mp_points1_new = n_mp_points1 + n_mp_points2;
1141dbe06d34SDave May 	ierr = DataBucketSetSizes(db1,n_mp_points1_new,-1);CHKERRQ(ierr);
114252849c42SDave May 
114352849c42SDave May 	for (p=0; p<n_mp_points2; p++) {
114452849c42SDave May 		// db1 <<== db2 //
1145dbe06d34SDave May 		ierr =DataBucketCopyPoint( db2,p, db1,(n_mp_points1 + p) );CHKERRQ(ierr);
114652849c42SDave May 	}
11477fbf63aeSDave May   PetscFunctionReturn(0);
114852849c42SDave May }
114952849c42SDave May 
115052849c42SDave May /* helpers for parallel send/recv */
11517fbf63aeSDave May #undef __FUNCT__
11527fbf63aeSDave May #define __FUNCT__ "DataBucketCreatePackedArray"
11537fbf63aeSDave May PetscErrorCode DataBucketCreatePackedArray(DataBucket db,size_t *bytes,void **buf)
115452849c42SDave May {
11555c18a9d6SDave May   PetscInt       f;
115652849c42SDave May   size_t    sizeof_marker_contents;
115752849c42SDave May   void      *buffer;
115852849c42SDave May 
115952849c42SDave May   sizeof_marker_contents = 0;
116052849c42SDave May   for (f=0; f<db->nfields; f++) {
116152849c42SDave May     DataField df = db->field[f];
116252849c42SDave May 
116352849c42SDave May     sizeof_marker_contents += df->atomic_size;
116452849c42SDave May   }
116552849c42SDave May 
116652849c42SDave May   buffer = malloc(sizeof_marker_contents);
116752849c42SDave May   memset(buffer,0,sizeof_marker_contents);
116852849c42SDave May 
116952849c42SDave May   if (bytes) { *bytes = sizeof_marker_contents; }
117052849c42SDave May   if (buf)   { *buf   = buffer; }
11717fbf63aeSDave May   PetscFunctionReturn(0);
117252849c42SDave May }
117352849c42SDave May 
11747fbf63aeSDave May #undef __FUNCT__
11757fbf63aeSDave May #define __FUNCT__ "DataBucketDestroyPackedArray"
11767fbf63aeSDave May PetscErrorCode DataBucketDestroyPackedArray(DataBucket db,void **buf)
117752849c42SDave May {
117852849c42SDave May   if (buf) {
117952849c42SDave May     free(*buf);
118052849c42SDave May     *buf = NULL;
118152849c42SDave May   }
11827fbf63aeSDave May   PetscFunctionReturn(0);
118352849c42SDave May }
118452849c42SDave May 
11857fbf63aeSDave May #undef __FUNCT__
11867fbf63aeSDave May #define __FUNCT__ "DataBucketFillPackedArray"
11877fbf63aeSDave May PetscErrorCode DataBucketFillPackedArray(DataBucket db,const PetscInt index,void *buf)
118852849c42SDave May {
11895c18a9d6SDave May   PetscInt    f;
119052849c42SDave May   void   *data,*data_p;
119152849c42SDave May   size_t asize,offset;
119252849c42SDave May 
119352849c42SDave May   offset = 0;
119452849c42SDave May   for (f=0; f<db->nfields; f++) {
119552849c42SDave May     DataField df = db->field[f];
119652849c42SDave May 
119752849c42SDave May     asize = df->atomic_size;
119852849c42SDave May 
119952849c42SDave May     data = (void*)( df->data );
120052849c42SDave May     data_p = (void*)( (char*)data + index*asize );
120152849c42SDave May 
120252849c42SDave May     memcpy( (void*)((char*)buf + offset),  data_p,  asize);
120352849c42SDave May     offset = offset + asize;
120452849c42SDave May   }
12057fbf63aeSDave May   PetscFunctionReturn(0);
120652849c42SDave May }
120752849c42SDave May 
12087fbf63aeSDave May #undef __FUNCT__
12097fbf63aeSDave May #define __FUNCT__ "DataBucketInsertPackedArray"
12107fbf63aeSDave May PetscErrorCode DataBucketInsertPackedArray(DataBucket db,const PetscInt idx,void *data)
121152849c42SDave May {
12125c18a9d6SDave May   PetscInt f;
121352849c42SDave May   void *data_p;
121452849c42SDave May   size_t offset;
1215dbe06d34SDave May 	PetscErrorCode ierr;
121652849c42SDave May 
121752849c42SDave May   offset = 0;
121852849c42SDave May   for (f=0; f<db->nfields; f++) {
121952849c42SDave May     DataField df = db->field[f];
122052849c42SDave May 
122152849c42SDave May     data_p = (void*)( (char*)data + offset );
122252849c42SDave May 
1223dbe06d34SDave May     ierr = DataFieldInsertPoint(df, idx, (void*)data_p );CHKERRQ(ierr);
122452849c42SDave May     offset = offset + df->atomic_size;
122552849c42SDave May   }
12267fbf63aeSDave May   PetscFunctionReturn(0);
122752849c42SDave May }
1228