xref: /petsc/src/dm/impls/swarm/swarm.c (revision d3a51819e924468836e8476eeebfdeb7f9f63a1e)
1 
2 #define PETSCDM_DLL
3 #include <petsc/private/dmswarmimpl.h>    /*I   "petscdmswarm.h"   I*/
4 #include "data_bucket.h"
5 
6 const char* DMSwarmTypeNames[] = { "basic", "pic", 0 };
7 const char* DMSwarmMigrateTypeNames[] = { "basic", "dmcellnscatter", "dmcellexact", "user", 0 };
8 const char* DMSwarmCollectTypeNames[] = { "basic", "boundingbox", "general", "user", 0 };
9 
10 const char DMSwarmField_pid[] = "DMSwarm_pid";
11 const char DMSwarmField_rank[] = "DMSwarm_rank";
12 const char DMSwarmPICField_coor[] = "DMSwarmPIC_coor";
13 
14 
15 PetscErrorCode DMSwarmMigrate_Push_Basic(DM dm,PetscBool remove_sent_points);
16 
17 /*@C
18 
19   DMSwarmVectorDefineField - Sets the field from which to define a Vec object
20 
21   Collective on DM
22 
23   Input parameters:
24 . dm - a DMSwarm
25 . fieldname - The textual name given to a registered field
26 
27   Level: beginner
28 
29   Notes:
30   The field with name fieldname must be defined as having a data type of PetscScalar
31   This function must be called prior to calling DMCreateLocalVector(), DMCreateGlobalVector().
32   Mutiple calls to DMSwarmVectorDefineField() are permitted.
33 
34 . seealso: DMSwarmRegisterPetscDatatypeField()
35 
36 @*/
37 #undef __FUNCT__
38 #define __FUNCT__ "DMSwarmVectorDefineField"
39 PETSC_EXTERN PetscErrorCode DMSwarmVectorDefineField(DM dm,const char fieldname[])
40 {
41   DM_Swarm *swarm = (DM_Swarm*)dm->data;
42   PetscErrorCode ierr;
43   PetscInt bs,n;
44   PetscScalar *array;
45   PetscDataType type;
46 
47   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
48   ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr);
49   ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
50 
51   /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */
52   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL");
53 
54   PetscSNPrintf(swarm->vec_field_name,PETSC_MAX_PATH_LEN-1,"%s",fieldname);
55   swarm->vec_field_set = PETSC_TRUE;
56   swarm->vec_field_bs = bs;
57   swarm->vec_field_nlocal = n;
58   ierr = DMSwarmRestoreField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
59 
60   PetscFunctionReturn(0);
61 }
62 
63 #undef __FUNCT__
64 #define __FUNCT__ "DMCreateGlobalVector_Swarm"
65 PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec)
66 {
67   DM_Swarm *swarm = (DM_Swarm*)dm->data;
68   PetscErrorCode ierr;
69   Vec x;
70   char name[PETSC_MAX_PATH_LEN];
71 
72   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
73   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
74   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);
75   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr);
76   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
77   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr);
78   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
79   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
80   *vec = x;
81 
82   PetscFunctionReturn(0);
83 }
84 
85 /* requires DMSwarmDefineFieldVector has been called */
86 #undef __FUNCT__
87 #define __FUNCT__ "DMCreateLocalVector_Swarm"
88 PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec)
89 {
90   DM_Swarm *swarm = (DM_Swarm*)dm->data;
91   PetscErrorCode ierr;
92   Vec x;
93   char name[PETSC_MAX_PATH_LEN];
94 
95   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
96   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
97   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);
98   ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr);
99   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
100   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,swarm->db->L);CHKERRQ(ierr);
101   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
102   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
103   *vec = x;
104 
105   PetscFunctionReturn(0);
106 }
107 
108 /*@C
109 
110  DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field
111 
112  Collective on DM
113 
114  Input parameters:
115  . dm - a DMSwarm
116  . fieldname - the textual name given to a registered field
117 
118  Output parameters:
119  . vec - the vector
120 
121  Level: beginner
122 
123  Notes:
124  Requires that DMSwarmDefineFieldVector() has been called
125 
126  . seealso: DMSwarmRegisterPetscDatatypeField()
127 
128 @*/
129 #undef __FUNCT__
130 #define __FUNCT__ "DMSwarmCreateGlobalVectorFromField"
131 PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
132 {
133   DM_Swarm *swarm = (DM_Swarm*)dm->data;
134   PetscErrorCode ierr;
135   PetscInt bs,n;
136   PetscScalar *array;
137   Vec x;
138   PetscDataType type;
139   char name[PETSC_MAX_PATH_LEN];
140   PetscMPIInt commsize;
141 
142   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
143   ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr);
144   ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
145 
146   /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */
147   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL");
148 
149   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&commsize);CHKERRQ(ierr);
150   if (commsize == 1) {
151     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)dm),bs,n*bs,array,&x);CHKERRQ(ierr);
152   } else {
153     ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)dm),bs,n*bs,PETSC_DETERMINE,array,&x);CHKERRQ(ierr);
154   }
155   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmSharedField_%s",fieldname);
156   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
157 
158   /* Set guard */
159   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarm_VecFieldInPlace_%s",fieldname);
160   ierr = PetscObjectComposeFunction((PetscObject)x,name,DMSwarmDestroyGlobalVectorFromField);CHKERRQ(ierr);
161 
162   *vec = x;
163   PetscFunctionReturn(0);
164 }
165 
166 
167 /*@C
168 
169  DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field
170 
171  Collective on DM
172 
173  Input parameters:
174  . dm - a DMSwarm
175  . fieldname - the textual name given to a registered field
176 
177  Output parameters:
178  . vec - the vector
179 
180  Level: beginner
181 
182  Notes:
183  Requires that DMSwarmDefineFieldVector() has been called
184 
185  . seealso: DMSwarmRegisterPetscDatatypeField()
186 
187 @*/
188 #undef __FUNCT__
189 #define __FUNCT__ "DMSwarmDestroyGlobalVectorFromField"
190 PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
191 {
192   DM_Swarm *swarm = (DM_Swarm*)dm->data;
193   PetscErrorCode ierr;
194   DataField gfield;
195   char name[PETSC_MAX_PATH_LEN];
196   void (*fptr)(void);
197 
198   /* get data field */
199   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
200 
201   /* check vector is an inplace array */
202   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarm_VecFieldInPlace_%s",fieldname);
203   ierr = PetscObjectQueryFunction((PetscObject)(*vec),name,&fptr);CHKERRQ(ierr);
204   if (!fptr) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Vector being destroyed was not created from DMSwarm field(%s)",fieldname);
205 
206   /* restore data field */
207   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
208 
209   ierr = VecDestroy(vec);CHKERRQ(ierr);
210 
211   PetscFunctionReturn(0);
212 }
213 
214 /*
215 PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec)
216 {
217   PetscFunctionReturn(0);
218 }
219 
220 PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec)
221 {
222   PetscFunctionReturn(0);
223 }
224 */
225 
226 
227 /*@C
228 
229  DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm
230 
231  Collective on DM
232 
233  Input parameter:
234  . dm - a DMSwarm
235 
236  Level: beginner
237 
238  Notes:
239  After all fields have been registered, users should call DMSwarmFinalizeFieldRegister()
240 
241  . seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
242  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
243 
244 @*/
245 #undef __FUNCT__
246 #define __FUNCT__ "DMSwarmInitializeFieldRegister"
247 PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm)
248 {
249   DM_Swarm *swarm = (DM_Swarm*)dm->data;
250   PetscErrorCode ierr;
251 
252   swarm->field_registration_initialized = PETSC_TRUE;
253 
254   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */
255   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */
256 
257   PetscFunctionReturn(0);
258 }
259 
260 /*@C
261 
262  DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm
263 
264  Collective on DM
265 
266  Input parameter:
267  . dm - a DMSwarm
268 
269  Level: beginner
270 
271  Notes:
272  After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined
273  on the DMSwarm
274 
275  . seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
276  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
277 
278 @*/
279 #undef __FUNCT__
280 #define __FUNCT__ "DMSwarmFinalizeFieldRegister"
281 PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm)
282 {
283   DM_Swarm *swarm = (DM_Swarm*)dm->data;
284   PetscErrorCode ierr;
285 
286   if (!swarm->field_registration_finalized) {
287     ierr = DataBucketFinalize(swarm->db);CHKERRQ(ierr);
288   }
289   swarm->field_registration_finalized = PETSC_TRUE;
290   PetscFunctionReturn(0);
291 }
292 
293 /*@C
294 
295  DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm
296 
297  Not collective
298 
299  Input parameters:
300  . dm - a DMSwarm
301  . nlocal - the length of each registered field
302  . buffer - the length of the buffer used to efficient dynamic re-sizing
303 
304  Level: beginner
305 
306  . seealso: DMSwarmGetLocalSize()
307 
308 @*/
309 #undef __FUNCT__
310 #define __FUNCT__ "DMSwarmSetLocalSizes"
311 PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer)
312 {
313   DM_Swarm *swarm = (DM_Swarm*)dm->data;
314   PetscErrorCode ierr;
315 
316   ierr = DataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr);
317 
318   PetscFunctionReturn(0);
319 }
320 
321 /*@C
322 
323  DMSwarmSetCellDM - Attachs a DM to a DMSwarm
324 
325  Collective on DM
326 
327  Input parameters:
328  . dm - a DMSwarm
329  . dmcell - the DM to attach to the DMSwarm
330 
331  Level: beginner
332 
333  Notes:
334  The attached DM (dmcell) will be queried for pointlocation and
335  neighbor MPI-rank information if DMSwarmMigrate() is called
336 
337  . seealso: DMSwarmGetCellDM(), DMSwarmMigrate()
338 
339 @*/
340 #undef __FUNCT__
341 #define __FUNCT__ "DMSwarmSetCellDM"
342 PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell)
343 {
344   DM_Swarm *swarm = (DM_Swarm*)dm->data;
345   swarm->dmcell = dmcell;
346   PetscFunctionReturn(0);
347 }
348 
349 /*@C
350 
351  DMSwarmGetCellDM - Fetches the attached cell DM
352 
353  Collective on DM
354 
355  Input parameter:
356  . dm - a DMSwarm
357 
358  Output parameter:
359  . dmcell - the DM which was attached to the DMSwarm
360 
361  Level: beginner
362 
363  Notes:
364  The attached DM (dmcell) will be queried for pointlocation and
365  neighbor MPI-rank information if DMSwarmMigrate() is called
366 
367  . seealso: DMSwarmSetCellDM()
368 
369 @*/
370 #undef __FUNCT__
371 #define __FUNCT__ "DMSwarmGetCellDM"
372 PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell)
373 {
374   DM_Swarm *swarm = (DM_Swarm*)dm->data;
375   *dmcell = swarm->dmcell;
376   PetscFunctionReturn(0);
377 }
378 
379 /*@C
380 
381  DMSwarmGetLocalSize - Retrives the local length of fields registered
382 
383  Not collective
384 
385  Input parameter:
386  . dm - a DMSwarm
387 
388  Output parameter:
389  . nlocal - the length of each registered field
390 
391  Level: beginner
392 
393  . seealso: DMSwarmSetLocalSizes()
394 
395 @*/
396 #undef __FUNCT__
397 #define __FUNCT__ "DMSwarmGetLocalSize"
398 PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal)
399 {
400   DM_Swarm *swarm = (DM_Swarm*)dm->data;
401   PetscErrorCode ierr;
402 
403   if (nlocal) {
404     ierr = DataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);
405   }
406 
407   PetscFunctionReturn(0);
408 }
409 
410 /*@C
411 
412  DMSwarmGetSize - Retrives the total length of fields registered
413 
414  Collective on DM
415 
416  Input parameter:
417  . dm - a DMSwarm
418 
419  Output parameter:
420  . n - the total length of each registered field
421 
422  Level: beginner
423 
424  Note:
425  This calls MPI_Allreduce upon each call (inefficient but safe)
426 
427  . seealso: DMSwarmGetLocalSize()
428 
429 @*/
430 #undef __FUNCT__
431 #define __FUNCT__ "DMSwarmGetSize"
432 PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n)
433 {
434   DM_Swarm *swarm = (DM_Swarm*)dm->data;
435   PetscErrorCode ierr;
436   PetscInt nlocal,ng;
437 
438   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
439   ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
440   if (n) { *n = ng; }
441   PetscFunctionReturn(0);
442 }
443 
444 /*@C
445 
446  DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm
447 
448  Collective on DM
449 
450  Input parameters:
451  . dm - a DMSwarm
452  . fieldname - the textual name to identify this field
453  . blocksize - the number of each data type
454  . type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG)
455 
456  Level: beginner
457 
458  Notes:
459  The textual name for each registered field must be unique
460 
461  . seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
462 
463 @*/
464 #undef __FUNCT__
465 #define __FUNCT__ "DMSwarmRegisterPetscDatatypeField"
466 PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
467 {
468   PetscErrorCode ierr;
469   DM_Swarm *swarm = (DM_Swarm*)dm->data;
470   size_t size;
471 
472   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
473   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
474 
475   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
476   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
477   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
478   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
479   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
480 
481   switch (type) {
482     case PETSC_CHAR:
483       size = sizeof(PetscChar);
484       break;
485     case PETSC_SHORT:
486       size = sizeof(PetscShort);
487       break;
488     case PETSC_INT:
489       size = sizeof(PetscInt);
490       break;
491     case PETSC_LONG:
492       size = sizeof(Petsc64bitInt);
493       break;
494     case PETSC_FLOAT:
495       size = sizeof(PetscFloat);
496       break;
497     case PETSC_DOUBLE:
498       size = sizeof(PetscReal);
499       break;
500 
501     default:
502       SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
503       break;
504   }
505 
506   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
507 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
508   {
509     DataField gfield;
510 
511     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
512     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
513   }
514   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
515 
516   PetscFunctionReturn(0);
517 }
518 
519 /*@C
520 
521  DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm
522 
523  Collective on DM
524 
525  Input parameters:
526  . dm - a DMSwarm
527  . fieldname - the textual name to identify this field
528  . size - the size in bytes of the user struct of each data type
529 
530  Level: beginner
531 
532  Notes:
533  The textual name for each registered field must be unique
534 
535  . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField()
536 
537 @*/
538 #undef __FUNCT__
539 #define __FUNCT__ "DMSwarmRegisterUserStructField"
540 PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
541 {
542   PetscErrorCode ierr;
543   DM_Swarm *swarm = (DM_Swarm*)dm->data;
544 
545 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
546   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
547 
548   PetscFunctionReturn(0);
549 }
550 
551 /*@C
552 
553  DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm
554 
555  Collective on DM
556 
557  Input parameters:
558  . dm - a DMSwarm
559  . fieldname - the textual name to identify this field
560  . size - the size in bytes of the user data type
561  . blocksize - the number of each data type
562 
563  Level: beginner
564 
565  Notes:
566  The textual name for each registered field must be unique
567 
568  . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
569 
570 @*/
571 #undef __FUNCT__
572 #define __FUNCT__ "DMSwarmRegisterUserDatatypeField"
573 PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize)
574 {
575   DM_Swarm *swarm = (DM_Swarm*)dm->data;
576   PetscErrorCode ierr;
577 
578 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
579   {
580     DataField gfield;
581 
582     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
583     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
584   }
585   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
586 
587   PetscFunctionReturn(0);
588 }
589 
590 /*@C
591 
592  DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field
593 
594  Not collective
595 
596  Input parameters:
597  . dm - a DMSwarm
598  . fieldname - the textual name to identify this field
599 
600  Output parameters:
601  . blocksize - the number of each data type
602  . type - the data type
603  . data - pointer to raw array
604 
605  Level: beginner
606 
607  Notes:
608  The user must call DMSwarmRestoreField()
609 
610  . seealso: DMSwarmRestoreField()
611 
612 @*/
613 #undef __FUNCT__
614 #define __FUNCT__ "DMSwarmGetField"
615 PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
616 {
617   DM_Swarm *swarm = (DM_Swarm*)dm->data;
618   DataField gfield;
619   PetscErrorCode ierr;
620 
621   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
622 
623   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
624   ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr);
625   ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr);
626   if (blocksize) {*blocksize = gfield->bs; }
627   if (type) { *type = gfield->petsc_type; }
628 
629   PetscFunctionReturn(0);
630 }
631 
632 /*@C
633 
634  DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field
635 
636  Not collective
637 
638  Input parameters:
639  . dm - a DMSwarm
640  . fieldname - the textual name to identify this field
641 
642  Output parameters:
643  . blocksize - the number of each data type
644  . type - the data type
645  . data - pointer to raw array
646 
647  Level: beginner
648 
649  Notes:
650  The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField()
651 
652  . seealso: DMSwarmGetField()
653 
654 @*/
655 #undef __FUNCT__
656 #define __FUNCT__ "DMSwarmRestoreField"
657 PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
658 {
659   DM_Swarm *swarm = (DM_Swarm*)dm->data;
660   DataField gfield;
661   PetscErrorCode ierr;
662 
663   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
664   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
665   if (data) *data = NULL;
666 
667   PetscFunctionReturn(0);
668 }
669 
670 /*@C
671 
672  DMSwarmAddPoint - Add space for one new point in the DMSwarm
673 
674  Not collective
675 
676  Input parameter:
677  . dm - a DMSwarm
678 
679  Level: beginner
680 
681  Notes:
682  The new point will have all fields initialized to zero
683 
684  . seealso: DMSwarmAddNPoints()
685 
686 @*/
687 #undef __FUNCT__
688 #define __FUNCT__ "DMSwarmAddPoint"
689 PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
690 {
691   DM_Swarm *swarm = (DM_Swarm*)dm->data;
692   PetscErrorCode ierr;
693 
694   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
695   ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr);
696   PetscFunctionReturn(0);
697 }
698 
699 /*@C
700 
701  DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm
702 
703  Not collective
704 
705  Input parameters:
706  . dm - a DMSwarm
707  . npoints - the number of new points to add
708 
709  Level: beginner
710 
711  Notes:
712  The new point will have all fields initialized to zero
713 
714  . seealso: DMSwarmAddPoint()
715 
716 @*/
717 #undef __FUNCT__
718 #define __FUNCT__ "DMSwarmAddNPoints"
719 PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
720 {
721   DM_Swarm *swarm = (DM_Swarm*)dm->data;
722   PetscErrorCode ierr;
723   PetscInt nlocal;
724 
725   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
726   nlocal = nlocal + npoints;
727   ierr = DataBucketSetSizes(swarm->db,nlocal,-1);CHKERRQ(ierr);
728   PetscFunctionReturn(0);
729 }
730 
731 /*@C
732 
733  DMSwarmRemovePoint - Remove the last point from the DMSwarm
734 
735  Not collective
736 
737  Input parameter:
738  . dm - a DMSwarm
739 
740  Level: beginner
741 
742  . seealso: DMSwarmRemovePointAtIndex()
743 
744 @*/
745 #undef __FUNCT__
746 #define __FUNCT__ "DMSwarmRemovePoint"
747 PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
748 {
749   DM_Swarm *swarm = (DM_Swarm*)dm->data;
750   PetscErrorCode ierr;
751 
752   ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
753   PetscFunctionReturn(0);
754 }
755 
756 /*@C
757 
758  DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm
759 
760  Not collective
761 
762  Input parameters:
763  . dm - a DMSwarm
764  . idx - index of point to remove
765 
766  Level: beginner
767 
768  . seealso: DMSwarmRemovePoint()
769 
770 @*/
771 #undef __FUNCT__
772 #define __FUNCT__ "DMSwarmRemovePointAtIndex"
773 PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
774 {
775   DM_Swarm *swarm = (DM_Swarm*)dm->data;
776   PetscErrorCode ierr;
777 
778   ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
779   PetscFunctionReturn(0);
780 }
781 
782 #undef __FUNCT__
783 #define __FUNCT__ "DMSwarmMigrate_Basic"
784 PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points)
785 {
786   PetscErrorCode ierr;
787   ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr);
788   PetscFunctionReturn(0);
789 }
790 
791 PetscErrorCode DMSwarmMigrate_CellDMScatter(DM dm,PetscBool remove_sent_points);
792 PetscErrorCode DMSwarmMigrate_CellDMExact(DM dm,PetscBool remove_sent_points);
793 
794 /*@C
795 
796  DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks
797 
798  Collective on DM
799 
800  Input parameters:
801  . dm - the DMSwarm
802  . remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank
803 
804  Notes:
805  The DM wil be modified to accomodate received points.
806  If remove_sent_points = PETSC_TRUE, send points will be removed from the DM
807  Different styles of migration are supported. See DMSwarmSetMigrateType()
808 
809  Level: advanced
810 
811  . seealso: DMSwarmSetMigrateType()
812 
813 @*/
814 #undef __FUNCT__
815 #define __FUNCT__ "DMSwarmMigrate"
816 PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points)
817 {
818   DM_Swarm *swarm = (DM_Swarm*)dm->data;
819   PetscErrorCode ierr;
820 
821   switch (swarm->migrate_type) {
822 
823     case DMSWARM_MIGRATE_BASIC:
824       ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr);
825       break;
826 
827     case DMSWARM_MIGRATE_DMCELLNSCATTER:
828       ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr);
829       break;
830 
831     case DMSWARM_MIGRATE_DMCELLEXACT:
832       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented");
833       //ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr);
834       break;
835 
836     case DMSWARM_MIGRATE_USER:
837       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented");
838       //ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr);
839       break;
840 
841     default:
842       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown");
843       break;
844   }
845   PetscFunctionReturn(0);
846 }
847 
848 PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize);
849 
850 /*
851  DMSwarmCollectViewCreate
852 
853  * Applies a collection method and gathers point neighbour points into dm
854 
855  Notes:
856  - Users should call DMSwarmCollectViewDestroy() after
857  they have finished computations associated with the collected points
858 */
859 
860 /*@C
861 
862  DMSwarmCollectViewCreate - Applies a collection method and gathers points
863  in neighbour MPI-ranks into the DMSwarm
864 
865  Collective on DM
866 
867  Input parameter:
868  . dm - the DMSwarm
869 
870  Notes:
871  Users should call DMSwarmCollectViewDestroy() after
872  they have finished computations associated with the collected points
873  Different collect methods are supported. See DMSwarmSetCollectType()
874 
875  Level: advanced
876 
877  . seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType()
878 
879 @*/
880 #undef __FUNCT__
881 #define __FUNCT__ "DMSwarmCollectViewCreate"
882 PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm)
883 {
884   PetscErrorCode ierr;
885   DM_Swarm *swarm = (DM_Swarm*)dm->data;
886   PetscInt ng;
887 
888   if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active");
889 
890   ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr);
891   switch (swarm->collect_type) {
892 
893     case DMSWARM_COLLECT_BASIC:
894       ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr);
895       break;
896 
897     case DMSWARM_COLLECT_DMDABOUNDINGBOX:
898       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented");
899       //ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr);
900       break;
901 
902     case DMSWARM_COLLECT_GENERAL:
903       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented");
904       //ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr);
905       break;
906 
907     default:
908       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown");
909       break;
910   }
911 
912   swarm->collect_view_active = PETSC_TRUE;
913   swarm->collect_view_reset_nlocal = ng;
914 
915   PetscFunctionReturn(0);
916 }
917 
918 /*@C
919 
920  DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate()
921 
922  Collective on DM
923 
924  Input parameters:
925  . dm - the DMSwarm
926 
927  Notes:
928  Users should call DMSwarmCollectViewCreate() before this function is called.
929 
930  Level: advanced
931 
932  . seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType()
933 
934 @*/
935 #undef __FUNCT__
936 #define __FUNCT__ "DMSwarmCollectViewDestroy"
937 PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm)
938 {
939   PetscErrorCode ierr;
940   DM_Swarm *swarm = (DM_Swarm*)dm->data;
941 
942   if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active");
943   ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr);
944   swarm->collect_view_active = PETSC_FALSE;
945 
946   PetscFunctionReturn(0);
947 }
948 
949 #undef __FUNCT__
950 #define __FUNCT__ "DMSwarmSetUpPIC"
951 PetscErrorCode DMSwarmSetUpPIC(DM dm)
952 {
953   PetscInt dim;
954   PetscErrorCode ierr;
955 
956   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
957   if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
958   if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
959   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr);
960   PetscFunctionReturn(0);
961 }
962 
963 /*@C
964 
965  DMSwarmSetType - Set particular flavor of DMSwarm
966 
967  Collective on DM
968 
969  Input parameters:
970  . dm - the DMSwarm
971  . stype - the DMSwarm type (e.g. DMSWARM_PIC)
972 
973  Level: advanced
974 
975  . seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType()
976 
977 @*/
978 #define __FUNCT__ "DMSwarmSetType"
979 PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype)
980 {
981   DM_Swarm *swarm = (DM_Swarm*)dm->data;
982   PetscErrorCode ierr;
983 
984   swarm->swarm_type = stype;
985   if (swarm->swarm_type == DMSWARM_PIC) {
986     ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr);
987   }
988   PetscFunctionReturn(0);
989 }
990 
991 #undef __FUNCT__
992 #define __FUNCT__ "DMSetup_Swarm"
993 PetscErrorCode DMSetup_Swarm(DM dm)
994 {
995   DM_Swarm *swarm = (DM_Swarm*)dm->data;
996   PetscErrorCode ierr;
997   PetscMPIInt rank;
998   PetscInt p,npoints,*rankval;
999 
1000   if (swarm->issetup) PetscFunctionReturn(0);
1001 
1002   swarm->issetup = PETSC_TRUE;
1003 
1004   if (swarm->swarm_type == DMSWARM_PIC) {
1005     /* check dmcell exists */
1006     if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM");
1007 
1008     if (swarm->dmcell->ops->locatepointssubdomain) {
1009       /* check methods exists for exact ownership identificiation */
1010       PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");
1011       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT;
1012     } else {
1013       /* check methods exist for point location AND rank neighbor identification */
1014       if (swarm->dmcell->ops->locatepoints) {
1015         PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->LocatePoints\n");
1016       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined");
1017 
1018       if (swarm->dmcell->ops->getneighbors) {
1019         PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->GetNeigbors\n");
1020       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined");
1021 
1022       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER;
1023     }
1024   }
1025 
1026   ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr);
1027 
1028   /* check some fields were registered */
1029   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
1030 
1031   /* check local sizes were set */
1032   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
1033 
1034   /* initialize values in pid and rank placeholders */
1035   /* TODO: [pid - use MPI_Scan] */
1036 
1037   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
1038   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
1039   ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
1040   for (p=0; p<npoints; p++) {
1041     rankval[p] = (PetscInt)rank;
1042   }
1043   ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
1044 
1045   PetscFunctionReturn(0);
1046 }
1047 
1048 #undef __FUNCT__
1049 #define __FUNCT__ "DMDestroy_Swarm"
1050 PetscErrorCode DMDestroy_Swarm(DM dm)
1051 {
1052   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1053   PetscErrorCode ierr;
1054 
1055   PetscFunctionBegin;
1056   ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr);
1057   ierr = PetscFree(swarm);CHKERRQ(ierr);
1058   PetscFunctionReturn(0);
1059 }
1060 
1061 #undef __FUNCT__
1062 #define __FUNCT__ "DMView_Swarm"
1063 PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
1064 {
1065   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1066   PetscBool      iascii,ibinary,ishdf5,isvtk;
1067   PetscErrorCode ierr;
1068 
1069   PetscFunctionBegin;
1070   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1071   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1072   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
1073   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
1074   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
1075   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1076   if (iascii) {
1077     ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
1078   } else if (ibinary) {
1079     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
1080   } else if (ishdf5) {
1081 #if defined(PETSC_HAVE_HDF5)
1082     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
1083 #else
1084     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
1085 #endif
1086   } else if (isvtk) {
1087     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
1088   }
1089   PetscFunctionReturn(0);
1090 }
1091 
1092 /*MC
1093 
1094  DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type.
1095  This implementation was designed for particle-in-cell type methods in which the underlying
1096  data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type.
1097 
1098  User data can be represented by DMSwarm through a registring "fields".
1099  To register a field, the user must provide:
1100  (a) a unique name
1101  (b) the data type (or size in bytes)
1102  (c) the block size of the data
1103 
1104  For example, suppose the application requires a unique id, energy, momentum and density to be stored
1105  on a set of of particles. Then the following application could be used
1106 
1107  DMSwarmInitializeFieldRegister(dm)
1108  DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG);
1109  DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL);
1110  DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL);
1111  DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT);
1112  DMSwarmFinalizeFieldRegister(dm)
1113 
1114  The fields represented by DMSwarm are dynamic and can be re-sized at any time.
1115  The only restriction imposed by DMSwarm is that all fields contain the same number of points
1116 
1117  To support particle methods, "migration" techniques are provided. These methods migrate data
1118  between MPI-ranks.
1119 
1120  DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector().
1121  As a DMSwarm may internally define and store values of different data types,
1122  before calling DMCreate{Global/Local}Vector() the user must inform DMSwarm which
1123  fields should be used to define a Vec object via
1124    DMSwarmVectorDefineField()
1125  The specified field can can changed be changed at any time - thereby permitting vectors
1126  compatable with different fields to be created.
1127 
1128  A dual representation of fields in the DMSwarm and a Vec object are permitted via
1129    DMSwarmCreateGlobalVectorFromField()
1130  Here the data defining the field in the DMSwarm is shared with a Vec.
1131  This is inherently unsafe if you alter the size of the field at any time between
1132  calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField().
1133 
1134 
1135  Level: beginner
1136 
1137  .seealso: DMType, DMCreate(), DMSetType()
1138 
1139 M*/
1140 #undef __FUNCT__
1141 #define __FUNCT__ "DMCreate_Swarm"
1142 PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
1143 {
1144   DM_Swarm      *swarm;
1145   PetscErrorCode ierr;
1146 
1147   PetscFunctionBegin;
1148   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1149   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
1150   dm->data = swarm;
1151 
1152   ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr);
1153   ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr);
1154 
1155   swarm->vec_field_set = PETSC_FALSE;
1156   swarm->issetup = PETSC_FALSE;
1157   swarm->swarm_type = DMSWARM_BASIC;
1158   swarm->migrate_type = DMSWARM_MIGRATE_BASIC;
1159   swarm->collect_type = DMSWARM_COLLECT_BASIC;
1160   swarm->migrate_error_on_missing_point = PETSC_FALSE;
1161 
1162   swarm->dmcell = NULL;
1163   swarm->collect_view_active = PETSC_FALSE;
1164   swarm->collect_view_reset_nlocal = -1;
1165 
1166   dm->dim  = 0;
1167   dm->ops->view                            = DMView_Swarm;
1168   dm->ops->load                            = NULL;
1169   dm->ops->setfromoptions                  = NULL;
1170   dm->ops->clone                           = NULL;
1171   dm->ops->setup                           = DMSetup_Swarm;
1172   dm->ops->createdefaultsection            = NULL;
1173   dm->ops->createdefaultconstraints        = NULL;
1174   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
1175   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
1176   dm->ops->getlocaltoglobalmapping         = NULL;
1177   dm->ops->createfieldis                   = NULL;
1178   dm->ops->createcoordinatedm              = NULL;
1179   dm->ops->getcoloring                     = NULL;
1180   dm->ops->creatematrix                    = NULL;
1181   dm->ops->createinterpolation             = NULL;
1182   dm->ops->getaggregates                   = NULL;
1183   dm->ops->getinjection                    = NULL;
1184   dm->ops->refine                          = NULL;
1185   dm->ops->coarsen                         = NULL;
1186   dm->ops->refinehierarchy                 = NULL;
1187   dm->ops->coarsenhierarchy                = NULL;
1188   dm->ops->globaltolocalbegin              = NULL;
1189   dm->ops->globaltolocalend                = NULL;
1190   dm->ops->localtoglobalbegin              = NULL;
1191   dm->ops->localtoglobalend                = NULL;
1192   dm->ops->destroy                         = DMDestroy_Swarm;
1193   dm->ops->createsubdm                     = NULL;
1194   dm->ops->getdimpoints                    = NULL;
1195   dm->ops->locatepoints                    = NULL;
1196 
1197   PetscFunctionReturn(0);
1198 }