xref: /petsc/src/dm/impls/swarm/swarm.c (revision 2ddcf43e58a27f1567064c3d4e7d2d78f507e308)
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 
63cc651181SDave May /* requires DMSwarmDefineFieldVector has been called */
64b5bcf523SDave May #undef __FUNCT__
65b5bcf523SDave May #define __FUNCT__ "DMCreateGlobalVector_Swarm"
66b5bcf523SDave May PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec)
67b5bcf523SDave May {
68b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
69b5bcf523SDave May   PetscErrorCode ierr;
70b5bcf523SDave May   Vec x;
71b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
72b5bcf523SDave May 
733454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
74b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
75cc651181SDave May   if (swarm->vec_field_nlocal != swarm->db->L) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSwarm sizes have changed since last call to VectorDefineField first"); /* Stale data */
76cc651181SDave May 
77b5bcf523SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);
78b5bcf523SDave May   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr);
79b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
801b1ea282SDave May   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr);
81b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
82b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
83b5bcf523SDave May   *vec = x;
84b5bcf523SDave May 
85b5bcf523SDave May   PetscFunctionReturn(0);
86b5bcf523SDave May }
87b5bcf523SDave May 
88b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */
89b5bcf523SDave May #undef __FUNCT__
90b5bcf523SDave May #define __FUNCT__ "DMCreateLocalVector_Swarm"
91b5bcf523SDave May PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec)
92b5bcf523SDave May {
93b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
94b5bcf523SDave May   PetscErrorCode ierr;
95b5bcf523SDave May   Vec x;
96b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
97b5bcf523SDave May 
983454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
99b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
100cc651181SDave May   if (swarm->vec_field_nlocal != swarm->db->L) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSwarm sizes have changed since last call to VectorDefineField first"); /* Stale data */
101cc651181SDave May 
102b5bcf523SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);
103b5bcf523SDave May   ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr);
104b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
1051b1ea282SDave May   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,swarm->db->L);CHKERRQ(ierr);
106b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
107b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
108b5bcf523SDave May   *vec = x;
109b5bcf523SDave May 
110b5bcf523SDave May   PetscFunctionReturn(0);
111b5bcf523SDave May }
112b5bcf523SDave May 
113d3a51819SDave May /*@C
114d3a51819SDave May 
115d3a51819SDave May  DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field
116d3a51819SDave May 
117d3a51819SDave May  Collective on DM
118d3a51819SDave May 
119d3a51819SDave May  Input parameters:
120d3a51819SDave May  . dm - a DMSwarm
121d3a51819SDave May  . fieldname - the textual name given to a registered field
122d3a51819SDave May 
123d3a51819SDave May  Output parameters:
124d3a51819SDave May  . vec - the vector
125d3a51819SDave May 
126d3a51819SDave May  Level: beginner
127d3a51819SDave May 
128d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField()
129d3a51819SDave May 
130d3a51819SDave May @*/
131b5bcf523SDave May #undef __FUNCT__
132b5bcf523SDave May #define __FUNCT__ "DMSwarmCreateGlobalVectorFromField"
133b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
134b5bcf523SDave May {
135b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
136b5bcf523SDave May   PetscErrorCode ierr;
137b5bcf523SDave May   PetscInt bs,n;
138b5bcf523SDave May   PetscScalar *array;
139b5bcf523SDave May   Vec x;
140b5bcf523SDave May   PetscDataType type;
141b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
1423454631fSDave May   PetscMPIInt commsize;
143b5bcf523SDave May 
1443454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
145cc651181SDave May 
1466845f8f5SDave May   ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr);
147b5bcf523SDave May   ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
148b5bcf523SDave May 
149b5bcf523SDave May   /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */
150b5bcf523SDave May   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL");
151b5bcf523SDave May 
1523454631fSDave May   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&commsize);CHKERRQ(ierr);
1533454631fSDave May   if (commsize == 1) {
1541b1ea282SDave May     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)dm),bs,n*bs,array,&x);CHKERRQ(ierr);
1553454631fSDave May   } else {
1561b1ea282SDave May     ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)dm),bs,n*bs,PETSC_DETERMINE,array,&x);CHKERRQ(ierr);
1573454631fSDave May   }
1586864fe11SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmSharedField_%s",fieldname);
159dcf43ee8SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
160b5bcf523SDave May 
161b5bcf523SDave May   /* Set guard */
162dcf43ee8SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarm_VecFieldInPlace_%s",fieldname);
163dcf43ee8SDave May   ierr = PetscObjectComposeFunction((PetscObject)x,name,DMSwarmDestroyGlobalVectorFromField);CHKERRQ(ierr);
164b5bcf523SDave May 
165b5bcf523SDave May   *vec = x;
166b5bcf523SDave May   PetscFunctionReturn(0);
167b5bcf523SDave May }
168b5bcf523SDave May 
169d3a51819SDave May 
170d3a51819SDave May /*@C
171d3a51819SDave May 
172d3a51819SDave May  DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field
173d3a51819SDave May 
174d3a51819SDave May  Collective on DM
175d3a51819SDave May 
176d3a51819SDave May  Input parameters:
177d3a51819SDave May  . dm - a DMSwarm
178d3a51819SDave May  . fieldname - the textual name given to a registered field
179d3a51819SDave May 
180d3a51819SDave May  Output parameters:
181d3a51819SDave May  . vec - the vector
182d3a51819SDave May 
183d3a51819SDave May  Level: beginner
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);
197cc651181SDave May   PetscInt bs,nlocal;
198cc651181SDave May 
199cc651181SDave May   ierr = VecGetLocalSize(*vec,&nlocal);CHKERRQ(ierr);
200cc651181SDave May   ierr = VecGetBlockSize(*vec,&bs);CHKERRQ(ierr);
201cc651181SDave May   if (nlocal/bs != swarm->db->L) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSwarm sizes have changed since vector was created - cannot ensure pointers are valid"); /* Stale data */
202b5bcf523SDave May 
203b5bcf523SDave May   /* get data field */
2042eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
205b5bcf523SDave May 
206b5bcf523SDave May   /* check vector is an inplace array */
207b5bcf523SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarm_VecFieldInPlace_%s",fieldname);
208b5bcf523SDave May   ierr = PetscObjectQueryFunction((PetscObject)(*vec),name,&fptr);CHKERRQ(ierr);
209b5bcf523SDave May   if (!fptr) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Vector being destroyed was not created from DMSwarm field(%s)",fieldname);
210b5bcf523SDave May 
211b5bcf523SDave May   /* restore data field */
2126845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
213b5bcf523SDave May 
214b5bcf523SDave May   ierr = VecDestroy(vec);CHKERRQ(ierr);
215b5bcf523SDave May 
216b5bcf523SDave May   PetscFunctionReturn(0);
217b5bcf523SDave May }
218b5bcf523SDave May 
219b5bcf523SDave May /*
220b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec)
221b5bcf523SDave May {
222b5bcf523SDave May   PetscFunctionReturn(0);
223b5bcf523SDave May }
224b5bcf523SDave May 
225b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec)
226b5bcf523SDave May {
227b5bcf523SDave May   PetscFunctionReturn(0);
228b5bcf523SDave May }
229b5bcf523SDave May */
230b5bcf523SDave May 
231d3a51819SDave May 
232d3a51819SDave May /*@C
233d3a51819SDave May 
234d3a51819SDave May  DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm
235d3a51819SDave May 
236d3a51819SDave May  Collective on DM
237d3a51819SDave May 
238d3a51819SDave May  Input parameter:
239d3a51819SDave May  . dm - a DMSwarm
240d3a51819SDave May 
241d3a51819SDave May  Level: beginner
242d3a51819SDave May 
243d3a51819SDave May  Notes:
244d3a51819SDave May  After all fields have been registered, users should call DMSwarmFinalizeFieldRegister()
245d3a51819SDave May 
246d3a51819SDave May  . seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
247d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
248d3a51819SDave May 
249d3a51819SDave May @*/
250b5bcf523SDave May #undef __FUNCT__
2515f50eb2eSDave May #define __FUNCT__ "DMSwarmInitializeFieldRegister"
2525f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm)
2535f50eb2eSDave May {
2545f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
2553454631fSDave May   PetscErrorCode ierr;
2563454631fSDave May 
257cc651181SDave May   if (!swarm->field_registration_initialized) {
2585f50eb2eSDave May     swarm->field_registration_initialized = PETSC_TRUE;
259f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */
260f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */
261cc651181SDave May   }
2623454631fSDave May 
2635f50eb2eSDave May   PetscFunctionReturn(0);
2645f50eb2eSDave May }
2655f50eb2eSDave May 
266d3a51819SDave May /*@C
267d3a51819SDave May 
268d3a51819SDave May  DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm
269d3a51819SDave May 
270d3a51819SDave May  Collective on DM
271d3a51819SDave May 
272d3a51819SDave May  Input parameter:
273d3a51819SDave May  . dm - a DMSwarm
274d3a51819SDave May 
275d3a51819SDave May  Level: beginner
276d3a51819SDave May 
277d3a51819SDave May  Notes:
278d3a51819SDave May  After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined
279d3a51819SDave May  on the DMSwarm
280d3a51819SDave May 
281d3a51819SDave May  . seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
282d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
283d3a51819SDave May 
284d3a51819SDave May @*/
2855f50eb2eSDave May #undef __FUNCT__
2865f50eb2eSDave May #define __FUNCT__ "DMSwarmFinalizeFieldRegister"
2875f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm)
2885f50eb2eSDave May {
2895f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
2906845f8f5SDave May   PetscErrorCode ierr;
2916845f8f5SDave May 
292f0cdbbbaSDave May   if (!swarm->field_registration_finalized) {
2936845f8f5SDave May     ierr = DataBucketFinalize(swarm->db);CHKERRQ(ierr);
294f0cdbbbaSDave May   }
295f0cdbbbaSDave May   swarm->field_registration_finalized = PETSC_TRUE;
2965f50eb2eSDave May   PetscFunctionReturn(0);
2975f50eb2eSDave May }
2985f50eb2eSDave May 
299d3a51819SDave May /*@C
300d3a51819SDave May 
301d3a51819SDave May  DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm
302d3a51819SDave May 
303d3a51819SDave May  Not collective
304d3a51819SDave May 
305d3a51819SDave May  Input parameters:
306d3a51819SDave May  . dm - a DMSwarm
307d3a51819SDave May  . nlocal - the length of each registered field
308d3a51819SDave May  . buffer - the length of the buffer used to efficient dynamic re-sizing
309d3a51819SDave May 
310d3a51819SDave May  Level: beginner
311d3a51819SDave May 
312d3a51819SDave May  . seealso: DMSwarmGetLocalSize()
313d3a51819SDave May 
314d3a51819SDave May @*/
3155f50eb2eSDave May #undef __FUNCT__
3165f50eb2eSDave May #define __FUNCT__ "DMSwarmSetLocalSizes"
3175f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer)
3185f50eb2eSDave May {
3195f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3206845f8f5SDave May   PetscErrorCode ierr;
3215f50eb2eSDave May 
3226845f8f5SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr);
3235f50eb2eSDave May 
3245f50eb2eSDave May   PetscFunctionReturn(0);
3255f50eb2eSDave May }
3265f50eb2eSDave May 
327d3a51819SDave May /*@C
328d3a51819SDave May 
329d3a51819SDave May  DMSwarmSetCellDM - Attachs a DM to a DMSwarm
330d3a51819SDave May 
331d3a51819SDave May  Collective on DM
332d3a51819SDave May 
333d3a51819SDave May  Input parameters:
334d3a51819SDave May  . dm - a DMSwarm
335d3a51819SDave May  . dmcell - the DM to attach to the DMSwarm
336d3a51819SDave May 
337d3a51819SDave May  Level: beginner
338d3a51819SDave May 
339d3a51819SDave May  Notes:
340d3a51819SDave May  The attached DM (dmcell) will be queried for pointlocation and
341d3a51819SDave May  neighbor MPI-rank information if DMSwarmMigrate() is called
342d3a51819SDave May 
343d3a51819SDave May  . seealso: DMSwarmGetCellDM(), DMSwarmMigrate()
344d3a51819SDave May 
345d3a51819SDave May @*/
3465f50eb2eSDave May #undef __FUNCT__
347b16650c8SDave May #define __FUNCT__ "DMSwarmSetCellDM"
348b16650c8SDave May PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell)
349b16650c8SDave May {
350b16650c8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
351b16650c8SDave May   swarm->dmcell = dmcell;
352b16650c8SDave May   PetscFunctionReturn(0);
353b16650c8SDave May }
354b16650c8SDave May 
355d3a51819SDave May /*@C
356d3a51819SDave May 
357d3a51819SDave May  DMSwarmGetCellDM - Fetches the attached cell DM
358d3a51819SDave May 
359d3a51819SDave May  Collective on DM
360d3a51819SDave May 
361d3a51819SDave May  Input parameter:
362d3a51819SDave May  . dm - a DMSwarm
363d3a51819SDave May 
364d3a51819SDave May  Output parameter:
365d3a51819SDave May  . dmcell - the DM which was attached to the DMSwarm
366d3a51819SDave May 
367d3a51819SDave May  Level: beginner
368d3a51819SDave May 
369d3a51819SDave May  Notes:
370d3a51819SDave May  The attached DM (dmcell) will be queried for pointlocation and
371d3a51819SDave May  neighbor MPI-rank information if DMSwarmMigrate() is called
372d3a51819SDave May 
373d3a51819SDave May  . seealso: DMSwarmSetCellDM()
374d3a51819SDave May 
375d3a51819SDave May @*/
376b16650c8SDave May #undef __FUNCT__
377fe39f135SDave May #define __FUNCT__ "DMSwarmGetCellDM"
378fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell)
379fe39f135SDave May {
380fe39f135SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
381fe39f135SDave May   *dmcell = swarm->dmcell;
382fe39f135SDave May   PetscFunctionReturn(0);
383fe39f135SDave May }
384fe39f135SDave May 
385d3a51819SDave May /*@C
386d3a51819SDave May 
387d3a51819SDave May  DMSwarmGetLocalSize - Retrives the local length of fields registered
388d3a51819SDave May 
389d3a51819SDave May  Not collective
390d3a51819SDave May 
391d3a51819SDave May  Input parameter:
392d3a51819SDave May  . dm - a DMSwarm
393d3a51819SDave May 
394d3a51819SDave May  Output parameter:
395d3a51819SDave May  . nlocal - the length of each registered field
396d3a51819SDave May 
397d3a51819SDave May  Level: beginner
398d3a51819SDave May 
399d3a51819SDave May  . seealso: DMSwarmSetLocalSizes()
400d3a51819SDave May 
401d3a51819SDave May @*/
402fe39f135SDave May #undef __FUNCT__
403dcf43ee8SDave May #define __FUNCT__ "DMSwarmGetLocalSize"
404dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal)
405dcf43ee8SDave May {
406dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
407dcf43ee8SDave May   PetscErrorCode ierr;
408dcf43ee8SDave May 
409dcf43ee8SDave May   if (nlocal) {
410dcf43ee8SDave May     ierr = DataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);
411dcf43ee8SDave May   }
412dcf43ee8SDave May 
413dcf43ee8SDave May   PetscFunctionReturn(0);
414dcf43ee8SDave May }
415dcf43ee8SDave May 
416d3a51819SDave May /*@C
417d3a51819SDave May 
418d3a51819SDave May  DMSwarmGetSize - Retrives the total length of fields registered
419d3a51819SDave May 
420d3a51819SDave May  Collective on DM
421d3a51819SDave May 
422d3a51819SDave May  Input parameter:
423d3a51819SDave May  . dm - a DMSwarm
424d3a51819SDave May 
425d3a51819SDave May  Output parameter:
426d3a51819SDave May  . n - the total length of each registered field
427d3a51819SDave May 
428d3a51819SDave May  Level: beginner
429d3a51819SDave May 
430d3a51819SDave May  Note:
431d3a51819SDave May  This calls MPI_Allreduce upon each call (inefficient but safe)
432d3a51819SDave May 
433d3a51819SDave May  . seealso: DMSwarmGetLocalSize()
434d3a51819SDave May 
435d3a51819SDave May @*/
436dcf43ee8SDave May #undef __FUNCT__
437dcf43ee8SDave May #define __FUNCT__ "DMSwarmGetSize"
438dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n)
439dcf43ee8SDave May {
440dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
441dcf43ee8SDave May   PetscErrorCode ierr;
442dcf43ee8SDave May   PetscInt nlocal,ng;
443dcf43ee8SDave May 
444dcf43ee8SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
445dcf43ee8SDave May   ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
446dcf43ee8SDave May   if (n) { *n = ng; }
447dcf43ee8SDave May   PetscFunctionReturn(0);
448dcf43ee8SDave May }
449dcf43ee8SDave May 
450d3a51819SDave May /*@C
451d3a51819SDave May 
452d3a51819SDave May  DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm
453d3a51819SDave May 
454d3a51819SDave May  Collective on DM
455d3a51819SDave May 
456d3a51819SDave May  Input parameters:
457d3a51819SDave May  . dm - a DMSwarm
458d3a51819SDave May  . fieldname - the textual name to identify this field
459d3a51819SDave May  . blocksize - the number of each data type
460d3a51819SDave May  . type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG)
461d3a51819SDave May 
462d3a51819SDave May  Level: beginner
463d3a51819SDave May 
464d3a51819SDave May  Notes:
465d3a51819SDave May  The textual name for each registered field must be unique
466d3a51819SDave May 
467d3a51819SDave May  . seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
468d3a51819SDave May 
469d3a51819SDave May @*/
470dcf43ee8SDave May #undef __FUNCT__
471b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterPetscDatatypeField"
4725f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
473b62e03f8SDave May {
4742eac95f8SDave May   PetscErrorCode ierr;
475b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
476b62e03f8SDave May   size_t size;
477b62e03f8SDave May 
4785f50eb2eSDave May   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
4795f50eb2eSDave May   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
4805f50eb2eSDave May 
4815f50eb2eSDave May   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
4825f50eb2eSDave May   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
4835f50eb2eSDave May   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
4845f50eb2eSDave May   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
4855f50eb2eSDave May   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
486b62e03f8SDave May 
487*2ddcf43eSMatthew G. Knepley   ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr);
488b62e03f8SDave May 
489b62e03f8SDave May   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
49052c3ed93SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
49152c3ed93SDave May   {
49252c3ed93SDave May     DataField gfield;
49352c3ed93SDave May 
49452c3ed93SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
49552c3ed93SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
49652c3ed93SDave May   }
497b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
498b62e03f8SDave May 
499b62e03f8SDave May   PetscFunctionReturn(0);
500b62e03f8SDave May }
501b62e03f8SDave May 
502d3a51819SDave May /*@C
503d3a51819SDave May 
504d3a51819SDave May  DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm
505d3a51819SDave May 
506d3a51819SDave May  Collective on DM
507d3a51819SDave May 
508d3a51819SDave May  Input parameters:
509d3a51819SDave May  . dm - a DMSwarm
510d3a51819SDave May  . fieldname - the textual name to identify this field
511d3a51819SDave May  . size - the size in bytes of the user struct of each data type
512d3a51819SDave May 
513d3a51819SDave May  Level: beginner
514d3a51819SDave May 
515d3a51819SDave May  Notes:
516d3a51819SDave May  The textual name for each registered field must be unique
517d3a51819SDave May 
518d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField()
519d3a51819SDave May 
520d3a51819SDave May @*/
521b62e03f8SDave May #undef __FUNCT__
522b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterUserStructField"
5235f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
524b62e03f8SDave May {
5252eac95f8SDave May   PetscErrorCode ierr;
526b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
527b62e03f8SDave May 
5282eac95f8SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
529b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
530b62e03f8SDave May 
531b62e03f8SDave May   PetscFunctionReturn(0);
532b62e03f8SDave May }
533b62e03f8SDave May 
534d3a51819SDave May /*@C
535d3a51819SDave May 
536d3a51819SDave May  DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm
537d3a51819SDave May 
538d3a51819SDave May  Collective on DM
539d3a51819SDave May 
540d3a51819SDave May  Input parameters:
541d3a51819SDave May  . dm - a DMSwarm
542d3a51819SDave May  . fieldname - the textual name to identify this field
543d3a51819SDave May  . size - the size in bytes of the user data type
544d3a51819SDave May  . blocksize - the number of each data type
545d3a51819SDave May 
546d3a51819SDave May  Level: beginner
547d3a51819SDave May 
548d3a51819SDave May  Notes:
549d3a51819SDave May  The textual name for each registered field must be unique
550d3a51819SDave May 
551d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
552d3a51819SDave May 
553d3a51819SDave May @*/
554b62e03f8SDave May #undef __FUNCT__
555b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterUserDatatypeField"
556320740a0SDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize)
557b62e03f8SDave May {
558b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
5596845f8f5SDave May   PetscErrorCode ierr;
560b62e03f8SDave May 
561320740a0SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
562320740a0SDave May   {
563320740a0SDave May     DataField gfield;
564320740a0SDave May 
565320740a0SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
566320740a0SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
567320740a0SDave May   }
568b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
569b62e03f8SDave May 
570b62e03f8SDave May   PetscFunctionReturn(0);
571b62e03f8SDave May }
572b62e03f8SDave May 
573d3a51819SDave May /*@C
574d3a51819SDave May 
575d3a51819SDave May  DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field
576d3a51819SDave May 
577d3a51819SDave May  Not collective
578d3a51819SDave May 
579d3a51819SDave May  Input parameters:
580d3a51819SDave May  . dm - a DMSwarm
581d3a51819SDave May  . fieldname - the textual name to identify this field
582d3a51819SDave May 
583d3a51819SDave May  Output parameters:
584d3a51819SDave May  . blocksize - the number of each data type
585d3a51819SDave May  . type - the data type
586d3a51819SDave May  . data - pointer to raw array
587d3a51819SDave May 
588d3a51819SDave May  Level: beginner
589d3a51819SDave May 
590d3a51819SDave May  Notes:
591d3a51819SDave May  The user must call DMSwarmRestoreField()
592d3a51819SDave May 
593d3a51819SDave May  . seealso: DMSwarmRestoreField()
594d3a51819SDave May 
595d3a51819SDave May @*/
596b62e03f8SDave May #undef __FUNCT__
597b62e03f8SDave May #define __FUNCT__ "DMSwarmGetField"
5985f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
599b62e03f8SDave May {
600b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
601b62e03f8SDave May   DataField gfield;
6022eac95f8SDave May   PetscErrorCode ierr;
603b62e03f8SDave May 
6043454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
6053454631fSDave May 
6062eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6076845f8f5SDave May   ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr);
6086845f8f5SDave May   ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr);
6091b1ea282SDave May   if (blocksize) {*blocksize = gfield->bs; }
610b5bcf523SDave May   if (type) { *type = gfield->petsc_type; }
611b62e03f8SDave May 
612b62e03f8SDave May   PetscFunctionReturn(0);
613b62e03f8SDave May }
614b62e03f8SDave May 
615d3a51819SDave May /*@C
616d3a51819SDave May 
617d3a51819SDave May  DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field
618d3a51819SDave May 
619d3a51819SDave May  Not collective
620d3a51819SDave May 
621d3a51819SDave May  Input parameters:
622d3a51819SDave May  . dm - a DMSwarm
623d3a51819SDave May  . fieldname - the textual name to identify this field
624d3a51819SDave May 
625d3a51819SDave May  Output parameters:
626d3a51819SDave May  . blocksize - the number of each data type
627d3a51819SDave May  . type - the data type
628d3a51819SDave May  . data - pointer to raw array
629d3a51819SDave May 
630d3a51819SDave May  Level: beginner
631d3a51819SDave May 
632d3a51819SDave May  Notes:
633d3a51819SDave May  The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField()
634d3a51819SDave May 
635d3a51819SDave May  . seealso: DMSwarmGetField()
636d3a51819SDave May 
637d3a51819SDave May @*/
638b62e03f8SDave May #undef __FUNCT__
639b62e03f8SDave May #define __FUNCT__ "DMSwarmRestoreField"
6405f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
641b62e03f8SDave May {
642b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
643b62e03f8SDave May   DataField gfield;
6442eac95f8SDave May   PetscErrorCode ierr;
645b62e03f8SDave May 
6462eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6476845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
648b62e03f8SDave May   if (data) *data = NULL;
649b62e03f8SDave May 
650b62e03f8SDave May   PetscFunctionReturn(0);
651b62e03f8SDave May }
652b62e03f8SDave May 
653d3a51819SDave May /*@C
654d3a51819SDave May 
655d3a51819SDave May  DMSwarmAddPoint - Add space for one new point in the DMSwarm
656d3a51819SDave May 
657d3a51819SDave May  Not collective
658d3a51819SDave May 
659d3a51819SDave May  Input parameter:
660d3a51819SDave May  . dm - a DMSwarm
661d3a51819SDave May 
662d3a51819SDave May  Level: beginner
663d3a51819SDave May 
664d3a51819SDave May  Notes:
665d3a51819SDave May  The new point will have all fields initialized to zero
666d3a51819SDave May 
667d3a51819SDave May  . seealso: DMSwarmAddNPoints()
668d3a51819SDave May 
669d3a51819SDave May @*/
670cb1d1399SDave May #undef __FUNCT__
671cb1d1399SDave May #define __FUNCT__ "DMSwarmAddPoint"
672cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
673cb1d1399SDave May {
674cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
675cb1d1399SDave May   PetscErrorCode ierr;
676cb1d1399SDave May 
6773454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
678cb1d1399SDave May   ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr);
679cb1d1399SDave May   PetscFunctionReturn(0);
680cb1d1399SDave May }
681cb1d1399SDave May 
682d3a51819SDave May /*@C
683d3a51819SDave May 
684d3a51819SDave May  DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm
685d3a51819SDave May 
686d3a51819SDave May  Not collective
687d3a51819SDave May 
688d3a51819SDave May  Input parameters:
689d3a51819SDave May  . dm - a DMSwarm
690d3a51819SDave May  . npoints - the number of new points to add
691d3a51819SDave May 
692d3a51819SDave May  Level: beginner
693d3a51819SDave May 
694d3a51819SDave May  Notes:
695d3a51819SDave May  The new point will have all fields initialized to zero
696d3a51819SDave May 
697d3a51819SDave May  . seealso: DMSwarmAddPoint()
698d3a51819SDave May 
699d3a51819SDave May @*/
700cb1d1399SDave May #undef __FUNCT__
701cb1d1399SDave May #define __FUNCT__ "DMSwarmAddNPoints"
702cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
703cb1d1399SDave May {
704cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
705cb1d1399SDave May   PetscErrorCode ierr;
706cb1d1399SDave May   PetscInt nlocal;
707cb1d1399SDave May 
708cb1d1399SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
709cb1d1399SDave May   nlocal = nlocal + npoints;
710cb1d1399SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,-1);CHKERRQ(ierr);
711cb1d1399SDave May   PetscFunctionReturn(0);
712cb1d1399SDave May }
713cb1d1399SDave May 
714d3a51819SDave May /*@C
715d3a51819SDave May 
716d3a51819SDave May  DMSwarmRemovePoint - Remove the last point from the DMSwarm
717d3a51819SDave May 
718d3a51819SDave May  Not collective
719d3a51819SDave May 
720d3a51819SDave May  Input parameter:
721d3a51819SDave May  . dm - a DMSwarm
722d3a51819SDave May 
723d3a51819SDave May  Level: beginner
724d3a51819SDave May 
725d3a51819SDave May  . seealso: DMSwarmRemovePointAtIndex()
726d3a51819SDave May 
727d3a51819SDave May @*/
728cb1d1399SDave May #undef __FUNCT__
729cb1d1399SDave May #define __FUNCT__ "DMSwarmRemovePoint"
730cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
731cb1d1399SDave May {
732cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
733cb1d1399SDave May   PetscErrorCode ierr;
734cb1d1399SDave May 
735cb1d1399SDave May   ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
736cb1d1399SDave May   PetscFunctionReturn(0);
737cb1d1399SDave May }
738cb1d1399SDave May 
739d3a51819SDave May /*@C
740d3a51819SDave May 
741d3a51819SDave May  DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm
742d3a51819SDave May 
743d3a51819SDave May  Not collective
744d3a51819SDave May 
745d3a51819SDave May  Input parameters:
746d3a51819SDave May  . dm - a DMSwarm
747d3a51819SDave May  . idx - index of point to remove
748d3a51819SDave May 
749d3a51819SDave May  Level: beginner
750d3a51819SDave May 
751d3a51819SDave May  . seealso: DMSwarmRemovePoint()
752d3a51819SDave May 
753d3a51819SDave May @*/
754cb1d1399SDave May #undef __FUNCT__
755cb1d1399SDave May #define __FUNCT__ "DMSwarmRemovePointAtIndex"
756cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
757cb1d1399SDave May {
758cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
759cb1d1399SDave May   PetscErrorCode ierr;
760cb1d1399SDave May 
761cb1d1399SDave May   ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
762cb1d1399SDave May   PetscFunctionReturn(0);
763cb1d1399SDave May }
764b62e03f8SDave May 
7653454631fSDave May #undef __FUNCT__
766095059a4SDave May #define __FUNCT__ "DMSwarmMigrate_Basic"
767095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points)
7683454631fSDave May {
769dcf43ee8SDave May   PetscErrorCode ierr;
770dcf43ee8SDave May   ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr);
7713454631fSDave May   PetscFunctionReturn(0);
7723454631fSDave May }
7733454631fSDave May 
774f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_CellDMScatter(DM dm,PetscBool remove_sent_points);
775f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_CellDMExact(DM dm,PetscBool remove_sent_points);
776f0cdbbbaSDave May 
777d3a51819SDave May /*@C
778d3a51819SDave May 
779d3a51819SDave May  DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks
780d3a51819SDave May 
781d3a51819SDave May  Collective on DM
782d3a51819SDave May 
783d3a51819SDave May  Input parameters:
784d3a51819SDave May  . dm - the DMSwarm
785d3a51819SDave May  . remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank
786d3a51819SDave May 
787d3a51819SDave May  Notes:
788d3a51819SDave May  The DM wil be modified to accomodate received points.
789d3a51819SDave May  If remove_sent_points = PETSC_TRUE, send points will be removed from the DM
790d3a51819SDave May  Different styles of migration are supported. See DMSwarmSetMigrateType()
791d3a51819SDave May 
792d3a51819SDave May  Level: advanced
793d3a51819SDave May 
794d3a51819SDave May  . seealso: DMSwarmSetMigrateType()
795d3a51819SDave May 
796d3a51819SDave May @*/
7973454631fSDave May #undef __FUNCT__
798095059a4SDave May #define __FUNCT__ "DMSwarmMigrate"
799095059a4SDave May PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points)
8003454631fSDave May {
801f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8023454631fSDave May   PetscErrorCode ierr;
803f0cdbbbaSDave May 
804f0cdbbbaSDave May   switch (swarm->migrate_type) {
805f0cdbbbaSDave May 
806f0cdbbbaSDave May     case DMSWARM_MIGRATE_BASIC:
807095059a4SDave May       ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr);
808f0cdbbbaSDave May       break;
809f0cdbbbaSDave May 
810f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLNSCATTER:
811f0cdbbbaSDave May       ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr);
812f0cdbbbaSDave May       break;
813f0cdbbbaSDave May 
814f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLEXACT:
815f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented");
816f0cdbbbaSDave May       //ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr);
817f0cdbbbaSDave May       break;
818f0cdbbbaSDave May 
819f0cdbbbaSDave May     case DMSWARM_MIGRATE_USER:
820f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented");
821f0cdbbbaSDave May       //ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr);
822f0cdbbbaSDave May       break;
823f0cdbbbaSDave May 
824f0cdbbbaSDave May     default:
825f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown");
826f0cdbbbaSDave May       break;
827f0cdbbbaSDave May   }
8283454631fSDave May   PetscFunctionReturn(0);
8293454631fSDave May }
8303454631fSDave May 
831f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize);
832f0cdbbbaSDave May 
833d3a51819SDave May /*
834d3a51819SDave May  DMSwarmCollectViewCreate
835d3a51819SDave May 
836d3a51819SDave May  * Applies a collection method and gathers point neighbour points into dm
837d3a51819SDave May 
838d3a51819SDave May  Notes:
839d3a51819SDave May  - Users should call DMSwarmCollectViewDestroy() after
840d3a51819SDave May  they have finished computations associated with the collected points
841d3a51819SDave May */
842d3a51819SDave May 
843d3a51819SDave May /*@C
844d3a51819SDave May 
845d3a51819SDave May  DMSwarmCollectViewCreate - Applies a collection method and gathers points
846d3a51819SDave May  in neighbour MPI-ranks into the DMSwarm
847d3a51819SDave May 
848d3a51819SDave May  Collective on DM
849d3a51819SDave May 
850d3a51819SDave May  Input parameter:
851d3a51819SDave May  . dm - the DMSwarm
852d3a51819SDave May 
853d3a51819SDave May  Notes:
854d3a51819SDave May  Users should call DMSwarmCollectViewDestroy() after
855d3a51819SDave May  they have finished computations associated with the collected points
856d3a51819SDave May  Different collect methods are supported. See DMSwarmSetCollectType()
857d3a51819SDave May 
858d3a51819SDave May  Level: advanced
859d3a51819SDave May 
860d3a51819SDave May  . seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType()
861d3a51819SDave May 
862d3a51819SDave May @*/
8632712d1f2SDave May #undef __FUNCT__
864fe39f135SDave May #define __FUNCT__ "DMSwarmCollectViewCreate"
865fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm)
8662712d1f2SDave May {
8672712d1f2SDave May   PetscErrorCode ierr;
8682712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8692712d1f2SDave May   PetscInt ng;
8702712d1f2SDave May 
871480eef7bSDave May   if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active");
8722712d1f2SDave May 
873480eef7bSDave May   ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr);
874480eef7bSDave May   switch (swarm->collect_type) {
875f0cdbbbaSDave May 
876480eef7bSDave May     case DMSWARM_COLLECT_BASIC:
8772712d1f2SDave May       ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr);
878480eef7bSDave May       break;
879f0cdbbbaSDave May 
880480eef7bSDave May     case DMSWARM_COLLECT_DMDABOUNDINGBOX:
881f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented");
882fe39f135SDave May       //ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr);
883480eef7bSDave May       break;
884f0cdbbbaSDave May 
885480eef7bSDave May     case DMSWARM_COLLECT_GENERAL:
886f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented");
887fe39f135SDave May       //ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr);
888480eef7bSDave May       break;
889480eef7bSDave May 
890480eef7bSDave May     default:
891f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown");
892480eef7bSDave May       break;
893480eef7bSDave May   }
894480eef7bSDave May 
895480eef7bSDave May   swarm->collect_view_active = PETSC_TRUE;
896480eef7bSDave May   swarm->collect_view_reset_nlocal = ng;
8972712d1f2SDave May 
8982712d1f2SDave May   PetscFunctionReturn(0);
8992712d1f2SDave May }
9002712d1f2SDave May 
901d3a51819SDave May /*@C
902d3a51819SDave May 
903d3a51819SDave May  DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate()
904d3a51819SDave May 
905d3a51819SDave May  Collective on DM
906d3a51819SDave May 
907d3a51819SDave May  Input parameters:
908d3a51819SDave May  . dm - the DMSwarm
909d3a51819SDave May 
910d3a51819SDave May  Notes:
911d3a51819SDave May  Users should call DMSwarmCollectViewCreate() before this function is called.
912d3a51819SDave May 
913d3a51819SDave May  Level: advanced
914d3a51819SDave May 
915d3a51819SDave May  . seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType()
916d3a51819SDave May 
917d3a51819SDave May @*/
9182712d1f2SDave May #undef __FUNCT__
919fe39f135SDave May #define __FUNCT__ "DMSwarmCollectViewDestroy"
920fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm)
9212712d1f2SDave May {
9222712d1f2SDave May   PetscErrorCode ierr;
9232712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9242712d1f2SDave May 
925480eef7bSDave May   if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active");
926480eef7bSDave May   ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr);
927480eef7bSDave May   swarm->collect_view_active = PETSC_FALSE;
9282712d1f2SDave May 
9292712d1f2SDave May   PetscFunctionReturn(0);
9302712d1f2SDave May }
9313454631fSDave May 
9323454631fSDave May #undef __FUNCT__
933f0cdbbbaSDave May #define __FUNCT__ "DMSwarmSetUpPIC"
934f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm)
935f0cdbbbaSDave May {
936f0cdbbbaSDave May   PetscInt dim;
937f0cdbbbaSDave May   PetscErrorCode ierr;
938f0cdbbbaSDave May 
939f0cdbbbaSDave May   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
940f0cdbbbaSDave May   if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
941f0cdbbbaSDave May   if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
942f0cdbbbaSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr);
943f0cdbbbaSDave May   PetscFunctionReturn(0);
944f0cdbbbaSDave May }
945f0cdbbbaSDave May 
946d3a51819SDave May /*@C
947d3a51819SDave May 
948d3a51819SDave May  DMSwarmSetType - Set particular flavor of DMSwarm
949d3a51819SDave May 
950d3a51819SDave May  Collective on DM
951d3a51819SDave May 
952d3a51819SDave May  Input parameters:
953d3a51819SDave May  . dm - the DMSwarm
954d3a51819SDave May  . stype - the DMSwarm type (e.g. DMSWARM_PIC)
955d3a51819SDave May 
956d3a51819SDave May  Level: advanced
957d3a51819SDave May 
958d3a51819SDave May  . seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType()
959d3a51819SDave May 
960d3a51819SDave May @*/
961cac75b86SDave May #undef __FUNCT__
962f0cdbbbaSDave May #define __FUNCT__ "DMSwarmSetType"
963f0cdbbbaSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype)
964f0cdbbbaSDave May {
965f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
966f0cdbbbaSDave May   PetscErrorCode ierr;
967f0cdbbbaSDave May 
968f0cdbbbaSDave May   swarm->swarm_type = stype;
969f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
970f0cdbbbaSDave May     ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr);
971f0cdbbbaSDave May   }
972f0cdbbbaSDave May   PetscFunctionReturn(0);
973f0cdbbbaSDave May }
974f0cdbbbaSDave May 
975f0cdbbbaSDave May #undef __FUNCT__
9763454631fSDave May #define __FUNCT__ "DMSetup_Swarm"
9773454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm)
9783454631fSDave May {
9793454631fSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9803454631fSDave May   PetscErrorCode ierr;
9813454631fSDave May   PetscMPIInt rank;
9823454631fSDave May   PetscInt p,npoints,*rankval;
9833454631fSDave May 
9843454631fSDave May   if (swarm->issetup) PetscFunctionReturn(0);
9853454631fSDave May 
9863454631fSDave May   swarm->issetup = PETSC_TRUE;
9873454631fSDave May 
988f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
989f0cdbbbaSDave May     /* check dmcell exists */
990f0cdbbbaSDave May     if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM");
991f0cdbbbaSDave May 
992f0cdbbbaSDave May     if (swarm->dmcell->ops->locatepointssubdomain) {
993f0cdbbbaSDave May       /* check methods exists for exact ownership identificiation */
994f0cdbbbaSDave May       PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");
995f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT;
996f0cdbbbaSDave May     } else {
997f0cdbbbaSDave May       /* check methods exist for point location AND rank neighbor identification */
998f0cdbbbaSDave May       if (swarm->dmcell->ops->locatepoints) {
999f0cdbbbaSDave May         PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->LocatePoints\n");
1000f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined");
1001f0cdbbbaSDave May 
1002f0cdbbbaSDave May       if (swarm->dmcell->ops->getneighbors) {
1003f0cdbbbaSDave May         PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->GetNeigbors\n");
1004f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined");
1005f0cdbbbaSDave May 
1006f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER;
1007f0cdbbbaSDave May     }
1008f0cdbbbaSDave May   }
1009f0cdbbbaSDave May 
1010f0cdbbbaSDave May   ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr);
1011f0cdbbbaSDave May 
10123454631fSDave May   /* check some fields were registered */
10133454631fSDave May   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
10143454631fSDave May 
10153454631fSDave May   /* check local sizes were set */
10163454631fSDave May   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
10173454631fSDave May 
10183454631fSDave May   /* initialize values in pid and rank placeholders */
10193454631fSDave May   /* TODO: [pid - use MPI_Scan] */
10203454631fSDave May 
10213454631fSDave May   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
10223454631fSDave May   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
1023f0cdbbbaSDave May   ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10243454631fSDave May   for (p=0; p<npoints; p++) {
10253454631fSDave May     rankval[p] = (PetscInt)rank;
10263454631fSDave May   }
1027f0cdbbbaSDave May   ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10283454631fSDave May 
10293454631fSDave May   PetscFunctionReturn(0);
10303454631fSDave May }
10313454631fSDave May 
1032b62e03f8SDave May #undef __FUNCT__
103357795646SDave May #define __FUNCT__ "DMDestroy_Swarm"
103457795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm)
103557795646SDave May {
103657795646SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
103757795646SDave May   PetscErrorCode ierr;
103857795646SDave May 
103957795646SDave May   PetscFunctionBegin;
10406845f8f5SDave May   ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr);
104157795646SDave May   ierr = PetscFree(swarm);CHKERRQ(ierr);
104257795646SDave May   PetscFunctionReturn(0);
104357795646SDave May }
104457795646SDave May 
104557795646SDave May #undef __FUNCT__
10465f50eb2eSDave May #define __FUNCT__ "DMView_Swarm"
10475f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
10485f50eb2eSDave May {
10495f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
10505f50eb2eSDave May   PetscBool      iascii,ibinary,ishdf5,isvtk;
10515f50eb2eSDave May   PetscErrorCode ierr;
10525f50eb2eSDave May 
10535f50eb2eSDave May   PetscFunctionBegin;
10545f50eb2eSDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10555f50eb2eSDave May   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
10565f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
10575f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
10585f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
10595f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
10605f50eb2eSDave May   if (iascii) {
10616845f8f5SDave May     ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
10625f50eb2eSDave May   } else if (ibinary) {
10635f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
10645f50eb2eSDave May   } else if (ishdf5) {
10655f50eb2eSDave May #if defined(PETSC_HAVE_HDF5)
10665f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
10675f50eb2eSDave May #else
10685f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
10695f50eb2eSDave May #endif
10705f50eb2eSDave May   } else if (isvtk) {
10715f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
10725f50eb2eSDave May   }
10735f50eb2eSDave May   PetscFunctionReturn(0);
10745f50eb2eSDave May }
10755f50eb2eSDave May 
1076d3a51819SDave May /*MC
1077d3a51819SDave May 
1078d3a51819SDave May  DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type.
1079d3a51819SDave May  This implementation was designed for particle-in-cell type methods in which the underlying
1080d3a51819SDave May  data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type.
1081d3a51819SDave May 
1082d3a51819SDave May  User data can be represented by DMSwarm through a registring "fields".
1083d3a51819SDave May  To register a field, the user must provide:
1084d3a51819SDave May  (a) a unique name
1085d3a51819SDave May  (b) the data type (or size in bytes)
1086d3a51819SDave May  (c) the block size of the data
1087d3a51819SDave May 
1088d3a51819SDave May  For example, suppose the application requires a unique id, energy, momentum and density to be stored
1089d3a51819SDave May  on a set of of particles. Then the following application could be used
1090d3a51819SDave May 
1091d3a51819SDave May  DMSwarmInitializeFieldRegister(dm)
1092d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG);
1093d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL);
1094d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL);
1095d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT);
1096d3a51819SDave May  DMSwarmFinalizeFieldRegister(dm)
1097d3a51819SDave May 
1098d3a51819SDave May  The fields represented by DMSwarm are dynamic and can be re-sized at any time.
1099d3a51819SDave May  The only restriction imposed by DMSwarm is that all fields contain the same number of points
1100d3a51819SDave May 
1101d3a51819SDave May  To support particle methods, "migration" techniques are provided. These methods migrate data
1102d3a51819SDave May  between MPI-ranks.
1103d3a51819SDave May 
1104d3a51819SDave May  DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector().
1105d3a51819SDave May  As a DMSwarm may internally define and store values of different data types,
1106d3a51819SDave May  before calling DMCreate{Global/Local}Vector() the user must inform DMSwarm which
1107d3a51819SDave May  fields should be used to define a Vec object via
1108d3a51819SDave May    DMSwarmVectorDefineField()
1109d3a51819SDave May  The specified field can can changed be changed at any time - thereby permitting vectors
1110d3a51819SDave May  compatable with different fields to be created.
1111d3a51819SDave May 
1112d3a51819SDave May  A dual representation of fields in the DMSwarm and a Vec object are permitted via
1113d3a51819SDave May    DMSwarmCreateGlobalVectorFromField()
1114d3a51819SDave May  Here the data defining the field in the DMSwarm is shared with a Vec.
1115d3a51819SDave May  This is inherently unsafe if you alter the size of the field at any time between
1116d3a51819SDave May  calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField().
1117cc651181SDave May  If the local size of the DMSwarm does not match the localsize of the global vector
1118cc651181SDave May  when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown.
1119d3a51819SDave May 
1120d3a51819SDave May  Level: beginner
1121d3a51819SDave May 
1122d3a51819SDave May  .seealso: DMType, DMCreate(), DMSetType()
1123d3a51819SDave May 
1124d3a51819SDave May M*/
11255f50eb2eSDave May #undef __FUNCT__
112657795646SDave May #define __FUNCT__ "DMCreate_Swarm"
112757795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
112857795646SDave May {
112957795646SDave May   DM_Swarm      *swarm;
113057795646SDave May   PetscErrorCode ierr;
113157795646SDave May 
113257795646SDave May   PetscFunctionBegin;
113357795646SDave May   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
113457795646SDave May   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
1135f0cdbbbaSDave May   dm->data = swarm;
113657795646SDave May 
11376845f8f5SDave May   ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr);
1138f0cdbbbaSDave May   ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr);
1139f0cdbbbaSDave May 
1140b5bcf523SDave May   swarm->vec_field_set = PETSC_FALSE;
11413454631fSDave May   swarm->issetup = PETSC_FALSE;
1142480eef7bSDave May   swarm->swarm_type = DMSWARM_BASIC;
1143480eef7bSDave May   swarm->migrate_type = DMSWARM_MIGRATE_BASIC;
1144480eef7bSDave May   swarm->collect_type = DMSWARM_COLLECT_BASIC;
114540c453e9SDave May   swarm->migrate_error_on_missing_point = PETSC_FALSE;
1146b62e03f8SDave May 
1147f0cdbbbaSDave May   swarm->dmcell = NULL;
1148f0cdbbbaSDave May   swarm->collect_view_active = PETSC_FALSE;
1149f0cdbbbaSDave May   swarm->collect_view_reset_nlocal = -1;
115057795646SDave May 
1151f0cdbbbaSDave May   dm->dim  = 0;
11525f50eb2eSDave May   dm->ops->view                            = DMView_Swarm;
115357795646SDave May   dm->ops->load                            = NULL;
115457795646SDave May   dm->ops->setfromoptions                  = NULL;
115557795646SDave May   dm->ops->clone                           = NULL;
11563454631fSDave May   dm->ops->setup                           = DMSetup_Swarm;
115757795646SDave May   dm->ops->createdefaultsection            = NULL;
115857795646SDave May   dm->ops->createdefaultconstraints        = NULL;
1159b5bcf523SDave May   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
1160b5bcf523SDave May   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
116157795646SDave May   dm->ops->getlocaltoglobalmapping         = NULL;
116257795646SDave May   dm->ops->createfieldis                   = NULL;
116357795646SDave May   dm->ops->createcoordinatedm              = NULL;
116457795646SDave May   dm->ops->getcoloring                     = NULL;
116557795646SDave May   dm->ops->creatematrix                    = NULL;
116657795646SDave May   dm->ops->createinterpolation             = NULL;
116757795646SDave May   dm->ops->getaggregates                   = NULL;
116857795646SDave May   dm->ops->getinjection                    = NULL;
116957795646SDave May   dm->ops->refine                          = NULL;
117057795646SDave May   dm->ops->coarsen                         = NULL;
117157795646SDave May   dm->ops->refinehierarchy                 = NULL;
117257795646SDave May   dm->ops->coarsenhierarchy                = NULL;
117357795646SDave May   dm->ops->globaltolocalbegin              = NULL;
117457795646SDave May   dm->ops->globaltolocalend                = NULL;
117557795646SDave May   dm->ops->localtoglobalbegin              = NULL;
117657795646SDave May   dm->ops->localtoglobalend                = NULL;
117757795646SDave May   dm->ops->destroy                         = DMDestroy_Swarm;
117857795646SDave May   dm->ops->createsubdm                     = NULL;
117957795646SDave May   dm->ops->getdimpoints                    = NULL;
118057795646SDave May   dm->ops->locatepoints                    = NULL;
118157795646SDave May 
118257795646SDave May   PetscFunctionReturn(0);
118357795646SDave May }