xref: /petsc/src/dm/impls/swarm/swarm.c (revision d3a51819e924468836e8476eeebfdeb7f9f63a1e)
157795646SDave May 
257795646SDave May #define PETSCDM_DLL
357795646SDave May #include <petsc/private/dmswarmimpl.h>    /*I   "petscdmswarm.h"   I*/
4b62e03f8SDave May #include "data_bucket.h"
557795646SDave May 
6f0cdbbbaSDave May const char* DMSwarmTypeNames[] = { "basic", "pic", 0 };
7f0cdbbbaSDave May const char* DMSwarmMigrateTypeNames[] = { "basic", "dmcellnscatter", "dmcellexact", "user", 0 };
8f0cdbbbaSDave May const char* DMSwarmCollectTypeNames[] = { "basic", "boundingbox", "general", "user", 0 };
9f0cdbbbaSDave May 
10f0cdbbbaSDave May const char DMSwarmField_pid[] = "DMSwarm_pid";
11f0cdbbbaSDave May const char DMSwarmField_rank[] = "DMSwarm_rank";
12f0cdbbbaSDave May const char DMSwarmPICField_coor[] = "DMSwarmPIC_coor";
13f0cdbbbaSDave May 
14f0cdbbbaSDave May 
15dcf43ee8SDave May PetscErrorCode DMSwarmMigrate_Push_Basic(DM dm,PetscBool remove_sent_points);
16dcf43ee8SDave May 
17*d3a51819SDave May /*@C
18dcf43ee8SDave May 
19*d3a51819SDave May   DMSwarmVectorDefineField - Sets the field from which to define a Vec object
2057795646SDave May 
21*d3a51819SDave May   Collective on DM
2257795646SDave May 
23*d3a51819SDave May   Input parameters:
24*d3a51819SDave May . dm - a DMSwarm
25*d3a51819SDave May . fieldname - The textual name given to a registered field
2657795646SDave May 
27*d3a51819SDave May   Level: beginner
2857795646SDave May 
29*d3a51819SDave May   Notes:
30*d3a51819SDave May   The field with name fieldname must be defined as having a data type of PetscScalar
31*d3a51819SDave May   This function must be called prior to calling DMCreateLocalVector(), DMCreateGlobalVector().
32*d3a51819SDave May   Mutiple calls to DMSwarmVectorDefineField() are permitted.
3357795646SDave May 
34*d3a51819SDave May . seealso: DMSwarmRegisterPetscDatatypeField()
3557795646SDave May 
36*d3a51819SDave May @*/
3757795646SDave May #undef __FUNCT__
38b5bcf523SDave May #define __FUNCT__ "DMSwarmVectorDefineField"
39b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmVectorDefineField(DM dm,const char fieldname[])
40b5bcf523SDave May {
41b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
42b5bcf523SDave May   PetscErrorCode ierr;
43b5bcf523SDave May   PetscInt bs,n;
44b5bcf523SDave May   PetscScalar *array;
45b5bcf523SDave May   PetscDataType type;
46b5bcf523SDave May 
473454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
486845f8f5SDave May   ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr);
49b5bcf523SDave May   ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
50b5bcf523SDave May 
51b5bcf523SDave May   /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */
52b5bcf523SDave May   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL");
53b5bcf523SDave May 
54b5bcf523SDave May   PetscSNPrintf(swarm->vec_field_name,PETSC_MAX_PATH_LEN-1,"%s",fieldname);
55b5bcf523SDave May   swarm->vec_field_set = PETSC_TRUE;
561b1ea282SDave May   swarm->vec_field_bs = bs;
57b5bcf523SDave May   swarm->vec_field_nlocal = n;
58dcf43ee8SDave May   ierr = DMSwarmRestoreField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
59b5bcf523SDave May 
60b5bcf523SDave May   PetscFunctionReturn(0);
61b5bcf523SDave May }
62b5bcf523SDave May 
63b5bcf523SDave May #undef __FUNCT__
64b5bcf523SDave May #define __FUNCT__ "DMCreateGlobalVector_Swarm"
65b5bcf523SDave May PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec)
66b5bcf523SDave May {
67b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
68b5bcf523SDave May   PetscErrorCode ierr;
69b5bcf523SDave May   Vec x;
70b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
71b5bcf523SDave May 
723454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
73b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
74b5bcf523SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);
75b5bcf523SDave May   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr);
76b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
771b1ea282SDave May   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr);
78b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
79b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
80b5bcf523SDave May   *vec = x;
81b5bcf523SDave May 
82b5bcf523SDave May   PetscFunctionReturn(0);
83b5bcf523SDave May }
84b5bcf523SDave May 
85b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */
86b5bcf523SDave May #undef __FUNCT__
87b5bcf523SDave May #define __FUNCT__ "DMCreateLocalVector_Swarm"
88b5bcf523SDave May PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec)
89b5bcf523SDave May {
90b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
91b5bcf523SDave May   PetscErrorCode ierr;
92b5bcf523SDave May   Vec x;
93b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
94b5bcf523SDave May 
953454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
96b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
97b5bcf523SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);
98b5bcf523SDave May   ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr);
99b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
1001b1ea282SDave May   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,swarm->db->L);CHKERRQ(ierr);
101b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
102b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
103b5bcf523SDave May   *vec = x;
104b5bcf523SDave May 
105b5bcf523SDave May   PetscFunctionReturn(0);
106b5bcf523SDave May }
107b5bcf523SDave May 
108*d3a51819SDave May /*@C
109*d3a51819SDave May 
110*d3a51819SDave May  DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field
111*d3a51819SDave May 
112*d3a51819SDave May  Collective on DM
113*d3a51819SDave May 
114*d3a51819SDave May  Input parameters:
115*d3a51819SDave May  . dm - a DMSwarm
116*d3a51819SDave May  . fieldname - the textual name given to a registered field
117*d3a51819SDave May 
118*d3a51819SDave May  Output parameters:
119*d3a51819SDave May  . vec - the vector
120*d3a51819SDave May 
121*d3a51819SDave May  Level: beginner
122*d3a51819SDave May 
123*d3a51819SDave May  Notes:
124*d3a51819SDave May  Requires that DMSwarmDefineFieldVector() has been called
125*d3a51819SDave May 
126*d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField()
127*d3a51819SDave May 
128*d3a51819SDave May @*/
129b5bcf523SDave May #undef __FUNCT__
130b5bcf523SDave May #define __FUNCT__ "DMSwarmCreateGlobalVectorFromField"
131b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
132b5bcf523SDave May {
133b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
134b5bcf523SDave May   PetscErrorCode ierr;
135b5bcf523SDave May   PetscInt bs,n;
136b5bcf523SDave May   PetscScalar *array;
137b5bcf523SDave May   Vec x;
138b5bcf523SDave May   PetscDataType type;
139b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
1403454631fSDave May   PetscMPIInt commsize;
141b5bcf523SDave May 
1423454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
1436845f8f5SDave May   ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr);
144b5bcf523SDave May   ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
145b5bcf523SDave May 
146b5bcf523SDave May   /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */
147b5bcf523SDave May   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL");
148b5bcf523SDave May 
1493454631fSDave May   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&commsize);CHKERRQ(ierr);
1503454631fSDave May   if (commsize == 1) {
1511b1ea282SDave May     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)dm),bs,n*bs,array,&x);CHKERRQ(ierr);
1523454631fSDave May   } else {
1531b1ea282SDave May     ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)dm),bs,n*bs,PETSC_DETERMINE,array,&x);CHKERRQ(ierr);
1543454631fSDave May   }
1556864fe11SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmSharedField_%s",fieldname);
156dcf43ee8SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
157b5bcf523SDave May 
158b5bcf523SDave May   /* Set guard */
159dcf43ee8SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarm_VecFieldInPlace_%s",fieldname);
160dcf43ee8SDave May   ierr = PetscObjectComposeFunction((PetscObject)x,name,DMSwarmDestroyGlobalVectorFromField);CHKERRQ(ierr);
161b5bcf523SDave May 
162b5bcf523SDave May   *vec = x;
163b5bcf523SDave May   PetscFunctionReturn(0);
164b5bcf523SDave May }
165b5bcf523SDave May 
166*d3a51819SDave May 
167*d3a51819SDave May /*@C
168*d3a51819SDave May 
169*d3a51819SDave May  DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field
170*d3a51819SDave May 
171*d3a51819SDave May  Collective on DM
172*d3a51819SDave May 
173*d3a51819SDave May  Input parameters:
174*d3a51819SDave May  . dm - a DMSwarm
175*d3a51819SDave May  . fieldname - the textual name given to a registered field
176*d3a51819SDave May 
177*d3a51819SDave May  Output parameters:
178*d3a51819SDave May  . vec - the vector
179*d3a51819SDave May 
180*d3a51819SDave May  Level: beginner
181*d3a51819SDave May 
182*d3a51819SDave May  Notes:
183*d3a51819SDave May  Requires that DMSwarmDefineFieldVector() has been called
184*d3a51819SDave May 
185*d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField()
186*d3a51819SDave May 
187*d3a51819SDave May @*/
188b5bcf523SDave May #undef __FUNCT__
189b5bcf523SDave May #define __FUNCT__ "DMSwarmDestroyGlobalVectorFromField"
190b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
191b5bcf523SDave May {
192b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
193b5bcf523SDave May   PetscErrorCode ierr;
194b5bcf523SDave May   DataField gfield;
195b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
196b5bcf523SDave May   void (*fptr)(void);
197b5bcf523SDave May 
198b5bcf523SDave May   /* get data field */
1992eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
200b5bcf523SDave May 
201b5bcf523SDave May   /* check vector is an inplace array */
202b5bcf523SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarm_VecFieldInPlace_%s",fieldname);
203b5bcf523SDave May   ierr = PetscObjectQueryFunction((PetscObject)(*vec),name,&fptr);CHKERRQ(ierr);
204b5bcf523SDave May   if (!fptr) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Vector being destroyed was not created from DMSwarm field(%s)",fieldname);
205b5bcf523SDave May 
206b5bcf523SDave May   /* restore data field */
2076845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
208b5bcf523SDave May 
209b5bcf523SDave May   ierr = VecDestroy(vec);CHKERRQ(ierr);
210b5bcf523SDave May 
211b5bcf523SDave May   PetscFunctionReturn(0);
212b5bcf523SDave May }
213b5bcf523SDave May 
214b5bcf523SDave May /*
215b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec)
216b5bcf523SDave May {
217b5bcf523SDave May   PetscFunctionReturn(0);
218b5bcf523SDave May }
219b5bcf523SDave May 
220b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec)
221b5bcf523SDave May {
222b5bcf523SDave May   PetscFunctionReturn(0);
223b5bcf523SDave May }
224b5bcf523SDave May */
225b5bcf523SDave May 
226*d3a51819SDave May 
227*d3a51819SDave May /*@C
228*d3a51819SDave May 
229*d3a51819SDave May  DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm
230*d3a51819SDave May 
231*d3a51819SDave May  Collective on DM
232*d3a51819SDave May 
233*d3a51819SDave May  Input parameter:
234*d3a51819SDave May  . dm - a DMSwarm
235*d3a51819SDave May 
236*d3a51819SDave May  Level: beginner
237*d3a51819SDave May 
238*d3a51819SDave May  Notes:
239*d3a51819SDave May  After all fields have been registered, users should call DMSwarmFinalizeFieldRegister()
240*d3a51819SDave May 
241*d3a51819SDave May  . seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
242*d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
243*d3a51819SDave May 
244*d3a51819SDave May @*/
245b5bcf523SDave May #undef __FUNCT__
2465f50eb2eSDave May #define __FUNCT__ "DMSwarmInitializeFieldRegister"
2475f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm)
2485f50eb2eSDave May {
2495f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
2503454631fSDave May   PetscErrorCode ierr;
2513454631fSDave May 
2525f50eb2eSDave May   swarm->field_registration_initialized = PETSC_TRUE;
2533454631fSDave May 
254f0cdbbbaSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */
255f0cdbbbaSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */
2563454631fSDave May 
2575f50eb2eSDave May   PetscFunctionReturn(0);
2585f50eb2eSDave May }
2595f50eb2eSDave May 
260*d3a51819SDave May /*@C
261*d3a51819SDave May 
262*d3a51819SDave May  DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm
263*d3a51819SDave May 
264*d3a51819SDave May  Collective on DM
265*d3a51819SDave May 
266*d3a51819SDave May  Input parameter:
267*d3a51819SDave May  . dm - a DMSwarm
268*d3a51819SDave May 
269*d3a51819SDave May  Level: beginner
270*d3a51819SDave May 
271*d3a51819SDave May  Notes:
272*d3a51819SDave May  After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined
273*d3a51819SDave May  on the DMSwarm
274*d3a51819SDave May 
275*d3a51819SDave May  . seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
276*d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
277*d3a51819SDave May 
278*d3a51819SDave May @*/
2795f50eb2eSDave May #undef __FUNCT__
2805f50eb2eSDave May #define __FUNCT__ "DMSwarmFinalizeFieldRegister"
2815f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm)
2825f50eb2eSDave May {
2835f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
2846845f8f5SDave May   PetscErrorCode ierr;
2856845f8f5SDave May 
286f0cdbbbaSDave May   if (!swarm->field_registration_finalized) {
2876845f8f5SDave May     ierr = DataBucketFinalize(swarm->db);CHKERRQ(ierr);
288f0cdbbbaSDave May   }
289f0cdbbbaSDave May   swarm->field_registration_finalized = PETSC_TRUE;
2905f50eb2eSDave May   PetscFunctionReturn(0);
2915f50eb2eSDave May }
2925f50eb2eSDave May 
293*d3a51819SDave May /*@C
294*d3a51819SDave May 
295*d3a51819SDave May  DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm
296*d3a51819SDave May 
297*d3a51819SDave May  Not collective
298*d3a51819SDave May 
299*d3a51819SDave May  Input parameters:
300*d3a51819SDave May  . dm - a DMSwarm
301*d3a51819SDave May  . nlocal - the length of each registered field
302*d3a51819SDave May  . buffer - the length of the buffer used to efficient dynamic re-sizing
303*d3a51819SDave May 
304*d3a51819SDave May  Level: beginner
305*d3a51819SDave May 
306*d3a51819SDave May  . seealso: DMSwarmGetLocalSize()
307*d3a51819SDave May 
308*d3a51819SDave May @*/
3095f50eb2eSDave May #undef __FUNCT__
3105f50eb2eSDave May #define __FUNCT__ "DMSwarmSetLocalSizes"
3115f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer)
3125f50eb2eSDave May {
3135f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3146845f8f5SDave May   PetscErrorCode ierr;
3155f50eb2eSDave May 
3166845f8f5SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr);
3175f50eb2eSDave May 
3185f50eb2eSDave May   PetscFunctionReturn(0);
3195f50eb2eSDave May }
3205f50eb2eSDave May 
321*d3a51819SDave May /*@C
322*d3a51819SDave May 
323*d3a51819SDave May  DMSwarmSetCellDM - Attachs a DM to a DMSwarm
324*d3a51819SDave May 
325*d3a51819SDave May  Collective on DM
326*d3a51819SDave May 
327*d3a51819SDave May  Input parameters:
328*d3a51819SDave May  . dm - a DMSwarm
329*d3a51819SDave May  . dmcell - the DM to attach to the DMSwarm
330*d3a51819SDave May 
331*d3a51819SDave May  Level: beginner
332*d3a51819SDave May 
333*d3a51819SDave May  Notes:
334*d3a51819SDave May  The attached DM (dmcell) will be queried for pointlocation and
335*d3a51819SDave May  neighbor MPI-rank information if DMSwarmMigrate() is called
336*d3a51819SDave May 
337*d3a51819SDave May  . seealso: DMSwarmGetCellDM(), DMSwarmMigrate()
338*d3a51819SDave May 
339*d3a51819SDave May @*/
3405f50eb2eSDave May #undef __FUNCT__
341b16650c8SDave May #define __FUNCT__ "DMSwarmSetCellDM"
342b16650c8SDave May PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell)
343b16650c8SDave May {
344b16650c8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
345b16650c8SDave May   swarm->dmcell = dmcell;
346b16650c8SDave May   PetscFunctionReturn(0);
347b16650c8SDave May }
348b16650c8SDave May 
349*d3a51819SDave May /*@C
350*d3a51819SDave May 
351*d3a51819SDave May  DMSwarmGetCellDM - Fetches the attached cell DM
352*d3a51819SDave May 
353*d3a51819SDave May  Collective on DM
354*d3a51819SDave May 
355*d3a51819SDave May  Input parameter:
356*d3a51819SDave May  . dm - a DMSwarm
357*d3a51819SDave May 
358*d3a51819SDave May  Output parameter:
359*d3a51819SDave May  . dmcell - the DM which was attached to the DMSwarm
360*d3a51819SDave May 
361*d3a51819SDave May  Level: beginner
362*d3a51819SDave May 
363*d3a51819SDave May  Notes:
364*d3a51819SDave May  The attached DM (dmcell) will be queried for pointlocation and
365*d3a51819SDave May  neighbor MPI-rank information if DMSwarmMigrate() is called
366*d3a51819SDave May 
367*d3a51819SDave May  . seealso: DMSwarmSetCellDM()
368*d3a51819SDave May 
369*d3a51819SDave May @*/
370b16650c8SDave May #undef __FUNCT__
371fe39f135SDave May #define __FUNCT__ "DMSwarmGetCellDM"
372fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell)
373fe39f135SDave May {
374fe39f135SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
375fe39f135SDave May   *dmcell = swarm->dmcell;
376fe39f135SDave May   PetscFunctionReturn(0);
377fe39f135SDave May }
378fe39f135SDave May 
379*d3a51819SDave May /*@C
380*d3a51819SDave May 
381*d3a51819SDave May  DMSwarmGetLocalSize - Retrives the local length of fields registered
382*d3a51819SDave May 
383*d3a51819SDave May  Not collective
384*d3a51819SDave May 
385*d3a51819SDave May  Input parameter:
386*d3a51819SDave May  . dm - a DMSwarm
387*d3a51819SDave May 
388*d3a51819SDave May  Output parameter:
389*d3a51819SDave May  . nlocal - the length of each registered field
390*d3a51819SDave May 
391*d3a51819SDave May  Level: beginner
392*d3a51819SDave May 
393*d3a51819SDave May  . seealso: DMSwarmSetLocalSizes()
394*d3a51819SDave May 
395*d3a51819SDave May @*/
396fe39f135SDave May #undef __FUNCT__
397dcf43ee8SDave May #define __FUNCT__ "DMSwarmGetLocalSize"
398dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal)
399dcf43ee8SDave May {
400dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
401dcf43ee8SDave May   PetscErrorCode ierr;
402dcf43ee8SDave May 
403dcf43ee8SDave May   if (nlocal) {
404dcf43ee8SDave May     ierr = DataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);
405dcf43ee8SDave May   }
406dcf43ee8SDave May 
407dcf43ee8SDave May   PetscFunctionReturn(0);
408dcf43ee8SDave May }
409dcf43ee8SDave May 
410*d3a51819SDave May /*@C
411*d3a51819SDave May 
412*d3a51819SDave May  DMSwarmGetSize - Retrives the total length of fields registered
413*d3a51819SDave May 
414*d3a51819SDave May  Collective on DM
415*d3a51819SDave May 
416*d3a51819SDave May  Input parameter:
417*d3a51819SDave May  . dm - a DMSwarm
418*d3a51819SDave May 
419*d3a51819SDave May  Output parameter:
420*d3a51819SDave May  . n - the total length of each registered field
421*d3a51819SDave May 
422*d3a51819SDave May  Level: beginner
423*d3a51819SDave May 
424*d3a51819SDave May  Note:
425*d3a51819SDave May  This calls MPI_Allreduce upon each call (inefficient but safe)
426*d3a51819SDave May 
427*d3a51819SDave May  . seealso: DMSwarmGetLocalSize()
428*d3a51819SDave May 
429*d3a51819SDave May @*/
430dcf43ee8SDave May #undef __FUNCT__
431dcf43ee8SDave May #define __FUNCT__ "DMSwarmGetSize"
432dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n)
433dcf43ee8SDave May {
434dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
435dcf43ee8SDave May   PetscErrorCode ierr;
436dcf43ee8SDave May   PetscInt nlocal,ng;
437dcf43ee8SDave May 
438dcf43ee8SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
439dcf43ee8SDave May   ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
440dcf43ee8SDave May   if (n) { *n = ng; }
441dcf43ee8SDave May   PetscFunctionReturn(0);
442dcf43ee8SDave May }
443dcf43ee8SDave May 
444*d3a51819SDave May /*@C
445*d3a51819SDave May 
446*d3a51819SDave May  DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm
447*d3a51819SDave May 
448*d3a51819SDave May  Collective on DM
449*d3a51819SDave May 
450*d3a51819SDave May  Input parameters:
451*d3a51819SDave May  . dm - a DMSwarm
452*d3a51819SDave May  . fieldname - the textual name to identify this field
453*d3a51819SDave May  . blocksize - the number of each data type
454*d3a51819SDave May  . type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG)
455*d3a51819SDave May 
456*d3a51819SDave May  Level: beginner
457*d3a51819SDave May 
458*d3a51819SDave May  Notes:
459*d3a51819SDave May  The textual name for each registered field must be unique
460*d3a51819SDave May 
461*d3a51819SDave May  . seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
462*d3a51819SDave May 
463*d3a51819SDave May @*/
464dcf43ee8SDave May #undef __FUNCT__
465b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterPetscDatatypeField"
4665f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
467b62e03f8SDave May {
4682eac95f8SDave May   PetscErrorCode ierr;
469b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
470b62e03f8SDave May   size_t size;
471b62e03f8SDave May 
4725f50eb2eSDave May   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
4735f50eb2eSDave May   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
4745f50eb2eSDave May 
4755f50eb2eSDave May   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
4765f50eb2eSDave May   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
4775f50eb2eSDave May   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
4785f50eb2eSDave May   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
4795f50eb2eSDave May   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
480b62e03f8SDave May 
481b62e03f8SDave May   switch (type) {
482b62e03f8SDave May     case PETSC_CHAR:
483b62e03f8SDave May       size = sizeof(PetscChar);
484b62e03f8SDave May       break;
485b62e03f8SDave May     case PETSC_SHORT:
486b62e03f8SDave May       size = sizeof(PetscShort);
487b62e03f8SDave May       break;
488b62e03f8SDave May     case PETSC_INT:
489b62e03f8SDave May       size = sizeof(PetscInt);
490b62e03f8SDave May       break;
491b62e03f8SDave May     case PETSC_LONG:
492b62e03f8SDave May       size = sizeof(Petsc64bitInt);
493b62e03f8SDave May       break;
494b62e03f8SDave May     case PETSC_FLOAT:
495b62e03f8SDave May       size = sizeof(PetscFloat);
496b62e03f8SDave May       break;
497b62e03f8SDave May     case PETSC_DOUBLE:
498b62e03f8SDave May       size = sizeof(PetscReal);
499b62e03f8SDave May       break;
500b62e03f8SDave May 
501b62e03f8SDave May     default:
5025f50eb2eSDave May       SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
503b62e03f8SDave May       break;
504b62e03f8SDave May   }
505b62e03f8SDave May 
506b62e03f8SDave May   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
50752c3ed93SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
50852c3ed93SDave May   {
50952c3ed93SDave May     DataField gfield;
51052c3ed93SDave May 
51152c3ed93SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
51252c3ed93SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
51352c3ed93SDave May   }
514b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
515b62e03f8SDave May 
516b62e03f8SDave May   PetscFunctionReturn(0);
517b62e03f8SDave May }
518b62e03f8SDave May 
519*d3a51819SDave May /*@C
520*d3a51819SDave May 
521*d3a51819SDave May  DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm
522*d3a51819SDave May 
523*d3a51819SDave May  Collective on DM
524*d3a51819SDave May 
525*d3a51819SDave May  Input parameters:
526*d3a51819SDave May  . dm - a DMSwarm
527*d3a51819SDave May  . fieldname - the textual name to identify this field
528*d3a51819SDave May  . size - the size in bytes of the user struct of each data type
529*d3a51819SDave May 
530*d3a51819SDave May  Level: beginner
531*d3a51819SDave May 
532*d3a51819SDave May  Notes:
533*d3a51819SDave May  The textual name for each registered field must be unique
534*d3a51819SDave May 
535*d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField()
536*d3a51819SDave May 
537*d3a51819SDave May @*/
538b62e03f8SDave May #undef __FUNCT__
539b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterUserStructField"
5405f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
541b62e03f8SDave May {
5422eac95f8SDave May   PetscErrorCode ierr;
543b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
544b62e03f8SDave May 
5452eac95f8SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
546b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
547b62e03f8SDave May 
548b62e03f8SDave May   PetscFunctionReturn(0);
549b62e03f8SDave May }
550b62e03f8SDave May 
551*d3a51819SDave May /*@C
552*d3a51819SDave May 
553*d3a51819SDave May  DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm
554*d3a51819SDave May 
555*d3a51819SDave May  Collective on DM
556*d3a51819SDave May 
557*d3a51819SDave May  Input parameters:
558*d3a51819SDave May  . dm - a DMSwarm
559*d3a51819SDave May  . fieldname - the textual name to identify this field
560*d3a51819SDave May  . size - the size in bytes of the user data type
561*d3a51819SDave May  . blocksize - the number of each data type
562*d3a51819SDave May 
563*d3a51819SDave May  Level: beginner
564*d3a51819SDave May 
565*d3a51819SDave May  Notes:
566*d3a51819SDave May  The textual name for each registered field must be unique
567*d3a51819SDave May 
568*d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
569*d3a51819SDave May 
570*d3a51819SDave May @*/
571b62e03f8SDave May #undef __FUNCT__
572b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterUserDatatypeField"
573320740a0SDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize)
574b62e03f8SDave May {
575b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
5766845f8f5SDave May   PetscErrorCode ierr;
577b62e03f8SDave May 
578320740a0SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
579320740a0SDave May   {
580320740a0SDave May     DataField gfield;
581320740a0SDave May 
582320740a0SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
583320740a0SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
584320740a0SDave May   }
585b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
586b62e03f8SDave May 
587b62e03f8SDave May   PetscFunctionReturn(0);
588b62e03f8SDave May }
589b62e03f8SDave May 
590*d3a51819SDave May /*@C
591*d3a51819SDave May 
592*d3a51819SDave May  DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field
593*d3a51819SDave May 
594*d3a51819SDave May  Not collective
595*d3a51819SDave May 
596*d3a51819SDave May  Input parameters:
597*d3a51819SDave May  . dm - a DMSwarm
598*d3a51819SDave May  . fieldname - the textual name to identify this field
599*d3a51819SDave May 
600*d3a51819SDave May  Output parameters:
601*d3a51819SDave May  . blocksize - the number of each data type
602*d3a51819SDave May  . type - the data type
603*d3a51819SDave May  . data - pointer to raw array
604*d3a51819SDave May 
605*d3a51819SDave May  Level: beginner
606*d3a51819SDave May 
607*d3a51819SDave May  Notes:
608*d3a51819SDave May  The user must call DMSwarmRestoreField()
609*d3a51819SDave May 
610*d3a51819SDave May  . seealso: DMSwarmRestoreField()
611*d3a51819SDave May 
612*d3a51819SDave May @*/
613b62e03f8SDave May #undef __FUNCT__
614b62e03f8SDave May #define __FUNCT__ "DMSwarmGetField"
6155f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
616b62e03f8SDave May {
617b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
618b62e03f8SDave May   DataField gfield;
6192eac95f8SDave May   PetscErrorCode ierr;
620b62e03f8SDave May 
6213454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
6223454631fSDave May 
6232eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6246845f8f5SDave May   ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr);
6256845f8f5SDave May   ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr);
6261b1ea282SDave May   if (blocksize) {*blocksize = gfield->bs; }
627b5bcf523SDave May   if (type) { *type = gfield->petsc_type; }
628b62e03f8SDave May 
629b62e03f8SDave May   PetscFunctionReturn(0);
630b62e03f8SDave May }
631b62e03f8SDave May 
632*d3a51819SDave May /*@C
633*d3a51819SDave May 
634*d3a51819SDave May  DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field
635*d3a51819SDave May 
636*d3a51819SDave May  Not collective
637*d3a51819SDave May 
638*d3a51819SDave May  Input parameters:
639*d3a51819SDave May  . dm - a DMSwarm
640*d3a51819SDave May  . fieldname - the textual name to identify this field
641*d3a51819SDave May 
642*d3a51819SDave May  Output parameters:
643*d3a51819SDave May  . blocksize - the number of each data type
644*d3a51819SDave May  . type - the data type
645*d3a51819SDave May  . data - pointer to raw array
646*d3a51819SDave May 
647*d3a51819SDave May  Level: beginner
648*d3a51819SDave May 
649*d3a51819SDave May  Notes:
650*d3a51819SDave May  The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField()
651*d3a51819SDave May 
652*d3a51819SDave May  . seealso: DMSwarmGetField()
653*d3a51819SDave May 
654*d3a51819SDave May @*/
655b62e03f8SDave May #undef __FUNCT__
656b62e03f8SDave May #define __FUNCT__ "DMSwarmRestoreField"
6575f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
658b62e03f8SDave May {
659b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
660b62e03f8SDave May   DataField gfield;
6612eac95f8SDave May   PetscErrorCode ierr;
662b62e03f8SDave May 
6632eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6646845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
665b62e03f8SDave May   if (data) *data = NULL;
666b62e03f8SDave May 
667b62e03f8SDave May   PetscFunctionReturn(0);
668b62e03f8SDave May }
669b62e03f8SDave May 
670*d3a51819SDave May /*@C
671*d3a51819SDave May 
672*d3a51819SDave May  DMSwarmAddPoint - Add space for one new point in the DMSwarm
673*d3a51819SDave May 
674*d3a51819SDave May  Not collective
675*d3a51819SDave May 
676*d3a51819SDave May  Input parameter:
677*d3a51819SDave May  . dm - a DMSwarm
678*d3a51819SDave May 
679*d3a51819SDave May  Level: beginner
680*d3a51819SDave May 
681*d3a51819SDave May  Notes:
682*d3a51819SDave May  The new point will have all fields initialized to zero
683*d3a51819SDave May 
684*d3a51819SDave May  . seealso: DMSwarmAddNPoints()
685*d3a51819SDave May 
686*d3a51819SDave May @*/
687cb1d1399SDave May #undef __FUNCT__
688cb1d1399SDave May #define __FUNCT__ "DMSwarmAddPoint"
689cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
690cb1d1399SDave May {
691cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
692cb1d1399SDave May   PetscErrorCode ierr;
693cb1d1399SDave May 
6943454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
695cb1d1399SDave May   ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr);
696cb1d1399SDave May   PetscFunctionReturn(0);
697cb1d1399SDave May }
698cb1d1399SDave May 
699*d3a51819SDave May /*@C
700*d3a51819SDave May 
701*d3a51819SDave May  DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm
702*d3a51819SDave May 
703*d3a51819SDave May  Not collective
704*d3a51819SDave May 
705*d3a51819SDave May  Input parameters:
706*d3a51819SDave May  . dm - a DMSwarm
707*d3a51819SDave May  . npoints - the number of new points to add
708*d3a51819SDave May 
709*d3a51819SDave May  Level: beginner
710*d3a51819SDave May 
711*d3a51819SDave May  Notes:
712*d3a51819SDave May  The new point will have all fields initialized to zero
713*d3a51819SDave May 
714*d3a51819SDave May  . seealso: DMSwarmAddPoint()
715*d3a51819SDave May 
716*d3a51819SDave May @*/
717cb1d1399SDave May #undef __FUNCT__
718cb1d1399SDave May #define __FUNCT__ "DMSwarmAddNPoints"
719cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
720cb1d1399SDave May {
721cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
722cb1d1399SDave May   PetscErrorCode ierr;
723cb1d1399SDave May   PetscInt nlocal;
724cb1d1399SDave May 
725cb1d1399SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
726cb1d1399SDave May   nlocal = nlocal + npoints;
727cb1d1399SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,-1);CHKERRQ(ierr);
728cb1d1399SDave May   PetscFunctionReturn(0);
729cb1d1399SDave May }
730cb1d1399SDave May 
731*d3a51819SDave May /*@C
732*d3a51819SDave May 
733*d3a51819SDave May  DMSwarmRemovePoint - Remove the last point from the DMSwarm
734*d3a51819SDave May 
735*d3a51819SDave May  Not collective
736*d3a51819SDave May 
737*d3a51819SDave May  Input parameter:
738*d3a51819SDave May  . dm - a DMSwarm
739*d3a51819SDave May 
740*d3a51819SDave May  Level: beginner
741*d3a51819SDave May 
742*d3a51819SDave May  . seealso: DMSwarmRemovePointAtIndex()
743*d3a51819SDave May 
744*d3a51819SDave May @*/
745cb1d1399SDave May #undef __FUNCT__
746cb1d1399SDave May #define __FUNCT__ "DMSwarmRemovePoint"
747cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
748cb1d1399SDave May {
749cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
750cb1d1399SDave May   PetscErrorCode ierr;
751cb1d1399SDave May 
752cb1d1399SDave May   ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
753cb1d1399SDave May   PetscFunctionReturn(0);
754cb1d1399SDave May }
755cb1d1399SDave May 
756*d3a51819SDave May /*@C
757*d3a51819SDave May 
758*d3a51819SDave May  DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm
759*d3a51819SDave May 
760*d3a51819SDave May  Not collective
761*d3a51819SDave May 
762*d3a51819SDave May  Input parameters:
763*d3a51819SDave May  . dm - a DMSwarm
764*d3a51819SDave May  . idx - index of point to remove
765*d3a51819SDave May 
766*d3a51819SDave May  Level: beginner
767*d3a51819SDave May 
768*d3a51819SDave May  . seealso: DMSwarmRemovePoint()
769*d3a51819SDave May 
770*d3a51819SDave May @*/
771cb1d1399SDave May #undef __FUNCT__
772cb1d1399SDave May #define __FUNCT__ "DMSwarmRemovePointAtIndex"
773cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
774cb1d1399SDave May {
775cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
776cb1d1399SDave May   PetscErrorCode ierr;
777cb1d1399SDave May 
778cb1d1399SDave May   ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
779cb1d1399SDave May   PetscFunctionReturn(0);
780cb1d1399SDave May }
781b62e03f8SDave May 
7823454631fSDave May #undef __FUNCT__
783095059a4SDave May #define __FUNCT__ "DMSwarmMigrate_Basic"
784095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points)
7853454631fSDave May {
786dcf43ee8SDave May   PetscErrorCode ierr;
787dcf43ee8SDave May   ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr);
7883454631fSDave May   PetscFunctionReturn(0);
7893454631fSDave May }
7903454631fSDave May 
791f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_CellDMScatter(DM dm,PetscBool remove_sent_points);
792f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_CellDMExact(DM dm,PetscBool remove_sent_points);
793f0cdbbbaSDave May 
794*d3a51819SDave May /*@C
795*d3a51819SDave May 
796*d3a51819SDave May  DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks
797*d3a51819SDave May 
798*d3a51819SDave May  Collective on DM
799*d3a51819SDave May 
800*d3a51819SDave May  Input parameters:
801*d3a51819SDave May  . dm - the DMSwarm
802*d3a51819SDave May  . remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank
803*d3a51819SDave May 
804*d3a51819SDave May  Notes:
805*d3a51819SDave May  The DM wil be modified to accomodate received points.
806*d3a51819SDave May  If remove_sent_points = PETSC_TRUE, send points will be removed from the DM
807*d3a51819SDave May  Different styles of migration are supported. See DMSwarmSetMigrateType()
808*d3a51819SDave May 
809*d3a51819SDave May  Level: advanced
810*d3a51819SDave May 
811*d3a51819SDave May  . seealso: DMSwarmSetMigrateType()
812*d3a51819SDave May 
813*d3a51819SDave May @*/
8143454631fSDave May #undef __FUNCT__
815095059a4SDave May #define __FUNCT__ "DMSwarmMigrate"
816095059a4SDave May PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points)
8173454631fSDave May {
818f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8193454631fSDave May   PetscErrorCode ierr;
820f0cdbbbaSDave May 
821f0cdbbbaSDave May   switch (swarm->migrate_type) {
822f0cdbbbaSDave May 
823f0cdbbbaSDave May     case DMSWARM_MIGRATE_BASIC:
824095059a4SDave May       ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr);
825f0cdbbbaSDave May       break;
826f0cdbbbaSDave May 
827f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLNSCATTER:
828f0cdbbbaSDave May       ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr);
829f0cdbbbaSDave May       break;
830f0cdbbbaSDave May 
831f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLEXACT:
832f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented");
833f0cdbbbaSDave May       //ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr);
834f0cdbbbaSDave May       break;
835f0cdbbbaSDave May 
836f0cdbbbaSDave May     case DMSWARM_MIGRATE_USER:
837f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented");
838f0cdbbbaSDave May       //ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr);
839f0cdbbbaSDave May       break;
840f0cdbbbaSDave May 
841f0cdbbbaSDave May     default:
842f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown");
843f0cdbbbaSDave May       break;
844f0cdbbbaSDave May   }
8453454631fSDave May   PetscFunctionReturn(0);
8463454631fSDave May }
8473454631fSDave May 
848f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize);
849f0cdbbbaSDave May 
850*d3a51819SDave May /*
851*d3a51819SDave May  DMSwarmCollectViewCreate
852*d3a51819SDave May 
853*d3a51819SDave May  * Applies a collection method and gathers point neighbour points into dm
854*d3a51819SDave May 
855*d3a51819SDave May  Notes:
856*d3a51819SDave May  - Users should call DMSwarmCollectViewDestroy() after
857*d3a51819SDave May  they have finished computations associated with the collected points
858*d3a51819SDave May */
859*d3a51819SDave May 
860*d3a51819SDave May /*@C
861*d3a51819SDave May 
862*d3a51819SDave May  DMSwarmCollectViewCreate - Applies a collection method and gathers points
863*d3a51819SDave May  in neighbour MPI-ranks into the DMSwarm
864*d3a51819SDave May 
865*d3a51819SDave May  Collective on DM
866*d3a51819SDave May 
867*d3a51819SDave May  Input parameter:
868*d3a51819SDave May  . dm - the DMSwarm
869*d3a51819SDave May 
870*d3a51819SDave May  Notes:
871*d3a51819SDave May  Users should call DMSwarmCollectViewDestroy() after
872*d3a51819SDave May  they have finished computations associated with the collected points
873*d3a51819SDave May  Different collect methods are supported. See DMSwarmSetCollectType()
874*d3a51819SDave May 
875*d3a51819SDave May  Level: advanced
876*d3a51819SDave May 
877*d3a51819SDave May  . seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType()
878*d3a51819SDave May 
879*d3a51819SDave May @*/
8802712d1f2SDave May #undef __FUNCT__
881fe39f135SDave May #define __FUNCT__ "DMSwarmCollectViewCreate"
882fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm)
8832712d1f2SDave May {
8842712d1f2SDave May   PetscErrorCode ierr;
8852712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8862712d1f2SDave May   PetscInt ng;
8872712d1f2SDave May 
888480eef7bSDave May   if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active");
8892712d1f2SDave May 
890480eef7bSDave May   ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr);
891480eef7bSDave May   switch (swarm->collect_type) {
892f0cdbbbaSDave May 
893480eef7bSDave May     case DMSWARM_COLLECT_BASIC:
8942712d1f2SDave May       ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr);
895480eef7bSDave May       break;
896f0cdbbbaSDave May 
897480eef7bSDave May     case DMSWARM_COLLECT_DMDABOUNDINGBOX:
898f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented");
899fe39f135SDave May       //ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr);
900480eef7bSDave May       break;
901f0cdbbbaSDave May 
902480eef7bSDave May     case DMSWARM_COLLECT_GENERAL:
903f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented");
904fe39f135SDave May       //ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr);
905480eef7bSDave May       break;
906480eef7bSDave May 
907480eef7bSDave May     default:
908f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown");
909480eef7bSDave May       break;
910480eef7bSDave May   }
911480eef7bSDave May 
912480eef7bSDave May   swarm->collect_view_active = PETSC_TRUE;
913480eef7bSDave May   swarm->collect_view_reset_nlocal = ng;
9142712d1f2SDave May 
9152712d1f2SDave May   PetscFunctionReturn(0);
9162712d1f2SDave May }
9172712d1f2SDave May 
918*d3a51819SDave May /*@C
919*d3a51819SDave May 
920*d3a51819SDave May  DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate()
921*d3a51819SDave May 
922*d3a51819SDave May  Collective on DM
923*d3a51819SDave May 
924*d3a51819SDave May  Input parameters:
925*d3a51819SDave May  . dm - the DMSwarm
926*d3a51819SDave May 
927*d3a51819SDave May  Notes:
928*d3a51819SDave May  Users should call DMSwarmCollectViewCreate() before this function is called.
929*d3a51819SDave May 
930*d3a51819SDave May  Level: advanced
931*d3a51819SDave May 
932*d3a51819SDave May  . seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType()
933*d3a51819SDave May 
934*d3a51819SDave May @*/
9352712d1f2SDave May #undef __FUNCT__
936fe39f135SDave May #define __FUNCT__ "DMSwarmCollectViewDestroy"
937fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm)
9382712d1f2SDave May {
9392712d1f2SDave May   PetscErrorCode ierr;
9402712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9412712d1f2SDave May 
942480eef7bSDave May   if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active");
943480eef7bSDave May   ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr);
944480eef7bSDave May   swarm->collect_view_active = PETSC_FALSE;
9452712d1f2SDave May 
9462712d1f2SDave May   PetscFunctionReturn(0);
9472712d1f2SDave May }
9483454631fSDave May 
9493454631fSDave May #undef __FUNCT__
950f0cdbbbaSDave May #define __FUNCT__ "DMSwarmSetUpPIC"
951f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm)
952f0cdbbbaSDave May {
953f0cdbbbaSDave May   PetscInt dim;
954f0cdbbbaSDave May   PetscErrorCode ierr;
955f0cdbbbaSDave May 
956f0cdbbbaSDave May   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
957f0cdbbbaSDave May   if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
958f0cdbbbaSDave May   if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
959f0cdbbbaSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr);
960f0cdbbbaSDave May   PetscFunctionReturn(0);
961f0cdbbbaSDave May }
962f0cdbbbaSDave May 
963*d3a51819SDave May /*@C
964*d3a51819SDave May 
965*d3a51819SDave May  DMSwarmSetType - Set particular flavor of DMSwarm
966*d3a51819SDave May 
967*d3a51819SDave May  Collective on DM
968*d3a51819SDave May 
969*d3a51819SDave May  Input parameters:
970*d3a51819SDave May  . dm - the DMSwarm
971*d3a51819SDave May  . stype - the DMSwarm type (e.g. DMSWARM_PIC)
972*d3a51819SDave May 
973*d3a51819SDave May  Level: advanced
974*d3a51819SDave May 
975*d3a51819SDave May  . seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType()
976*d3a51819SDave May 
977*d3a51819SDave May @*/
978f0cdbbbaSDave May #define __FUNCT__ "DMSwarmSetType"
979f0cdbbbaSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype)
980f0cdbbbaSDave May {
981f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
982f0cdbbbaSDave May   PetscErrorCode ierr;
983f0cdbbbaSDave May 
984f0cdbbbaSDave May   swarm->swarm_type = stype;
985f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
986f0cdbbbaSDave May     ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr);
987f0cdbbbaSDave May   }
988f0cdbbbaSDave May   PetscFunctionReturn(0);
989f0cdbbbaSDave May }
990f0cdbbbaSDave May 
991f0cdbbbaSDave May #undef __FUNCT__
9923454631fSDave May #define __FUNCT__ "DMSetup_Swarm"
9933454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm)
9943454631fSDave May {
9953454631fSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9963454631fSDave May   PetscErrorCode ierr;
9973454631fSDave May   PetscMPIInt rank;
9983454631fSDave May   PetscInt p,npoints,*rankval;
9993454631fSDave May 
10003454631fSDave May   if (swarm->issetup) PetscFunctionReturn(0);
10013454631fSDave May 
10023454631fSDave May   swarm->issetup = PETSC_TRUE;
10033454631fSDave May 
1004f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
1005f0cdbbbaSDave May     /* check dmcell exists */
1006f0cdbbbaSDave May     if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM");
1007f0cdbbbaSDave May 
1008f0cdbbbaSDave May     if (swarm->dmcell->ops->locatepointssubdomain) {
1009f0cdbbbaSDave May       /* check methods exists for exact ownership identificiation */
1010f0cdbbbaSDave May       PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");
1011f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT;
1012f0cdbbbaSDave May     } else {
1013f0cdbbbaSDave May       /* check methods exist for point location AND rank neighbor identification */
1014f0cdbbbaSDave May       if (swarm->dmcell->ops->locatepoints) {
1015f0cdbbbaSDave May         PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->LocatePoints\n");
1016f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined");
1017f0cdbbbaSDave May 
1018f0cdbbbaSDave May       if (swarm->dmcell->ops->getneighbors) {
1019f0cdbbbaSDave May         PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->GetNeigbors\n");
1020f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined");
1021f0cdbbbaSDave May 
1022f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER;
1023f0cdbbbaSDave May     }
1024f0cdbbbaSDave May   }
1025f0cdbbbaSDave May 
1026f0cdbbbaSDave May   ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr);
1027f0cdbbbaSDave May 
10283454631fSDave May   /* check some fields were registered */
10293454631fSDave May   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
10303454631fSDave May 
10313454631fSDave May   /* check local sizes were set */
10323454631fSDave May   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
10333454631fSDave May 
10343454631fSDave May   /* initialize values in pid and rank placeholders */
10353454631fSDave May   /* TODO: [pid - use MPI_Scan] */
10363454631fSDave May 
10373454631fSDave May   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
10383454631fSDave May   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
1039f0cdbbbaSDave May   ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10403454631fSDave May   for (p=0; p<npoints; p++) {
10413454631fSDave May     rankval[p] = (PetscInt)rank;
10423454631fSDave May   }
1043f0cdbbbaSDave May   ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10443454631fSDave May 
10453454631fSDave May   PetscFunctionReturn(0);
10463454631fSDave May }
10473454631fSDave May 
1048b62e03f8SDave May #undef __FUNCT__
104957795646SDave May #define __FUNCT__ "DMDestroy_Swarm"
105057795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm)
105157795646SDave May {
105257795646SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
105357795646SDave May   PetscErrorCode ierr;
105457795646SDave May 
105557795646SDave May   PetscFunctionBegin;
10566845f8f5SDave May   ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr);
105757795646SDave May   ierr = PetscFree(swarm);CHKERRQ(ierr);
105857795646SDave May   PetscFunctionReturn(0);
105957795646SDave May }
106057795646SDave May 
106157795646SDave May #undef __FUNCT__
10625f50eb2eSDave May #define __FUNCT__ "DMView_Swarm"
10635f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
10645f50eb2eSDave May {
10655f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
10665f50eb2eSDave May   PetscBool      iascii,ibinary,ishdf5,isvtk;
10675f50eb2eSDave May   PetscErrorCode ierr;
10685f50eb2eSDave May 
10695f50eb2eSDave May   PetscFunctionBegin;
10705f50eb2eSDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10715f50eb2eSDave May   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
10725f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
10735f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
10745f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
10755f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
10765f50eb2eSDave May   if (iascii) {
10776845f8f5SDave May     ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
10785f50eb2eSDave May   } else if (ibinary) {
10795f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
10805f50eb2eSDave May   } else if (ishdf5) {
10815f50eb2eSDave May #if defined(PETSC_HAVE_HDF5)
10825f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
10835f50eb2eSDave May #else
10845f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
10855f50eb2eSDave May #endif
10865f50eb2eSDave May   } else if (isvtk) {
10875f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
10885f50eb2eSDave May   }
10895f50eb2eSDave May   PetscFunctionReturn(0);
10905f50eb2eSDave May }
10915f50eb2eSDave May 
1092*d3a51819SDave May /*MC
1093*d3a51819SDave May 
1094*d3a51819SDave May  DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type.
1095*d3a51819SDave May  This implementation was designed for particle-in-cell type methods in which the underlying
1096*d3a51819SDave May  data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type.
1097*d3a51819SDave May 
1098*d3a51819SDave May  User data can be represented by DMSwarm through a registring "fields".
1099*d3a51819SDave May  To register a field, the user must provide:
1100*d3a51819SDave May  (a) a unique name
1101*d3a51819SDave May  (b) the data type (or size in bytes)
1102*d3a51819SDave May  (c) the block size of the data
1103*d3a51819SDave May 
1104*d3a51819SDave May  For example, suppose the application requires a unique id, energy, momentum and density to be stored
1105*d3a51819SDave May  on a set of of particles. Then the following application could be used
1106*d3a51819SDave May 
1107*d3a51819SDave May  DMSwarmInitializeFieldRegister(dm)
1108*d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG);
1109*d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL);
1110*d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL);
1111*d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT);
1112*d3a51819SDave May  DMSwarmFinalizeFieldRegister(dm)
1113*d3a51819SDave May 
1114*d3a51819SDave May  The fields represented by DMSwarm are dynamic and can be re-sized at any time.
1115*d3a51819SDave May  The only restriction imposed by DMSwarm is that all fields contain the same number of points
1116*d3a51819SDave May 
1117*d3a51819SDave May  To support particle methods, "migration" techniques are provided. These methods migrate data
1118*d3a51819SDave May  between MPI-ranks.
1119*d3a51819SDave May 
1120*d3a51819SDave May  DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector().
1121*d3a51819SDave May  As a DMSwarm may internally define and store values of different data types,
1122*d3a51819SDave May  before calling DMCreate{Global/Local}Vector() the user must inform DMSwarm which
1123*d3a51819SDave May  fields should be used to define a Vec object via
1124*d3a51819SDave May    DMSwarmVectorDefineField()
1125*d3a51819SDave May  The specified field can can changed be changed at any time - thereby permitting vectors
1126*d3a51819SDave May  compatable with different fields to be created.
1127*d3a51819SDave May 
1128*d3a51819SDave May  A dual representation of fields in the DMSwarm and a Vec object are permitted via
1129*d3a51819SDave May    DMSwarmCreateGlobalVectorFromField()
1130*d3a51819SDave May  Here the data defining the field in the DMSwarm is shared with a Vec.
1131*d3a51819SDave May  This is inherently unsafe if you alter the size of the field at any time between
1132*d3a51819SDave May  calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField().
1133*d3a51819SDave May 
1134*d3a51819SDave May 
1135*d3a51819SDave May  Level: beginner
1136*d3a51819SDave May 
1137*d3a51819SDave May  .seealso: DMType, DMCreate(), DMSetType()
1138*d3a51819SDave May 
1139*d3a51819SDave May M*/
11405f50eb2eSDave May #undef __FUNCT__
114157795646SDave May #define __FUNCT__ "DMCreate_Swarm"
114257795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
114357795646SDave May {
114457795646SDave May   DM_Swarm      *swarm;
114557795646SDave May   PetscErrorCode ierr;
114657795646SDave May 
114757795646SDave May   PetscFunctionBegin;
114857795646SDave May   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
114957795646SDave May   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
1150f0cdbbbaSDave May   dm->data = swarm;
115157795646SDave May 
11526845f8f5SDave May   ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr);
1153f0cdbbbaSDave May   ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr);
1154f0cdbbbaSDave May 
1155b5bcf523SDave May   swarm->vec_field_set = PETSC_FALSE;
11563454631fSDave May   swarm->issetup = PETSC_FALSE;
1157480eef7bSDave May   swarm->swarm_type = DMSWARM_BASIC;
1158480eef7bSDave May   swarm->migrate_type = DMSWARM_MIGRATE_BASIC;
1159480eef7bSDave May   swarm->collect_type = DMSWARM_COLLECT_BASIC;
116040c453e9SDave May   swarm->migrate_error_on_missing_point = PETSC_FALSE;
1161b62e03f8SDave May 
1162f0cdbbbaSDave May   swarm->dmcell = NULL;
1163f0cdbbbaSDave May   swarm->collect_view_active = PETSC_FALSE;
1164f0cdbbbaSDave May   swarm->collect_view_reset_nlocal = -1;
116557795646SDave May 
1166f0cdbbbaSDave May   dm->dim  = 0;
11675f50eb2eSDave May   dm->ops->view                            = DMView_Swarm;
116857795646SDave May   dm->ops->load                            = NULL;
116957795646SDave May   dm->ops->setfromoptions                  = NULL;
117057795646SDave May   dm->ops->clone                           = NULL;
11713454631fSDave May   dm->ops->setup                           = DMSetup_Swarm;
117257795646SDave May   dm->ops->createdefaultsection            = NULL;
117357795646SDave May   dm->ops->createdefaultconstraints        = NULL;
1174b5bcf523SDave May   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
1175b5bcf523SDave May   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
117657795646SDave May   dm->ops->getlocaltoglobalmapping         = NULL;
117757795646SDave May   dm->ops->createfieldis                   = NULL;
117857795646SDave May   dm->ops->createcoordinatedm              = NULL;
117957795646SDave May   dm->ops->getcoloring                     = NULL;
118057795646SDave May   dm->ops->creatematrix                    = NULL;
118157795646SDave May   dm->ops->createinterpolation             = NULL;
118257795646SDave May   dm->ops->getaggregates                   = NULL;
118357795646SDave May   dm->ops->getinjection                    = NULL;
118457795646SDave May   dm->ops->refine                          = NULL;
118557795646SDave May   dm->ops->coarsen                         = NULL;
118657795646SDave May   dm->ops->refinehierarchy                 = NULL;
118757795646SDave May   dm->ops->coarsenhierarchy                = NULL;
118857795646SDave May   dm->ops->globaltolocalbegin              = NULL;
118957795646SDave May   dm->ops->globaltolocalend                = NULL;
119057795646SDave May   dm->ops->localtoglobalbegin              = NULL;
119157795646SDave May   dm->ops->localtoglobalend                = NULL;
119257795646SDave May   dm->ops->destroy                         = DMDestroy_Swarm;
119357795646SDave May   dm->ops->createsubdm                     = NULL;
119457795646SDave May   dm->ops->getdimpoints                    = NULL;
119557795646SDave May   dm->ops->locatepoints                    = NULL;
119657795646SDave May 
119757795646SDave May   PetscFunctionReturn(0);
119857795646SDave May }