xref: /petsc/src/dm/impls/swarm/swarm.c (revision 3454631f4aaa15891cb2714934d2ee90b7996f8c)
1 
2 #define PETSCDM_DLL
3 #include <petsc/private/dmswarmimpl.h>    /*I   "petscdmswarm.h"   I*/
4 #include "data_bucket.h"
5 
6 //typedef PetscErrorCode (*swarm_project)(DM,DM,Vec) DMSwarmProjectMethod; /* swarm, geometry, result */
7 
8 //typedef enum { PROJECT_DMDA_AQ1=0, PROJECT_DMDA_P0 } DMSwarmDMDAProjectionType;
9 
10 #if 0
11 
12 /* Defines what the local space will be */
13 PetscErrorCode DMSwarmSetOverlap(void)
14 {
15 
16   PetscFunctionReturn(0);
17 }
18 
19 
20 /* coordinates */
21 /*
22 DMGetCoordinateDM returns self
23 DMGetCoordinates and DMGetCoordinatesLocal return same thing
24 Local view could be used to define overlapping information
25 */
26 
27 #endif
28 
29 #undef __FUNCT__
30 #define __FUNCT__ "DMSwarmVectorDefineField"
31 PETSC_EXTERN PetscErrorCode DMSwarmVectorDefineField(DM dm,const char fieldname[])
32 {
33   DM_Swarm *swarm = (DM_Swarm*)dm->data;
34   PetscErrorCode ierr;
35   PetscInt bs,n;
36   PetscScalar *array;
37   PetscDataType type;
38 
39   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
40   ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr);
41   ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
42 
43   /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */
44   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL");
45 
46   PetscSNPrintf(swarm->vec_field_name,PETSC_MAX_PATH_LEN-1,"%s",fieldname);
47   swarm->vec_field_set = PETSC_TRUE;
48   swarm->vec_field_bs = 1;//bs;
49   swarm->vec_field_nlocal = n;
50 
51   PetscFunctionReturn(0);
52 }
53 
54 /* requires DMSwarmDefineFieldVector has been called */
55 #undef __FUNCT__
56 #define __FUNCT__ "DMCreateGlobalVector_Swarm"
57 PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec)
58 {
59   DM_Swarm *swarm = (DM_Swarm*)dm->data;
60   PetscErrorCode ierr;
61   Vec x;
62   char name[PETSC_MAX_PATH_LEN];
63 
64   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
65   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
66   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);
67   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr);
68   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
69   ierr = VecSetSizes(x,swarm->vec_field_nlocal,PETSC_DETERMINE);CHKERRQ(ierr);
70   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
71   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
72   *vec = x;
73 
74   PetscFunctionReturn(0);
75 }
76 
77 /* requires DMSwarmDefineFieldVector has been called */
78 #undef __FUNCT__
79 #define __FUNCT__ "DMCreateLocalVector_Swarm"
80 PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec)
81 {
82   DM_Swarm *swarm = (DM_Swarm*)dm->data;
83   PetscErrorCode ierr;
84   Vec x;
85   char name[PETSC_MAX_PATH_LEN];
86 
87   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
88   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
89   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);
90   ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr);
91   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
92   ierr = VecSetSizes(x,swarm->vec_field_nlocal,swarm->vec_field_nlocal);CHKERRQ(ierr);
93   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
94   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
95   *vec = x;
96 
97   PetscFunctionReturn(0);
98 }
99 
100 #undef __FUNCT__
101 #define __FUNCT__ "DMSwarmCreateGlobalVectorFromField"
102 PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
103 {
104   DM_Swarm *swarm = (DM_Swarm*)dm->data;
105   PetscErrorCode ierr;
106   PetscInt bs,n;
107   PetscScalar *array;
108   Vec x;
109   PetscDataType type;
110   char name[PETSC_MAX_PATH_LEN];
111   PetscMPIInt commsize;
112 
113   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
114   ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr);
115   ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
116 
117   /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */
118   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL");
119 
120   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&commsize);CHKERRQ(ierr);
121   if (commsize == 1) {
122     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)dm),1,n,array,&x);CHKERRQ(ierr);
123   } else {
124     ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)dm),1,n,PETSC_DETERMINE,array,&x);CHKERRQ(ierr);
125   }
126   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarm_VecFieldInPlace_%s",fieldname);
127   ierr = PetscObjectComposeFunction((PetscObject)x,name,DMSwarmDestroyGlobalVectorFromField);CHKERRQ(ierr);
128 
129   /* Set guard */
130 
131   *vec = x;
132   PetscFunctionReturn(0);
133 }
134 
135 #undef __FUNCT__
136 #define __FUNCT__ "DMSwarmDestroyGlobalVectorFromField"
137 PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
138 {
139   DM_Swarm *swarm = (DM_Swarm*)dm->data;
140   PetscErrorCode ierr;
141   DataField gfield;
142   char name[PETSC_MAX_PATH_LEN];
143   void (*fptr)(void);
144 
145   /* get data field */
146   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
147 
148   /* check vector is an inplace array */
149   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarm_VecFieldInPlace_%s",fieldname);
150   ierr = PetscObjectQueryFunction((PetscObject)(*vec),name,&fptr);CHKERRQ(ierr);
151   if (!fptr) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Vector being destroyed was not created from DMSwarm field(%s)",fieldname);
152 
153   /* restore data field */
154   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
155 
156   ierr = VecDestroy(vec);CHKERRQ(ierr);
157 
158   PetscFunctionReturn(0);
159 }
160 
161 /*
162 PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec)
163 {
164   PetscFunctionReturn(0);
165 }
166 
167 PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec)
168 {
169   PetscFunctionReturn(0);
170 }
171 */
172 
173 #undef __FUNCT__
174 #define __FUNCT__ "DMSwarmInitializeFieldRegister"
175 PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm)
176 {
177   DM_Swarm *swarm = (DM_Swarm*)dm->data;
178   PetscErrorCode ierr;
179 
180   swarm->field_registration_initialized = PETSC_TRUE;
181 
182   ierr = DMSwarmRegisterPetscDatatypeField(dm,"DMSwarm_pid",1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */
183   ierr = DMSwarmRegisterPetscDatatypeField(dm,"DMSwarm_rank",1,PETSC_INT);CHKERRQ(ierr); /* used for communication */
184 
185   PetscFunctionReturn(0);
186 }
187 
188 #undef __FUNCT__
189 #define __FUNCT__ "DMSwarmFinalizeFieldRegister"
190 PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm)
191 {
192   DM_Swarm *swarm = (DM_Swarm*)dm->data;
193   PetscErrorCode ierr;
194 
195   swarm->field_registration_finalized = PETSC_TRUE;
196   ierr = DataBucketFinalize(swarm->db);CHKERRQ(ierr);
197   PetscFunctionReturn(0);
198 }
199 
200 #undef __FUNCT__
201 #define __FUNCT__ "DMSwarmSetLocalSizes"
202 PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer)
203 {
204   DM_Swarm *swarm = (DM_Swarm*)dm->data;
205   PetscErrorCode ierr;
206 
207   ierr = DataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr);
208 
209   PetscFunctionReturn(0);
210 }
211 
212 #undef __FUNCT__
213 #define __FUNCT__ "DMSwarmRegisterPetscDatatypeField"
214 PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
215 {
216   PetscErrorCode ierr;
217   DM_Swarm *swarm = (DM_Swarm*)dm->data;
218   size_t size;
219 
220   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
221   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
222 
223   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
224   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
225   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
226   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
227   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
228 
229   switch (type) {
230     case PETSC_CHAR:
231       size = sizeof(PetscChar);
232       break;
233     case PETSC_SHORT:
234       size = sizeof(PetscShort);
235       break;
236     case PETSC_INT:
237       size = sizeof(PetscInt);
238       break;
239     case PETSC_LONG:
240       size = sizeof(Petsc64bitInt);
241       break;
242     case PETSC_FLOAT:
243       size = sizeof(PetscFloat);
244       break;
245     case PETSC_DOUBLE:
246       size = sizeof(PetscReal);
247       break;
248 
249     default:
250       SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
251       break;
252   }
253 
254   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
255 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,size,NULL);CHKERRQ(ierr);
256   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
257 
258   PetscFunctionReturn(0);
259 }
260 
261 #undef __FUNCT__
262 #define __FUNCT__ "DMSwarmRegisterUserStructField"
263 PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
264 {
265   PetscErrorCode ierr;
266   DM_Swarm *swarm = (DM_Swarm*)dm->data;
267 
268 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
269   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
270 
271   PetscFunctionReturn(0);
272 }
273 
274 #undef __FUNCT__
275 #define __FUNCT__ "DMSwarmRegisterUserDatatypeField"
276 PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size)
277 {
278   DM_Swarm *swarm = (DM_Swarm*)dm->data;
279   PetscErrorCode ierr;
280 
281 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,size,NULL);CHKERRQ(ierr);
282   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
283 
284   PetscFunctionReturn(0);
285 }
286 
287 #undef __FUNCT__
288 #define __FUNCT__ "DMSwarmGetField"
289 PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
290 {
291   DM_Swarm *swarm = (DM_Swarm*)dm->data;
292   DataField gfield;
293   PetscErrorCode ierr;
294 
295   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
296 
297   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
298   ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr);
299   ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr);
300   if (blocksize) {}
301   if (type) { *type = gfield->petsc_type; }
302 
303   PetscFunctionReturn(0);
304 }
305 
306 #undef __FUNCT__
307 #define __FUNCT__ "DMSwarmRestoreField"
308 PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
309 {
310   DM_Swarm *swarm = (DM_Swarm*)dm->data;
311   DataField gfield;
312   PetscErrorCode ierr;
313 
314   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
315   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
316   if (data) *data = NULL;
317 
318   PetscFunctionReturn(0);
319 }
320 
321 #undef __FUNCT__
322 #define __FUNCT__ "DMSwarmAddPoint"
323 PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
324 {
325   DM_Swarm *swarm = (DM_Swarm*)dm->data;
326   PetscErrorCode ierr;
327 
328   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
329   ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr);
330   PetscFunctionReturn(0);
331 }
332 
333 #undef __FUNCT__
334 #define __FUNCT__ "DMSwarmAddNPoints"
335 PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
336 {
337   DM_Swarm *swarm = (DM_Swarm*)dm->data;
338   PetscErrorCode ierr;
339   PetscInt nlocal;
340 
341   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
342   nlocal = nlocal + npoints;
343   ierr = DataBucketSetSizes(swarm->db,nlocal,-1);CHKERRQ(ierr);
344   PetscFunctionReturn(0);
345 }
346 
347 #undef __FUNCT__
348 #define __FUNCT__ "DMSwarmRemovePoint"
349 PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
350 {
351   DM_Swarm *swarm = (DM_Swarm*)dm->data;
352   PetscErrorCode ierr;
353 
354   ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
355   PetscFunctionReturn(0);
356 }
357 
358 #undef __FUNCT__
359 #define __FUNCT__ "DMSwarmRemovePointAtIndex"
360 PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
361 {
362   DM_Swarm *swarm = (DM_Swarm*)dm->data;
363   PetscErrorCode ierr;
364 
365   ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
366   PetscFunctionReturn(0);
367 }
368 
369 /*
370  (i) examines DMSwarm field named DMSwarm_rank
371  (ii) all entries label with field_rank[] != rank are pushed to processor rank
372  (iii) points sent can be optionaly removd from local list
373 */
374 #undef __FUNCT__
375 #define __FUNCT__ "DMSwarmPush_Basic"
376 PetscErrorCode DMSwarmPush_Basic(DM dm,PetscBool remove_sent_points)
377 {
378 #if 0
379   DM_Swarm *swarm = (DM_Swarm*)dm->data;
380   PetscErrorCode ierr;
381   MPI_Comm comm;
382   PetscMPIInt *toranks,nfrom,*fromranks,rank;
383   PetscInt p,k,pk,npoints,*rankval,nto,sendcount;
384   char *todata,*fromdata;
385   void *singlebuffer;
386   size_t sizeof_dmswarm_point;
387 
388   comm = PetscObjectComm((PetscObject)dm);
389   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
390 
391   ierr = DataBucketCreatePackedArray(swarm->db,&sizeof_dmswarm_point,&singlebuffer);CHKERRQ(ierr);
392 
393   /* two pass */
394   /* a) count total amount of points to send : count */
395 
396   PetscMalloc1(50,&toranks);
397   for (k=0; k<50; k++) { toranks[k] = -1; }
398 
399   nto = 0;
400   sendcount  = 0;
401   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
402   ierr = DMSwarmGetField(dm,"DMSwarm_rank",NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
403   for (p=0; p<npoints; p++) {
404     if (rankval[p] != (PetscInt)rank) {
405       PetscBool found_rank;
406 
407       sendcount++;
408 
409       for (k=0; k<50; k++) {
410         if (toranks[k] == (PetscMPIInt)rankval[p]) { found_rank = PETSC_TRUE; }
411       }
412       if (!found_rank) {
413         toranks[nto] = (PetscMPIInt)rankval[p];
414         nto++;
415       }
416 
417     }
418   }
419 
420   PetscMalloc1(sizeof_dmswarm_point*sendcount,&todata);
421   pk = 0;
422   for (p=0; p<npoints; p++) {
423     if (rankval[p] != (PetscInt)rank) {
424 
425       ierr = DataBucketFillPackedArray(swarm->db,p,singlebuffer);CHKERRQ(ierr);
426       memcpy(todata + pk*sizeof_dmswarm_point,singlebuffer,sizeof_dmswarm_point);
427       pk++;
428     }
429   }
430 
431   ierr = DMSwarmRestoreField(dm,"DMSwarm_rank",NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
432 
433   if (nto == 0) {
434     PetscPrintf(PETSC_COMM_SELF,"rank[%d] sending nothing\n",rank);
435   } else if (nto == 1) {
436     PetscPrintf(PETSC_COMM_SELF,"rank[%d] sending %D to rank %D\n",rank,sendcount,toranks[0]);
437   } else if (nto == 2) {
438     PetscPrintf(PETSC_COMM_SELF,"rank[%d] sending %D to ranks %D %D\n",rank,sendcount,toranks[0],toranks[1]);
439   } else if (nto == 3) {
440     PetscPrintf(PETSC_COMM_SELF,"rank[%d] sending %D to ranks %D %D %D\n",rank,sendcount,toranks[0],toranks[1],toranks[2]);
441   } else if (nto == 4) {
442     PetscPrintf(PETSC_COMM_SELF,"rank[%d] sending %D to ranks %D %D %D %D\n",rank,sendcount,toranks[0],toranks[1],toranks[2],toranks[3]);
443   } else if (nto == 5) {
444     PetscPrintf(PETSC_COMM_SELF,"rank[%d] sending %D to ranks %D %D %D %D %D\n",rank,sendcount,toranks[0],toranks[1],toranks[2],toranks[3],toranks[4]);
445   }
446 
447   /* this function is not going to be useful if the count has to be equal on all ranks */
448   ierr = PetscCommBuildTwoSided( comm, 1, MPI_CHAR, nto, toranks, (void*)todata,
449                                 &nfrom, &fromranks, (void**)&fromdata);CHKERRQ(ierr);
450 
451 
452   if (nfrom == 0) {
453     PetscPrintf(PETSC_COMM_SELF,"rank[%d] recievd nothing\n",rank);
454   } else if (nfrom == 1) {
455     PetscPrintf(PETSC_COMM_SELF,"rank[%d] recieving %D from rank %D\n",rank,sendcount,fromranks[0]);
456   } else if (nfrom == 2) {
457     PetscPrintf(PETSC_COMM_SELF,"rank[%d] recieving %D from ranks %D %D\n",rank,sendcount,fromranks[0],fromranks[1]);
458   } else if (nfrom == 3) {
459     PetscPrintf(PETSC_COMM_SELF,"rank[%d] recieving %D from ranks %D %D %D\n",rank,sendcount,fromranks[0],fromranks[1],fromranks[2]);
460   } else if (nfrom == 4) {
461     PetscPrintf(PETSC_COMM_SELF,"rank[%d] recieving %D from ranks %D %D %D %D\n",rank,sendcount,fromranks[0],fromranks[1],fromranks[2],fromranks[3]);
462   } else if (nfrom == 5) {
463     PetscPrintf(PETSC_COMM_SELF,"rank[%d] recieving %D from ranks %D %D %D %D %D\n",rank,sendcount,fromranks[0],fromranks[1],fromranks[2],fromranks[3],fromranks[4]);
464   }
465 
466 
467 
468   ierr = DataBucketDestroyPackedArray(swarm->db,&singlebuffer);CHKERRQ(ierr);
469   PetscFree(toranks);
470   PetscFree(fromranks);
471   PetscFree(todata);
472 #endif
473   PetscFunctionReturn(0);
474 }
475 
476 #undef __FUNCT__
477 #define __FUNCT__ "DMSwarmPush"
478 PETSC_EXTERN PetscErrorCode DMSwarmPush(DM dm,PetscBool remove_sent_points)
479 {
480   PetscErrorCode ierr;
481   ierr = DMSwarmPush_Basic(dm,remove_sent_points);CHKERRQ(ierr);
482   PetscFunctionReturn(0);
483 }
484 
485 
486 #undef __FUNCT__
487 #define __FUNCT__ "DMSetup_Swarm"
488 PetscErrorCode DMSetup_Swarm(DM dm)
489 {
490   DM_Swarm *swarm = (DM_Swarm*)dm->data;
491   PetscErrorCode ierr;
492   PetscMPIInt rank;
493   PetscInt p,npoints,*rankval;
494 
495   if (swarm->issetup) PetscFunctionReturn(0);
496 
497   PetscPrintf(PETSC_COMM_SELF,"Swarm setup \n");
498   swarm->issetup = PETSC_TRUE;
499 
500   /* check some fields were registered */
501   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
502 
503   /* check local sizes were set */
504   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
505 
506   /* initialize values in pid and rank placeholders */
507   /* TODO: [pid - use MPI_Scan] */
508 
509   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
510   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
511   ierr = DMSwarmGetField(dm,"DMSwarm_rank",NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
512   for (p=0; p<npoints; p++) {
513     rankval[p] = (PetscInt)rank;
514   }
515   ierr = DMSwarmRestoreField(dm,"DMSwarm_rank",NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
516 
517   PetscFunctionReturn(0);
518 }
519 
520 #undef __FUNCT__
521 #define __FUNCT__ "DMDestroy_Swarm"
522 PetscErrorCode DMDestroy_Swarm(DM dm)
523 {
524   DM_Swarm *swarm = (DM_Swarm*)dm->data;
525   PetscErrorCode ierr;
526 
527   PetscFunctionBegin;
528   ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr);
529   ierr = PetscFree(swarm);CHKERRQ(ierr);
530   PetscFunctionReturn(0);
531 }
532 
533 #undef __FUNCT__
534 #define __FUNCT__ "DMView_Swarm"
535 PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
536 {
537   DM_Swarm *swarm = (DM_Swarm*)dm->data;
538   PetscBool      iascii,ibinary,ishdf5,isvtk;
539   PetscErrorCode ierr;
540 
541   PetscFunctionBegin;
542   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
543   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
544   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
545   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
546   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
547   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
548   if (iascii) {
549     ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
550   } else if (ibinary) {
551     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
552   } else if (ishdf5) {
553 #if defined(PETSC_HAVE_HDF5)
554     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
555 #else
556     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
557 #endif
558   } else if (isvtk) {
559     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
560   }
561   PetscFunctionReturn(0);
562 }
563 
564 #undef __FUNCT__
565 #define __FUNCT__ "DMCreate_Swarm"
566 PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
567 {
568   DM_Swarm      *swarm;
569   PetscErrorCode ierr;
570 
571   PetscFunctionBegin;
572   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
573   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
574 
575   ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr);
576   swarm->vec_field_set = PETSC_FALSE;
577   swarm->issetup = PETSC_FALSE;
578 
579   dm->dim  = 0;
580   dm->data = swarm;
581 
582   dm->ops->view                            = DMView_Swarm;
583   dm->ops->load                            = NULL;
584   dm->ops->setfromoptions                  = NULL;
585   dm->ops->clone                           = NULL;
586   dm->ops->setup                           = DMSetup_Swarm;
587   dm->ops->createdefaultsection            = NULL;
588   dm->ops->createdefaultconstraints        = NULL;
589   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
590   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
591   dm->ops->getlocaltoglobalmapping         = NULL;
592   dm->ops->createfieldis                   = NULL;
593   dm->ops->createcoordinatedm              = NULL;
594   dm->ops->getcoloring                     = NULL;
595   dm->ops->creatematrix                    = NULL;
596   dm->ops->createinterpolation             = NULL;
597   dm->ops->getaggregates                   = NULL;
598   dm->ops->getinjection                    = NULL;
599   dm->ops->refine                          = NULL;
600   dm->ops->coarsen                         = NULL;
601   dm->ops->refinehierarchy                 = NULL;
602   dm->ops->coarsenhierarchy                = NULL;
603   dm->ops->globaltolocalbegin              = NULL;
604   dm->ops->globaltolocalend                = NULL;
605   dm->ops->localtoglobalbegin              = NULL;
606   dm->ops->localtoglobalend                = NULL;
607   dm->ops->destroy                         = DMDestroy_Swarm;
608   dm->ops->createsubdm                     = NULL;
609   dm->ops->getdimpoints                    = NULL;
610   dm->ops->locatepoints                    = NULL;
611 
612   PetscFunctionReturn(0);
613 }