xref: /petsc/src/dm/impls/swarm/swarm.c (revision cac75b866cc536e068a555292247149ed7a6872b)
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 
17d3a51819SDave May /*@C
18dcf43ee8SDave May 
19d3a51819SDave May   DMSwarmVectorDefineField - Sets the field from which to define a Vec object
2057795646SDave May 
21d3a51819SDave May   Collective on DM
2257795646SDave May 
23d3a51819SDave May   Input parameters:
24d3a51819SDave May . dm - a DMSwarm
25d3a51819SDave May . fieldname - The textual name given to a registered field
2657795646SDave May 
27d3a51819SDave May   Level: beginner
2857795646SDave May 
29d3a51819SDave May   Notes:
30d3a51819SDave May   The field with name fieldname must be defined as having a data type of PetscScalar
31d3a51819SDave May   This function must be called prior to calling DMCreateLocalVector(), DMCreateGlobalVector().
32d3a51819SDave May   Mutiple calls to DMSwarmVectorDefineField() are permitted.
3357795646SDave May 
34d3a51819SDave May . seealso: DMSwarmRegisterPetscDatatypeField()
3557795646SDave May 
36d3a51819SDave 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 
108d3a51819SDave May /*@C
109d3a51819SDave May 
110d3a51819SDave May  DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field
111d3a51819SDave May 
112d3a51819SDave May  Collective on DM
113d3a51819SDave May 
114d3a51819SDave May  Input parameters:
115d3a51819SDave May  . dm - a DMSwarm
116d3a51819SDave May  . fieldname - the textual name given to a registered field
117d3a51819SDave May 
118d3a51819SDave May  Output parameters:
119d3a51819SDave May  . vec - the vector
120d3a51819SDave May 
121d3a51819SDave May  Level: beginner
122d3a51819SDave May 
123d3a51819SDave May  Notes:
124d3a51819SDave May  Requires that DMSwarmDefineFieldVector() has been called
125d3a51819SDave May 
126d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField()
127d3a51819SDave May 
128d3a51819SDave 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 
166d3a51819SDave May 
167d3a51819SDave May /*@C
168d3a51819SDave May 
169d3a51819SDave May  DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field
170d3a51819SDave May 
171d3a51819SDave May  Collective on DM
172d3a51819SDave May 
173d3a51819SDave May  Input parameters:
174d3a51819SDave May  . dm - a DMSwarm
175d3a51819SDave May  . fieldname - the textual name given to a registered field
176d3a51819SDave May 
177d3a51819SDave May  Output parameters:
178d3a51819SDave May  . vec - the vector
179d3a51819SDave May 
180d3a51819SDave May  Level: beginner
181d3a51819SDave May 
182d3a51819SDave May  Notes:
183d3a51819SDave May  Requires that DMSwarmDefineFieldVector() has been called
184d3a51819SDave May 
185d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField()
186d3a51819SDave May 
187d3a51819SDave 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 
226d3a51819SDave May 
227d3a51819SDave May /*@C
228d3a51819SDave May 
229d3a51819SDave May  DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm
230d3a51819SDave May 
231d3a51819SDave May  Collective on DM
232d3a51819SDave May 
233d3a51819SDave May  Input parameter:
234d3a51819SDave May  . dm - a DMSwarm
235d3a51819SDave May 
236d3a51819SDave May  Level: beginner
237d3a51819SDave May 
238d3a51819SDave May  Notes:
239d3a51819SDave May  After all fields have been registered, users should call DMSwarmFinalizeFieldRegister()
240d3a51819SDave May 
241d3a51819SDave May  . seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
242d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
243d3a51819SDave May 
244d3a51819SDave 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 
260d3a51819SDave May /*@C
261d3a51819SDave May 
262d3a51819SDave May  DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm
263d3a51819SDave May 
264d3a51819SDave May  Collective on DM
265d3a51819SDave May 
266d3a51819SDave May  Input parameter:
267d3a51819SDave May  . dm - a DMSwarm
268d3a51819SDave May 
269d3a51819SDave May  Level: beginner
270d3a51819SDave May 
271d3a51819SDave May  Notes:
272d3a51819SDave May  After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined
273d3a51819SDave May  on the DMSwarm
274d3a51819SDave May 
275d3a51819SDave May  . seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
276d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
277d3a51819SDave May 
278d3a51819SDave 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 
293d3a51819SDave May /*@C
294d3a51819SDave May 
295d3a51819SDave May  DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm
296d3a51819SDave May 
297d3a51819SDave May  Not collective
298d3a51819SDave May 
299d3a51819SDave May  Input parameters:
300d3a51819SDave May  . dm - a DMSwarm
301d3a51819SDave May  . nlocal - the length of each registered field
302d3a51819SDave May  . buffer - the length of the buffer used to efficient dynamic re-sizing
303d3a51819SDave May 
304d3a51819SDave May  Level: beginner
305d3a51819SDave May 
306d3a51819SDave May  . seealso: DMSwarmGetLocalSize()
307d3a51819SDave May 
308d3a51819SDave 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 
321d3a51819SDave May /*@C
322d3a51819SDave May 
323d3a51819SDave May  DMSwarmSetCellDM - Attachs a DM to a DMSwarm
324d3a51819SDave May 
325d3a51819SDave May  Collective on DM
326d3a51819SDave May 
327d3a51819SDave May  Input parameters:
328d3a51819SDave May  . dm - a DMSwarm
329d3a51819SDave May  . dmcell - the DM to attach to the DMSwarm
330d3a51819SDave May 
331d3a51819SDave May  Level: beginner
332d3a51819SDave May 
333d3a51819SDave May  Notes:
334d3a51819SDave May  The attached DM (dmcell) will be queried for pointlocation and
335d3a51819SDave May  neighbor MPI-rank information if DMSwarmMigrate() is called
336d3a51819SDave May 
337d3a51819SDave May  . seealso: DMSwarmGetCellDM(), DMSwarmMigrate()
338d3a51819SDave May 
339d3a51819SDave 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 
349d3a51819SDave May /*@C
350d3a51819SDave May 
351d3a51819SDave May  DMSwarmGetCellDM - Fetches the attached cell DM
352d3a51819SDave May 
353d3a51819SDave May  Collective on DM
354d3a51819SDave May 
355d3a51819SDave May  Input parameter:
356d3a51819SDave May  . dm - a DMSwarm
357d3a51819SDave May 
358d3a51819SDave May  Output parameter:
359d3a51819SDave May  . dmcell - the DM which was attached to the DMSwarm
360d3a51819SDave May 
361d3a51819SDave May  Level: beginner
362d3a51819SDave May 
363d3a51819SDave May  Notes:
364d3a51819SDave May  The attached DM (dmcell) will be queried for pointlocation and
365d3a51819SDave May  neighbor MPI-rank information if DMSwarmMigrate() is called
366d3a51819SDave May 
367d3a51819SDave May  . seealso: DMSwarmSetCellDM()
368d3a51819SDave May 
369d3a51819SDave 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 
379d3a51819SDave May /*@C
380d3a51819SDave May 
381d3a51819SDave May  DMSwarmGetLocalSize - Retrives the local length of fields registered
382d3a51819SDave May 
383d3a51819SDave May  Not collective
384d3a51819SDave May 
385d3a51819SDave May  Input parameter:
386d3a51819SDave May  . dm - a DMSwarm
387d3a51819SDave May 
388d3a51819SDave May  Output parameter:
389d3a51819SDave May  . nlocal - the length of each registered field
390d3a51819SDave May 
391d3a51819SDave May  Level: beginner
392d3a51819SDave May 
393d3a51819SDave May  . seealso: DMSwarmSetLocalSizes()
394d3a51819SDave May 
395d3a51819SDave 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 
410d3a51819SDave May /*@C
411d3a51819SDave May 
412d3a51819SDave May  DMSwarmGetSize - Retrives the total length of fields registered
413d3a51819SDave May 
414d3a51819SDave May  Collective on DM
415d3a51819SDave May 
416d3a51819SDave May  Input parameter:
417d3a51819SDave May  . dm - a DMSwarm
418d3a51819SDave May 
419d3a51819SDave May  Output parameter:
420d3a51819SDave May  . n - the total length of each registered field
421d3a51819SDave May 
422d3a51819SDave May  Level: beginner
423d3a51819SDave May 
424d3a51819SDave May  Note:
425d3a51819SDave May  This calls MPI_Allreduce upon each call (inefficient but safe)
426d3a51819SDave May 
427d3a51819SDave May  . seealso: DMSwarmGetLocalSize()
428d3a51819SDave May 
429d3a51819SDave 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 
444d3a51819SDave May /*@C
445d3a51819SDave May 
446d3a51819SDave May  DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm
447d3a51819SDave May 
448d3a51819SDave May  Collective on DM
449d3a51819SDave May 
450d3a51819SDave May  Input parameters:
451d3a51819SDave May  . dm - a DMSwarm
452d3a51819SDave May  . fieldname - the textual name to identify this field
453d3a51819SDave May  . blocksize - the number of each data type
454d3a51819SDave May  . type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG)
455d3a51819SDave May 
456d3a51819SDave May  Level: beginner
457d3a51819SDave May 
458d3a51819SDave May  Notes:
459d3a51819SDave May  The textual name for each registered field must be unique
460d3a51819SDave May 
461d3a51819SDave May  . seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
462d3a51819SDave May 
463d3a51819SDave 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 
519d3a51819SDave May /*@C
520d3a51819SDave May 
521d3a51819SDave May  DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm
522d3a51819SDave May 
523d3a51819SDave May  Collective on DM
524d3a51819SDave May 
525d3a51819SDave May  Input parameters:
526d3a51819SDave May  . dm - a DMSwarm
527d3a51819SDave May  . fieldname - the textual name to identify this field
528d3a51819SDave May  . size - the size in bytes of the user struct of each data type
529d3a51819SDave May 
530d3a51819SDave May  Level: beginner
531d3a51819SDave May 
532d3a51819SDave May  Notes:
533d3a51819SDave May  The textual name for each registered field must be unique
534d3a51819SDave May 
535d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField()
536d3a51819SDave May 
537d3a51819SDave 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 
551d3a51819SDave May /*@C
552d3a51819SDave May 
553d3a51819SDave May  DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm
554d3a51819SDave May 
555d3a51819SDave May  Collective on DM
556d3a51819SDave May 
557d3a51819SDave May  Input parameters:
558d3a51819SDave May  . dm - a DMSwarm
559d3a51819SDave May  . fieldname - the textual name to identify this field
560d3a51819SDave May  . size - the size in bytes of the user data type
561d3a51819SDave May  . blocksize - the number of each data type
562d3a51819SDave May 
563d3a51819SDave May  Level: beginner
564d3a51819SDave May 
565d3a51819SDave May  Notes:
566d3a51819SDave May  The textual name for each registered field must be unique
567d3a51819SDave May 
568d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
569d3a51819SDave May 
570d3a51819SDave 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 
590d3a51819SDave May /*@C
591d3a51819SDave May 
592d3a51819SDave May  DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field
593d3a51819SDave May 
594d3a51819SDave May  Not collective
595d3a51819SDave May 
596d3a51819SDave May  Input parameters:
597d3a51819SDave May  . dm - a DMSwarm
598d3a51819SDave May  . fieldname - the textual name to identify this field
599d3a51819SDave May 
600d3a51819SDave May  Output parameters:
601d3a51819SDave May  . blocksize - the number of each data type
602d3a51819SDave May  . type - the data type
603d3a51819SDave May  . data - pointer to raw array
604d3a51819SDave May 
605d3a51819SDave May  Level: beginner
606d3a51819SDave May 
607d3a51819SDave May  Notes:
608d3a51819SDave May  The user must call DMSwarmRestoreField()
609d3a51819SDave May 
610d3a51819SDave May  . seealso: DMSwarmRestoreField()
611d3a51819SDave May 
612d3a51819SDave 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 
632d3a51819SDave May /*@C
633d3a51819SDave May 
634d3a51819SDave May  DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field
635d3a51819SDave May 
636d3a51819SDave May  Not collective
637d3a51819SDave May 
638d3a51819SDave May  Input parameters:
639d3a51819SDave May  . dm - a DMSwarm
640d3a51819SDave May  . fieldname - the textual name to identify this field
641d3a51819SDave May 
642d3a51819SDave May  Output parameters:
643d3a51819SDave May  . blocksize - the number of each data type
644d3a51819SDave May  . type - the data type
645d3a51819SDave May  . data - pointer to raw array
646d3a51819SDave May 
647d3a51819SDave May  Level: beginner
648d3a51819SDave May 
649d3a51819SDave May  Notes:
650d3a51819SDave May  The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField()
651d3a51819SDave May 
652d3a51819SDave May  . seealso: DMSwarmGetField()
653d3a51819SDave May 
654d3a51819SDave 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 
670d3a51819SDave May /*@C
671d3a51819SDave May 
672d3a51819SDave May  DMSwarmAddPoint - Add space for one new point in the DMSwarm
673d3a51819SDave May 
674d3a51819SDave May  Not collective
675d3a51819SDave May 
676d3a51819SDave May  Input parameter:
677d3a51819SDave May  . dm - a DMSwarm
678d3a51819SDave May 
679d3a51819SDave May  Level: beginner
680d3a51819SDave May 
681d3a51819SDave May  Notes:
682d3a51819SDave May  The new point will have all fields initialized to zero
683d3a51819SDave May 
684d3a51819SDave May  . seealso: DMSwarmAddNPoints()
685d3a51819SDave May 
686d3a51819SDave 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 
699d3a51819SDave May /*@C
700d3a51819SDave May 
701d3a51819SDave May  DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm
702d3a51819SDave May 
703d3a51819SDave May  Not collective
704d3a51819SDave May 
705d3a51819SDave May  Input parameters:
706d3a51819SDave May  . dm - a DMSwarm
707d3a51819SDave May  . npoints - the number of new points to add
708d3a51819SDave May 
709d3a51819SDave May  Level: beginner
710d3a51819SDave May 
711d3a51819SDave May  Notes:
712d3a51819SDave May  The new point will have all fields initialized to zero
713d3a51819SDave May 
714d3a51819SDave May  . seealso: DMSwarmAddPoint()
715d3a51819SDave May 
716d3a51819SDave 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 
731d3a51819SDave May /*@C
732d3a51819SDave May 
733d3a51819SDave May  DMSwarmRemovePoint - Remove the last point from the DMSwarm
734d3a51819SDave May 
735d3a51819SDave May  Not collective
736d3a51819SDave May 
737d3a51819SDave May  Input parameter:
738d3a51819SDave May  . dm - a DMSwarm
739d3a51819SDave May 
740d3a51819SDave May  Level: beginner
741d3a51819SDave May 
742d3a51819SDave May  . seealso: DMSwarmRemovePointAtIndex()
743d3a51819SDave May 
744d3a51819SDave 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 
756d3a51819SDave May /*@C
757d3a51819SDave May 
758d3a51819SDave May  DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm
759d3a51819SDave May 
760d3a51819SDave May  Not collective
761d3a51819SDave May 
762d3a51819SDave May  Input parameters:
763d3a51819SDave May  . dm - a DMSwarm
764d3a51819SDave May  . idx - index of point to remove
765d3a51819SDave May 
766d3a51819SDave May  Level: beginner
767d3a51819SDave May 
768d3a51819SDave May  . seealso: DMSwarmRemovePoint()
769d3a51819SDave May 
770d3a51819SDave 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 
794d3a51819SDave May /*@C
795d3a51819SDave May 
796d3a51819SDave May  DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks
797d3a51819SDave May 
798d3a51819SDave May  Collective on DM
799d3a51819SDave May 
800d3a51819SDave May  Input parameters:
801d3a51819SDave May  . dm - the DMSwarm
802d3a51819SDave May  . remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank
803d3a51819SDave May 
804d3a51819SDave May  Notes:
805d3a51819SDave May  The DM wil be modified to accomodate received points.
806d3a51819SDave May  If remove_sent_points = PETSC_TRUE, send points will be removed from the DM
807d3a51819SDave May  Different styles of migration are supported. See DMSwarmSetMigrateType()
808d3a51819SDave May 
809d3a51819SDave May  Level: advanced
810d3a51819SDave May 
811d3a51819SDave May  . seealso: DMSwarmSetMigrateType()
812d3a51819SDave May 
813d3a51819SDave 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 
850d3a51819SDave May /*
851d3a51819SDave May  DMSwarmCollectViewCreate
852d3a51819SDave May 
853d3a51819SDave May  * Applies a collection method and gathers point neighbour points into dm
854d3a51819SDave May 
855d3a51819SDave May  Notes:
856d3a51819SDave May  - Users should call DMSwarmCollectViewDestroy() after
857d3a51819SDave May  they have finished computations associated with the collected points
858d3a51819SDave May */
859d3a51819SDave May 
860d3a51819SDave May /*@C
861d3a51819SDave May 
862d3a51819SDave May  DMSwarmCollectViewCreate - Applies a collection method and gathers points
863d3a51819SDave May  in neighbour MPI-ranks into the DMSwarm
864d3a51819SDave May 
865d3a51819SDave May  Collective on DM
866d3a51819SDave May 
867d3a51819SDave May  Input parameter:
868d3a51819SDave May  . dm - the DMSwarm
869d3a51819SDave May 
870d3a51819SDave May  Notes:
871d3a51819SDave May  Users should call DMSwarmCollectViewDestroy() after
872d3a51819SDave May  they have finished computations associated with the collected points
873d3a51819SDave May  Different collect methods are supported. See DMSwarmSetCollectType()
874d3a51819SDave May 
875d3a51819SDave May  Level: advanced
876d3a51819SDave May 
877d3a51819SDave May  . seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType()
878d3a51819SDave May 
879d3a51819SDave 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 
918d3a51819SDave May /*@C
919d3a51819SDave May 
920d3a51819SDave May  DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate()
921d3a51819SDave May 
922d3a51819SDave May  Collective on DM
923d3a51819SDave May 
924d3a51819SDave May  Input parameters:
925d3a51819SDave May  . dm - the DMSwarm
926d3a51819SDave May 
927d3a51819SDave May  Notes:
928d3a51819SDave May  Users should call DMSwarmCollectViewCreate() before this function is called.
929d3a51819SDave May 
930d3a51819SDave May  Level: advanced
931d3a51819SDave May 
932d3a51819SDave May  . seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType()
933d3a51819SDave May 
934d3a51819SDave 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 
963d3a51819SDave May /*@C
964d3a51819SDave May 
965d3a51819SDave May  DMSwarmSetType - Set particular flavor of DMSwarm
966d3a51819SDave May 
967d3a51819SDave May  Collective on DM
968d3a51819SDave May 
969d3a51819SDave May  Input parameters:
970d3a51819SDave May  . dm - the DMSwarm
971d3a51819SDave May  . stype - the DMSwarm type (e.g. DMSWARM_PIC)
972d3a51819SDave May 
973d3a51819SDave May  Level: advanced
974d3a51819SDave May 
975d3a51819SDave May  . seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType()
976d3a51819SDave May 
977d3a51819SDave May @*/
978*cac75b86SDave May #undef __FUNCT__
979f0cdbbbaSDave May #define __FUNCT__ "DMSwarmSetType"
980f0cdbbbaSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype)
981f0cdbbbaSDave May {
982f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
983f0cdbbbaSDave May   PetscErrorCode ierr;
984f0cdbbbaSDave May 
985f0cdbbbaSDave May   swarm->swarm_type = stype;
986f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
987f0cdbbbaSDave May     ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr);
988f0cdbbbaSDave May   }
989f0cdbbbaSDave May   PetscFunctionReturn(0);
990f0cdbbbaSDave May }
991f0cdbbbaSDave May 
992f0cdbbbaSDave May #undef __FUNCT__
9933454631fSDave May #define __FUNCT__ "DMSetup_Swarm"
9943454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm)
9953454631fSDave May {
9963454631fSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9973454631fSDave May   PetscErrorCode ierr;
9983454631fSDave May   PetscMPIInt rank;
9993454631fSDave May   PetscInt p,npoints,*rankval;
10003454631fSDave May 
10013454631fSDave May   if (swarm->issetup) PetscFunctionReturn(0);
10023454631fSDave May 
10033454631fSDave May   swarm->issetup = PETSC_TRUE;
10043454631fSDave May 
1005f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
1006f0cdbbbaSDave May     /* check dmcell exists */
1007f0cdbbbaSDave May     if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM");
1008f0cdbbbaSDave May 
1009f0cdbbbaSDave May     if (swarm->dmcell->ops->locatepointssubdomain) {
1010f0cdbbbaSDave May       /* check methods exists for exact ownership identificiation */
1011f0cdbbbaSDave May       PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");
1012f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT;
1013f0cdbbbaSDave May     } else {
1014f0cdbbbaSDave May       /* check methods exist for point location AND rank neighbor identification */
1015f0cdbbbaSDave May       if (swarm->dmcell->ops->locatepoints) {
1016f0cdbbbaSDave May         PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->LocatePoints\n");
1017f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined");
1018f0cdbbbaSDave May 
1019f0cdbbbaSDave May       if (swarm->dmcell->ops->getneighbors) {
1020f0cdbbbaSDave May         PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->GetNeigbors\n");
1021f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined");
1022f0cdbbbaSDave May 
1023f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER;
1024f0cdbbbaSDave May     }
1025f0cdbbbaSDave May   }
1026f0cdbbbaSDave May 
1027f0cdbbbaSDave May   ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr);
1028f0cdbbbaSDave May 
10293454631fSDave May   /* check some fields were registered */
10303454631fSDave May   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
10313454631fSDave May 
10323454631fSDave May   /* check local sizes were set */
10333454631fSDave May   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
10343454631fSDave May 
10353454631fSDave May   /* initialize values in pid and rank placeholders */
10363454631fSDave May   /* TODO: [pid - use MPI_Scan] */
10373454631fSDave May 
10383454631fSDave May   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
10393454631fSDave May   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
1040f0cdbbbaSDave May   ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10413454631fSDave May   for (p=0; p<npoints; p++) {
10423454631fSDave May     rankval[p] = (PetscInt)rank;
10433454631fSDave May   }
1044f0cdbbbaSDave May   ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10453454631fSDave May 
10463454631fSDave May   PetscFunctionReturn(0);
10473454631fSDave May }
10483454631fSDave May 
1049b62e03f8SDave May #undef __FUNCT__
105057795646SDave May #define __FUNCT__ "DMDestroy_Swarm"
105157795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm)
105257795646SDave May {
105357795646SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
105457795646SDave May   PetscErrorCode ierr;
105557795646SDave May 
105657795646SDave May   PetscFunctionBegin;
10576845f8f5SDave May   ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr);
105857795646SDave May   ierr = PetscFree(swarm);CHKERRQ(ierr);
105957795646SDave May   PetscFunctionReturn(0);
106057795646SDave May }
106157795646SDave May 
106257795646SDave May #undef __FUNCT__
10635f50eb2eSDave May #define __FUNCT__ "DMView_Swarm"
10645f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
10655f50eb2eSDave May {
10665f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
10675f50eb2eSDave May   PetscBool      iascii,ibinary,ishdf5,isvtk;
10685f50eb2eSDave May   PetscErrorCode ierr;
10695f50eb2eSDave May 
10705f50eb2eSDave May   PetscFunctionBegin;
10715f50eb2eSDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10725f50eb2eSDave May   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
10735f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
10745f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
10755f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
10765f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
10775f50eb2eSDave May   if (iascii) {
10786845f8f5SDave May     ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
10795f50eb2eSDave May   } else if (ibinary) {
10805f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
10815f50eb2eSDave May   } else if (ishdf5) {
10825f50eb2eSDave May #if defined(PETSC_HAVE_HDF5)
10835f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
10845f50eb2eSDave May #else
10855f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
10865f50eb2eSDave May #endif
10875f50eb2eSDave May   } else if (isvtk) {
10885f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
10895f50eb2eSDave May   }
10905f50eb2eSDave May   PetscFunctionReturn(0);
10915f50eb2eSDave May }
10925f50eb2eSDave May 
1093d3a51819SDave May /*MC
1094d3a51819SDave May 
1095d3a51819SDave May  DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type.
1096d3a51819SDave May  This implementation was designed for particle-in-cell type methods in which the underlying
1097d3a51819SDave May  data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type.
1098d3a51819SDave May 
1099d3a51819SDave May  User data can be represented by DMSwarm through a registring "fields".
1100d3a51819SDave May  To register a field, the user must provide:
1101d3a51819SDave May  (a) a unique name
1102d3a51819SDave May  (b) the data type (or size in bytes)
1103d3a51819SDave May  (c) the block size of the data
1104d3a51819SDave May 
1105d3a51819SDave May  For example, suppose the application requires a unique id, energy, momentum and density to be stored
1106d3a51819SDave May  on a set of of particles. Then the following application could be used
1107d3a51819SDave May 
1108d3a51819SDave May  DMSwarmInitializeFieldRegister(dm)
1109d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG);
1110d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL);
1111d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL);
1112d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT);
1113d3a51819SDave May  DMSwarmFinalizeFieldRegister(dm)
1114d3a51819SDave May 
1115d3a51819SDave May  The fields represented by DMSwarm are dynamic and can be re-sized at any time.
1116d3a51819SDave May  The only restriction imposed by DMSwarm is that all fields contain the same number of points
1117d3a51819SDave May 
1118d3a51819SDave May  To support particle methods, "migration" techniques are provided. These methods migrate data
1119d3a51819SDave May  between MPI-ranks.
1120d3a51819SDave May 
1121d3a51819SDave May  DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector().
1122d3a51819SDave May  As a DMSwarm may internally define and store values of different data types,
1123d3a51819SDave May  before calling DMCreate{Global/Local}Vector() the user must inform DMSwarm which
1124d3a51819SDave May  fields should be used to define a Vec object via
1125d3a51819SDave May    DMSwarmVectorDefineField()
1126d3a51819SDave May  The specified field can can changed be changed at any time - thereby permitting vectors
1127d3a51819SDave May  compatable with different fields to be created.
1128d3a51819SDave May 
1129d3a51819SDave May  A dual representation of fields in the DMSwarm and a Vec object are permitted via
1130d3a51819SDave May    DMSwarmCreateGlobalVectorFromField()
1131d3a51819SDave May  Here the data defining the field in the DMSwarm is shared with a Vec.
1132d3a51819SDave May  This is inherently unsafe if you alter the size of the field at any time between
1133d3a51819SDave May  calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField().
1134d3a51819SDave May 
1135d3a51819SDave May 
1136d3a51819SDave May  Level: beginner
1137d3a51819SDave May 
1138d3a51819SDave May  .seealso: DMType, DMCreate(), DMSetType()
1139d3a51819SDave May 
1140d3a51819SDave May M*/
11415f50eb2eSDave May #undef __FUNCT__
114257795646SDave May #define __FUNCT__ "DMCreate_Swarm"
114357795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
114457795646SDave May {
114557795646SDave May   DM_Swarm      *swarm;
114657795646SDave May   PetscErrorCode ierr;
114757795646SDave May 
114857795646SDave May   PetscFunctionBegin;
114957795646SDave May   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
115057795646SDave May   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
1151f0cdbbbaSDave May   dm->data = swarm;
115257795646SDave May 
11536845f8f5SDave May   ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr);
1154f0cdbbbaSDave May   ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr);
1155f0cdbbbaSDave May 
1156b5bcf523SDave May   swarm->vec_field_set = PETSC_FALSE;
11573454631fSDave May   swarm->issetup = PETSC_FALSE;
1158480eef7bSDave May   swarm->swarm_type = DMSWARM_BASIC;
1159480eef7bSDave May   swarm->migrate_type = DMSWARM_MIGRATE_BASIC;
1160480eef7bSDave May   swarm->collect_type = DMSWARM_COLLECT_BASIC;
116140c453e9SDave May   swarm->migrate_error_on_missing_point = PETSC_FALSE;
1162b62e03f8SDave May 
1163f0cdbbbaSDave May   swarm->dmcell = NULL;
1164f0cdbbbaSDave May   swarm->collect_view_active = PETSC_FALSE;
1165f0cdbbbaSDave May   swarm->collect_view_reset_nlocal = -1;
116657795646SDave May 
1167f0cdbbbaSDave May   dm->dim  = 0;
11685f50eb2eSDave May   dm->ops->view                            = DMView_Swarm;
116957795646SDave May   dm->ops->load                            = NULL;
117057795646SDave May   dm->ops->setfromoptions                  = NULL;
117157795646SDave May   dm->ops->clone                           = NULL;
11723454631fSDave May   dm->ops->setup                           = DMSetup_Swarm;
117357795646SDave May   dm->ops->createdefaultsection            = NULL;
117457795646SDave May   dm->ops->createdefaultconstraints        = NULL;
1175b5bcf523SDave May   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
1176b5bcf523SDave May   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
117757795646SDave May   dm->ops->getlocaltoglobalmapping         = NULL;
117857795646SDave May   dm->ops->createfieldis                   = NULL;
117957795646SDave May   dm->ops->createcoordinatedm              = NULL;
118057795646SDave May   dm->ops->getcoloring                     = NULL;
118157795646SDave May   dm->ops->creatematrix                    = NULL;
118257795646SDave May   dm->ops->createinterpolation             = NULL;
118357795646SDave May   dm->ops->getaggregates                   = NULL;
118457795646SDave May   dm->ops->getinjection                    = NULL;
118557795646SDave May   dm->ops->refine                          = NULL;
118657795646SDave May   dm->ops->coarsen                         = NULL;
118757795646SDave May   dm->ops->refinehierarchy                 = NULL;
118857795646SDave May   dm->ops->coarsenhierarchy                = NULL;
118957795646SDave May   dm->ops->globaltolocalbegin              = NULL;
119057795646SDave May   dm->ops->globaltolocalend                = NULL;
119157795646SDave May   dm->ops->localtoglobalbegin              = NULL;
119257795646SDave May   dm->ops->localtoglobalend                = NULL;
119357795646SDave May   dm->ops->destroy                         = DMDestroy_Swarm;
119457795646SDave May   dm->ops->createsubdm                     = NULL;
119557795646SDave May   dm->ops->getdimpoints                    = NULL;
119657795646SDave May   dm->ops->locatepoints                    = NULL;
119757795646SDave May 
119857795646SDave May   PetscFunctionReturn(0);
119957795646SDave May }