xref: /petsc/src/dm/impls/swarm/swarm.c (revision bbe8250be0a3a1853856323c848bd4e50d115766)
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   *vec = x;
165b5bcf523SDave May   PetscFunctionReturn(0);
166b5bcf523SDave May }
167b5bcf523SDave May 
168d3a51819SDave May 
169d3a51819SDave May /*@C
170d3a51819SDave May 
171d3a51819SDave May  DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field
172d3a51819SDave May 
173d3a51819SDave May  Collective on DM
174d3a51819SDave May 
175d3a51819SDave May  Input parameters:
176d3a51819SDave May  . dm - a DMSwarm
177d3a51819SDave May  . fieldname - the textual name given to a registered field
178d3a51819SDave May 
179d3a51819SDave May  Output parameters:
180d3a51819SDave May  . vec - the vector
181d3a51819SDave May 
182d3a51819SDave May  Level: beginner
183d3a51819SDave May 
184d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField()
185d3a51819SDave May 
186d3a51819SDave May @*/
187b5bcf523SDave May #undef __FUNCT__
188b5bcf523SDave May #define __FUNCT__ "DMSwarmDestroyGlobalVectorFromField"
189b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
190b5bcf523SDave May {
191b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
192b5bcf523SDave May   PetscErrorCode ierr;
193b5bcf523SDave May   DataField gfield;
194b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
195b5bcf523SDave May   void (*fptr)(void);
196cc651181SDave May   PetscInt bs,nlocal;
197cc651181SDave May 
198cc651181SDave May   ierr = VecGetLocalSize(*vec,&nlocal);CHKERRQ(ierr);
199cc651181SDave May   ierr = VecGetBlockSize(*vec,&bs);CHKERRQ(ierr);
200cc651181SDave 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 */
201b5bcf523SDave May 
202b5bcf523SDave May   /* get data field */
2032eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
204b5bcf523SDave May 
205b5bcf523SDave May   /* check vector is an inplace array */
206b5bcf523SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarm_VecFieldInPlace_%s",fieldname);
207b5bcf523SDave May   ierr = PetscObjectQueryFunction((PetscObject)(*vec),name,&fptr);CHKERRQ(ierr);
208b5bcf523SDave May   if (!fptr) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Vector being destroyed was not created from DMSwarm field(%s)",fieldname);
209b5bcf523SDave May 
210b5bcf523SDave May   /* restore data field */
2116845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
212b5bcf523SDave May 
213b5bcf523SDave May   ierr = VecDestroy(vec);CHKERRQ(ierr);
214b5bcf523SDave May 
215b5bcf523SDave May   PetscFunctionReturn(0);
216b5bcf523SDave May }
217b5bcf523SDave May 
218*bbe8250bSMatthew G. Knepley #undef __FUNCT__
219*bbe8250bSMatthew G. Knepley #define __FUNCT__ "DMSwarmCreateGlobalVector"
220*bbe8250bSMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVector(DM dm, const char fieldname[], Vec *vec)
221*bbe8250bSMatthew G. Knepley {
222*bbe8250bSMatthew G. Knepley   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
223*bbe8250bSMatthew G. Knepley   PetscScalar   *array;
224*bbe8250bSMatthew G. Knepley   PetscInt       bs,n;
225*bbe8250bSMatthew G. Knepley   PetscMPIInt    commsize;
226*bbe8250bSMatthew G. Knepley   PetscErrorCode ierr;
227*bbe8250bSMatthew G. Knepley 
228*bbe8250bSMatthew G. Knepley   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
229*bbe8250bSMatthew G. Knepley 
230*bbe8250bSMatthew G. Knepley   ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr);
231*bbe8250bSMatthew G. Knepley   ierr = DMSwarmGetField(dm,fieldname,&bs,NULL,(void**) &array);CHKERRQ(ierr);
232*bbe8250bSMatthew G. Knepley   ierr = DMSwarmRestoreField(dm,fieldname,&bs,NULL,(void**) &array);CHKERRQ(ierr);
233*bbe8250bSMatthew G. Knepley   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&commsize);CHKERRQ(ierr);
234*bbe8250bSMatthew G. Knepley   if (commsize == 1) {
235*bbe8250bSMatthew G. Knepley     ierr = VecCreateSeq(PetscObjectComm((PetscObject)dm),n*bs,vec);CHKERRQ(ierr);
236*bbe8250bSMatthew G. Knepley     ierr = VecSetBlockSize(*vec,bs);CHKERRQ(ierr);
237*bbe8250bSMatthew G. Knepley   } else {
238*bbe8250bSMatthew G. Knepley     ierr = VecCreateMPI(PetscObjectComm((PetscObject)dm),n*bs,PETSC_DETERMINE,vec);CHKERRQ(ierr);
239*bbe8250bSMatthew G. Knepley     ierr = VecSetBlockSize(*vec,bs);CHKERRQ(ierr);
240*bbe8250bSMatthew G. Knepley   }
241*bbe8250bSMatthew G. Knepley   PetscFunctionReturn(0);
242*bbe8250bSMatthew G. Knepley }
243*bbe8250bSMatthew G. Knepley 
244b5bcf523SDave May /*
245b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec)
246b5bcf523SDave May {
247b5bcf523SDave May   PetscFunctionReturn(0);
248b5bcf523SDave May }
249b5bcf523SDave May 
250b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec)
251b5bcf523SDave May {
252b5bcf523SDave May   PetscFunctionReturn(0);
253b5bcf523SDave May }
254b5bcf523SDave May */
255b5bcf523SDave May 
256d3a51819SDave May 
257d3a51819SDave May /*@C
258d3a51819SDave May 
259d3a51819SDave May  DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm
260d3a51819SDave May 
261d3a51819SDave May  Collective on DM
262d3a51819SDave May 
263d3a51819SDave May  Input parameter:
264d3a51819SDave May  . dm - a DMSwarm
265d3a51819SDave May 
266d3a51819SDave May  Level: beginner
267d3a51819SDave May 
268d3a51819SDave May  Notes:
269d3a51819SDave May  After all fields have been registered, users should call DMSwarmFinalizeFieldRegister()
270d3a51819SDave May 
271d3a51819SDave May  . seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
272d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
273d3a51819SDave May 
274d3a51819SDave May @*/
275b5bcf523SDave May #undef __FUNCT__
2765f50eb2eSDave May #define __FUNCT__ "DMSwarmInitializeFieldRegister"
2775f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm)
2785f50eb2eSDave May {
2795f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
2803454631fSDave May   PetscErrorCode ierr;
2813454631fSDave May 
282cc651181SDave May   if (!swarm->field_registration_initialized) {
2835f50eb2eSDave May     swarm->field_registration_initialized = PETSC_TRUE;
284f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */
285f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */
286cc651181SDave May   }
2873454631fSDave May 
2885f50eb2eSDave May   PetscFunctionReturn(0);
2895f50eb2eSDave May }
2905f50eb2eSDave May 
291d3a51819SDave May /*@C
292d3a51819SDave May 
293d3a51819SDave May  DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm
294d3a51819SDave May 
295d3a51819SDave May  Collective on DM
296d3a51819SDave May 
297d3a51819SDave May  Input parameter:
298d3a51819SDave May  . dm - a DMSwarm
299d3a51819SDave May 
300d3a51819SDave May  Level: beginner
301d3a51819SDave May 
302d3a51819SDave May  Notes:
303d3a51819SDave May  After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined
304d3a51819SDave May  on the DMSwarm
305d3a51819SDave May 
306d3a51819SDave May  . seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
307d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
308d3a51819SDave May 
309d3a51819SDave May @*/
3105f50eb2eSDave May #undef __FUNCT__
3115f50eb2eSDave May #define __FUNCT__ "DMSwarmFinalizeFieldRegister"
3125f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm)
3135f50eb2eSDave May {
3145f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3156845f8f5SDave May   PetscErrorCode ierr;
3166845f8f5SDave May 
317f0cdbbbaSDave May   if (!swarm->field_registration_finalized) {
3186845f8f5SDave May     ierr = DataBucketFinalize(swarm->db);CHKERRQ(ierr);
319f0cdbbbaSDave May   }
320f0cdbbbaSDave May   swarm->field_registration_finalized = PETSC_TRUE;
3215f50eb2eSDave May   PetscFunctionReturn(0);
3225f50eb2eSDave May }
3235f50eb2eSDave May 
324d3a51819SDave May /*@C
325d3a51819SDave May 
326d3a51819SDave May  DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm
327d3a51819SDave May 
328d3a51819SDave May  Not collective
329d3a51819SDave May 
330d3a51819SDave May  Input parameters:
331d3a51819SDave May  . dm - a DMSwarm
332d3a51819SDave May  . nlocal - the length of each registered field
333d3a51819SDave May  . buffer - the length of the buffer used to efficient dynamic re-sizing
334d3a51819SDave May 
335d3a51819SDave May  Level: beginner
336d3a51819SDave May 
337d3a51819SDave May  . seealso: DMSwarmGetLocalSize()
338d3a51819SDave May 
339d3a51819SDave May @*/
3405f50eb2eSDave May #undef __FUNCT__
3415f50eb2eSDave May #define __FUNCT__ "DMSwarmSetLocalSizes"
3425f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer)
3435f50eb2eSDave May {
3445f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3456845f8f5SDave May   PetscErrorCode ierr;
3465f50eb2eSDave May 
3476845f8f5SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr);
3485f50eb2eSDave May 
3495f50eb2eSDave May   PetscFunctionReturn(0);
3505f50eb2eSDave May }
3515f50eb2eSDave May 
352d3a51819SDave May /*@C
353d3a51819SDave May 
354d3a51819SDave May  DMSwarmSetCellDM - Attachs a DM to a DMSwarm
355d3a51819SDave May 
356d3a51819SDave May  Collective on DM
357d3a51819SDave May 
358d3a51819SDave May  Input parameters:
359d3a51819SDave May  . dm - a DMSwarm
360d3a51819SDave May  . dmcell - the DM to attach to the DMSwarm
361d3a51819SDave May 
362d3a51819SDave May  Level: beginner
363d3a51819SDave May 
364d3a51819SDave May  Notes:
365d3a51819SDave May  The attached DM (dmcell) will be queried for pointlocation and
366d3a51819SDave May  neighbor MPI-rank information if DMSwarmMigrate() is called
367d3a51819SDave May 
368d3a51819SDave May  . seealso: DMSwarmGetCellDM(), DMSwarmMigrate()
369d3a51819SDave May 
370d3a51819SDave May @*/
3715f50eb2eSDave May #undef __FUNCT__
372b16650c8SDave May #define __FUNCT__ "DMSwarmSetCellDM"
373b16650c8SDave May PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell)
374b16650c8SDave May {
375b16650c8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
376b16650c8SDave May   swarm->dmcell = dmcell;
377b16650c8SDave May   PetscFunctionReturn(0);
378b16650c8SDave May }
379b16650c8SDave May 
380d3a51819SDave May /*@C
381d3a51819SDave May 
382d3a51819SDave May  DMSwarmGetCellDM - Fetches the attached cell DM
383d3a51819SDave May 
384d3a51819SDave May  Collective on DM
385d3a51819SDave May 
386d3a51819SDave May  Input parameter:
387d3a51819SDave May  . dm - a DMSwarm
388d3a51819SDave May 
389d3a51819SDave May  Output parameter:
390d3a51819SDave May  . dmcell - the DM which was attached to the DMSwarm
391d3a51819SDave May 
392d3a51819SDave May  Level: beginner
393d3a51819SDave May 
394d3a51819SDave May  Notes:
395d3a51819SDave May  The attached DM (dmcell) will be queried for pointlocation and
396d3a51819SDave May  neighbor MPI-rank information if DMSwarmMigrate() is called
397d3a51819SDave May 
398d3a51819SDave May  . seealso: DMSwarmSetCellDM()
399d3a51819SDave May 
400d3a51819SDave May @*/
401b16650c8SDave May #undef __FUNCT__
402fe39f135SDave May #define __FUNCT__ "DMSwarmGetCellDM"
403fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell)
404fe39f135SDave May {
405fe39f135SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
406fe39f135SDave May   *dmcell = swarm->dmcell;
407fe39f135SDave May   PetscFunctionReturn(0);
408fe39f135SDave May }
409fe39f135SDave May 
410d3a51819SDave May /*@C
411d3a51819SDave May 
412d3a51819SDave May  DMSwarmGetLocalSize - Retrives the local length of fields registered
413d3a51819SDave May 
414d3a51819SDave May  Not collective
415d3a51819SDave May 
416d3a51819SDave May  Input parameter:
417d3a51819SDave May  . dm - a DMSwarm
418d3a51819SDave May 
419d3a51819SDave May  Output parameter:
420d3a51819SDave May  . nlocal - the length of each registered field
421d3a51819SDave May 
422d3a51819SDave May  Level: beginner
423d3a51819SDave May 
424d3a51819SDave May  . seealso: DMSwarmSetLocalSizes()
425d3a51819SDave May 
426d3a51819SDave May @*/
427fe39f135SDave May #undef __FUNCT__
428dcf43ee8SDave May #define __FUNCT__ "DMSwarmGetLocalSize"
429dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal)
430dcf43ee8SDave May {
431dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
432dcf43ee8SDave May   PetscErrorCode ierr;
433dcf43ee8SDave May 
434dcf43ee8SDave May   if (nlocal) {
435dcf43ee8SDave May     ierr = DataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);
436dcf43ee8SDave May   }
437dcf43ee8SDave May 
438dcf43ee8SDave May   PetscFunctionReturn(0);
439dcf43ee8SDave May }
440dcf43ee8SDave May 
441d3a51819SDave May /*@C
442d3a51819SDave May 
443d3a51819SDave May  DMSwarmGetSize - Retrives the total length of fields registered
444d3a51819SDave May 
445d3a51819SDave May  Collective on DM
446d3a51819SDave May 
447d3a51819SDave May  Input parameter:
448d3a51819SDave May  . dm - a DMSwarm
449d3a51819SDave May 
450d3a51819SDave May  Output parameter:
451d3a51819SDave May  . n - the total length of each registered field
452d3a51819SDave May 
453d3a51819SDave May  Level: beginner
454d3a51819SDave May 
455d3a51819SDave May  Note:
456d3a51819SDave May  This calls MPI_Allreduce upon each call (inefficient but safe)
457d3a51819SDave May 
458d3a51819SDave May  . seealso: DMSwarmGetLocalSize()
459d3a51819SDave May 
460d3a51819SDave May @*/
461dcf43ee8SDave May #undef __FUNCT__
462dcf43ee8SDave May #define __FUNCT__ "DMSwarmGetSize"
463dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n)
464dcf43ee8SDave May {
465dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
466dcf43ee8SDave May   PetscErrorCode ierr;
467dcf43ee8SDave May   PetscInt nlocal,ng;
468dcf43ee8SDave May 
469dcf43ee8SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
470dcf43ee8SDave May   ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
471dcf43ee8SDave May   if (n) { *n = ng; }
472dcf43ee8SDave May   PetscFunctionReturn(0);
473dcf43ee8SDave May }
474dcf43ee8SDave May 
475d3a51819SDave May /*@C
476d3a51819SDave May 
477d3a51819SDave May  DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm
478d3a51819SDave May 
479d3a51819SDave May  Collective on DM
480d3a51819SDave May 
481d3a51819SDave May  Input parameters:
482d3a51819SDave May  . dm - a DMSwarm
483d3a51819SDave May  . fieldname - the textual name to identify this field
484d3a51819SDave May  . blocksize - the number of each data type
485d3a51819SDave May  . type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG)
486d3a51819SDave May 
487d3a51819SDave May  Level: beginner
488d3a51819SDave May 
489d3a51819SDave May  Notes:
490d3a51819SDave May  The textual name for each registered field must be unique
491d3a51819SDave May 
492d3a51819SDave May  . seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
493d3a51819SDave May 
494d3a51819SDave May @*/
495dcf43ee8SDave May #undef __FUNCT__
496b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterPetscDatatypeField"
4975f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
498b62e03f8SDave May {
4992eac95f8SDave May   PetscErrorCode ierr;
500b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
501b62e03f8SDave May   size_t size;
502b62e03f8SDave May 
5035f50eb2eSDave May   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
5045f50eb2eSDave May   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
5055f50eb2eSDave May 
5065f50eb2eSDave May   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5075f50eb2eSDave May   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5085f50eb2eSDave May   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5095f50eb2eSDave May   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5105f50eb2eSDave May   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
511b62e03f8SDave May 
5122ddcf43eSMatthew G. Knepley   ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr);
513b62e03f8SDave May 
514b62e03f8SDave May   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
51552c3ed93SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
51652c3ed93SDave May   {
51752c3ed93SDave May     DataField gfield;
51852c3ed93SDave May 
51952c3ed93SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
52052c3ed93SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
52152c3ed93SDave May   }
522b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
523b62e03f8SDave May 
524b62e03f8SDave May   PetscFunctionReturn(0);
525b62e03f8SDave May }
526b62e03f8SDave May 
527d3a51819SDave May /*@C
528d3a51819SDave May 
529d3a51819SDave May  DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm
530d3a51819SDave May 
531d3a51819SDave May  Collective on DM
532d3a51819SDave May 
533d3a51819SDave May  Input parameters:
534d3a51819SDave May  . dm - a DMSwarm
535d3a51819SDave May  . fieldname - the textual name to identify this field
536d3a51819SDave May  . size - the size in bytes of the user struct of each data type
537d3a51819SDave May 
538d3a51819SDave May  Level: beginner
539d3a51819SDave May 
540d3a51819SDave May  Notes:
541d3a51819SDave May  The textual name for each registered field must be unique
542d3a51819SDave May 
543d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField()
544d3a51819SDave May 
545d3a51819SDave May @*/
546b62e03f8SDave May #undef __FUNCT__
547b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterUserStructField"
5485f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
549b62e03f8SDave May {
5502eac95f8SDave May   PetscErrorCode ierr;
551b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
552b62e03f8SDave May 
5532eac95f8SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
554b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
555b62e03f8SDave May 
556b62e03f8SDave May   PetscFunctionReturn(0);
557b62e03f8SDave May }
558b62e03f8SDave May 
559d3a51819SDave May /*@C
560d3a51819SDave May 
561d3a51819SDave May  DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm
562d3a51819SDave May 
563d3a51819SDave May  Collective on DM
564d3a51819SDave May 
565d3a51819SDave May  Input parameters:
566d3a51819SDave May  . dm - a DMSwarm
567d3a51819SDave May  . fieldname - the textual name to identify this field
568d3a51819SDave May  . size - the size in bytes of the user data type
569d3a51819SDave May  . blocksize - the number of each data type
570d3a51819SDave May 
571d3a51819SDave May  Level: beginner
572d3a51819SDave May 
573d3a51819SDave May  Notes:
574d3a51819SDave May  The textual name for each registered field must be unique
575d3a51819SDave May 
576d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
577d3a51819SDave May 
578d3a51819SDave May @*/
579b62e03f8SDave May #undef __FUNCT__
580b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterUserDatatypeField"
581320740a0SDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize)
582b62e03f8SDave May {
583b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
5846845f8f5SDave May   PetscErrorCode ierr;
585b62e03f8SDave May 
586320740a0SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
587320740a0SDave May   {
588320740a0SDave May     DataField gfield;
589320740a0SDave May 
590320740a0SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
591320740a0SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
592320740a0SDave May   }
593b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
594b62e03f8SDave May 
595b62e03f8SDave May   PetscFunctionReturn(0);
596b62e03f8SDave May }
597b62e03f8SDave May 
598d3a51819SDave May /*@C
599d3a51819SDave May 
600d3a51819SDave May  DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field
601d3a51819SDave May 
602d3a51819SDave May  Not collective
603d3a51819SDave May 
604d3a51819SDave May  Input parameters:
605d3a51819SDave May  . dm - a DMSwarm
606d3a51819SDave May  . fieldname - the textual name to identify this field
607d3a51819SDave May 
608d3a51819SDave May  Output parameters:
609d3a51819SDave May  . blocksize - the number of each data type
610d3a51819SDave May  . type - the data type
611d3a51819SDave May  . data - pointer to raw array
612d3a51819SDave May 
613d3a51819SDave May  Level: beginner
614d3a51819SDave May 
615d3a51819SDave May  Notes:
616d3a51819SDave May  The user must call DMSwarmRestoreField()
617d3a51819SDave May 
618d3a51819SDave May  . seealso: DMSwarmRestoreField()
619d3a51819SDave May 
620d3a51819SDave May @*/
621b62e03f8SDave May #undef __FUNCT__
622b62e03f8SDave May #define __FUNCT__ "DMSwarmGetField"
6235f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
624b62e03f8SDave May {
625b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
626b62e03f8SDave May   DataField gfield;
6272eac95f8SDave May   PetscErrorCode ierr;
628b62e03f8SDave May 
6293454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
6303454631fSDave May 
6312eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6326845f8f5SDave May   ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr);
6336845f8f5SDave May   ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr);
6341b1ea282SDave May   if (blocksize) {*blocksize = gfield->bs; }
635b5bcf523SDave May   if (type) { *type = gfield->petsc_type; }
636b62e03f8SDave May 
637b62e03f8SDave May   PetscFunctionReturn(0);
638b62e03f8SDave May }
639b62e03f8SDave May 
640d3a51819SDave May /*@C
641d3a51819SDave May 
642d3a51819SDave May  DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field
643d3a51819SDave May 
644d3a51819SDave May  Not collective
645d3a51819SDave May 
646d3a51819SDave May  Input parameters:
647d3a51819SDave May  . dm - a DMSwarm
648d3a51819SDave May  . fieldname - the textual name to identify this field
649d3a51819SDave May 
650d3a51819SDave May  Output parameters:
651d3a51819SDave May  . blocksize - the number of each data type
652d3a51819SDave May  . type - the data type
653d3a51819SDave May  . data - pointer to raw array
654d3a51819SDave May 
655d3a51819SDave May  Level: beginner
656d3a51819SDave May 
657d3a51819SDave May  Notes:
658d3a51819SDave May  The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField()
659d3a51819SDave May 
660d3a51819SDave May  . seealso: DMSwarmGetField()
661d3a51819SDave May 
662d3a51819SDave May @*/
663b62e03f8SDave May #undef __FUNCT__
664b62e03f8SDave May #define __FUNCT__ "DMSwarmRestoreField"
6655f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
666b62e03f8SDave May {
667b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
668b62e03f8SDave May   DataField gfield;
6692eac95f8SDave May   PetscErrorCode ierr;
670b62e03f8SDave May 
6712eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6726845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
673b62e03f8SDave May   if (data) *data = NULL;
674b62e03f8SDave May 
675b62e03f8SDave May   PetscFunctionReturn(0);
676b62e03f8SDave May }
677b62e03f8SDave May 
678d3a51819SDave May /*@C
679d3a51819SDave May 
680d3a51819SDave May  DMSwarmAddPoint - Add space for one new point in the DMSwarm
681d3a51819SDave May 
682d3a51819SDave May  Not collective
683d3a51819SDave May 
684d3a51819SDave May  Input parameter:
685d3a51819SDave May  . dm - a DMSwarm
686d3a51819SDave May 
687d3a51819SDave May  Level: beginner
688d3a51819SDave May 
689d3a51819SDave May  Notes:
690d3a51819SDave May  The new point will have all fields initialized to zero
691d3a51819SDave May 
692d3a51819SDave May  . seealso: DMSwarmAddNPoints()
693d3a51819SDave May 
694d3a51819SDave May @*/
695cb1d1399SDave May #undef __FUNCT__
696cb1d1399SDave May #define __FUNCT__ "DMSwarmAddPoint"
697cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
698cb1d1399SDave May {
699cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
700cb1d1399SDave May   PetscErrorCode ierr;
701cb1d1399SDave May 
7023454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
703cb1d1399SDave May   ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr);
704cb1d1399SDave May   PetscFunctionReturn(0);
705cb1d1399SDave May }
706cb1d1399SDave May 
707d3a51819SDave May /*@C
708d3a51819SDave May 
709d3a51819SDave May  DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm
710d3a51819SDave May 
711d3a51819SDave May  Not collective
712d3a51819SDave May 
713d3a51819SDave May  Input parameters:
714d3a51819SDave May  . dm - a DMSwarm
715d3a51819SDave May  . npoints - the number of new points to add
716d3a51819SDave May 
717d3a51819SDave May  Level: beginner
718d3a51819SDave May 
719d3a51819SDave May  Notes:
720d3a51819SDave May  The new point will have all fields initialized to zero
721d3a51819SDave May 
722d3a51819SDave May  . seealso: DMSwarmAddPoint()
723d3a51819SDave May 
724d3a51819SDave May @*/
725cb1d1399SDave May #undef __FUNCT__
726cb1d1399SDave May #define __FUNCT__ "DMSwarmAddNPoints"
727cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
728cb1d1399SDave May {
729cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
730cb1d1399SDave May   PetscErrorCode ierr;
731cb1d1399SDave May   PetscInt nlocal;
732cb1d1399SDave May 
733cb1d1399SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
734cb1d1399SDave May   nlocal = nlocal + npoints;
735cb1d1399SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,-1);CHKERRQ(ierr);
736cb1d1399SDave May   PetscFunctionReturn(0);
737cb1d1399SDave May }
738cb1d1399SDave May 
739d3a51819SDave May /*@C
740d3a51819SDave May 
741d3a51819SDave May  DMSwarmRemovePoint - Remove the last point from the DMSwarm
742d3a51819SDave May 
743d3a51819SDave May  Not collective
744d3a51819SDave May 
745d3a51819SDave May  Input parameter:
746d3a51819SDave May  . dm - a DMSwarm
747d3a51819SDave May 
748d3a51819SDave May  Level: beginner
749d3a51819SDave May 
750d3a51819SDave May  . seealso: DMSwarmRemovePointAtIndex()
751d3a51819SDave May 
752d3a51819SDave May @*/
753cb1d1399SDave May #undef __FUNCT__
754cb1d1399SDave May #define __FUNCT__ "DMSwarmRemovePoint"
755cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
756cb1d1399SDave May {
757cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
758cb1d1399SDave May   PetscErrorCode ierr;
759cb1d1399SDave May 
760cb1d1399SDave May   ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
761cb1d1399SDave May   PetscFunctionReturn(0);
762cb1d1399SDave May }
763cb1d1399SDave May 
764d3a51819SDave May /*@C
765d3a51819SDave May 
766d3a51819SDave May  DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm
767d3a51819SDave May 
768d3a51819SDave May  Not collective
769d3a51819SDave May 
770d3a51819SDave May  Input parameters:
771d3a51819SDave May  . dm - a DMSwarm
772d3a51819SDave May  . idx - index of point to remove
773d3a51819SDave May 
774d3a51819SDave May  Level: beginner
775d3a51819SDave May 
776d3a51819SDave May  . seealso: DMSwarmRemovePoint()
777d3a51819SDave May 
778d3a51819SDave May @*/
779cb1d1399SDave May #undef __FUNCT__
780cb1d1399SDave May #define __FUNCT__ "DMSwarmRemovePointAtIndex"
781cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
782cb1d1399SDave May {
783cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
784cb1d1399SDave May   PetscErrorCode ierr;
785cb1d1399SDave May 
786cb1d1399SDave May   ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
787cb1d1399SDave May   PetscFunctionReturn(0);
788cb1d1399SDave May }
789b62e03f8SDave May 
7903454631fSDave May #undef __FUNCT__
791095059a4SDave May #define __FUNCT__ "DMSwarmMigrate_Basic"
792095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points)
7933454631fSDave May {
794dcf43ee8SDave May   PetscErrorCode ierr;
795dcf43ee8SDave May   ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr);
7963454631fSDave May   PetscFunctionReturn(0);
7973454631fSDave May }
7983454631fSDave May 
799f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_CellDMScatter(DM dm,PetscBool remove_sent_points);
800f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_CellDMExact(DM dm,PetscBool remove_sent_points);
801f0cdbbbaSDave May 
802d3a51819SDave May /*@C
803d3a51819SDave May 
804d3a51819SDave May  DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks
805d3a51819SDave May 
806d3a51819SDave May  Collective on DM
807d3a51819SDave May 
808d3a51819SDave May  Input parameters:
809d3a51819SDave May  . dm - the DMSwarm
810d3a51819SDave May  . remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank
811d3a51819SDave May 
812d3a51819SDave May  Notes:
813d3a51819SDave May  The DM wil be modified to accomodate received points.
814d3a51819SDave May  If remove_sent_points = PETSC_TRUE, send points will be removed from the DM
815d3a51819SDave May  Different styles of migration are supported. See DMSwarmSetMigrateType()
816d3a51819SDave May 
817d3a51819SDave May  Level: advanced
818d3a51819SDave May 
819d3a51819SDave May  . seealso: DMSwarmSetMigrateType()
820d3a51819SDave May 
821d3a51819SDave May @*/
8223454631fSDave May #undef __FUNCT__
823095059a4SDave May #define __FUNCT__ "DMSwarmMigrate"
824095059a4SDave May PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points)
8253454631fSDave May {
826f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8273454631fSDave May   PetscErrorCode ierr;
828f0cdbbbaSDave May 
829f0cdbbbaSDave May   switch (swarm->migrate_type) {
830f0cdbbbaSDave May 
831f0cdbbbaSDave May     case DMSWARM_MIGRATE_BASIC:
832095059a4SDave May       ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr);
833f0cdbbbaSDave May       break;
834f0cdbbbaSDave May 
835f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLNSCATTER:
836f0cdbbbaSDave May       ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr);
837f0cdbbbaSDave May       break;
838f0cdbbbaSDave May 
839f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLEXACT:
840f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented");
841f0cdbbbaSDave May       //ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr);
842f0cdbbbaSDave May       break;
843f0cdbbbaSDave May 
844f0cdbbbaSDave May     case DMSWARM_MIGRATE_USER:
845f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented");
846f0cdbbbaSDave May       //ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr);
847f0cdbbbaSDave May       break;
848f0cdbbbaSDave May 
849f0cdbbbaSDave May     default:
850f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown");
851f0cdbbbaSDave May       break;
852f0cdbbbaSDave May   }
8533454631fSDave May   PetscFunctionReturn(0);
8543454631fSDave May }
8553454631fSDave May 
856f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize);
857f0cdbbbaSDave May 
858d3a51819SDave May /*
859d3a51819SDave May  DMSwarmCollectViewCreate
860d3a51819SDave May 
861d3a51819SDave May  * Applies a collection method and gathers point neighbour points into dm
862d3a51819SDave May 
863d3a51819SDave May  Notes:
864d3a51819SDave May  - Users should call DMSwarmCollectViewDestroy() after
865d3a51819SDave May  they have finished computations associated with the collected points
866d3a51819SDave May */
867d3a51819SDave May 
868d3a51819SDave May /*@C
869d3a51819SDave May 
870d3a51819SDave May  DMSwarmCollectViewCreate - Applies a collection method and gathers points
871d3a51819SDave May  in neighbour MPI-ranks into the DMSwarm
872d3a51819SDave May 
873d3a51819SDave May  Collective on DM
874d3a51819SDave May 
875d3a51819SDave May  Input parameter:
876d3a51819SDave May  . dm - the DMSwarm
877d3a51819SDave May 
878d3a51819SDave May  Notes:
879d3a51819SDave May  Users should call DMSwarmCollectViewDestroy() after
880d3a51819SDave May  they have finished computations associated with the collected points
881d3a51819SDave May  Different collect methods are supported. See DMSwarmSetCollectType()
882d3a51819SDave May 
883d3a51819SDave May  Level: advanced
884d3a51819SDave May 
885d3a51819SDave May  . seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType()
886d3a51819SDave May 
887d3a51819SDave May @*/
8882712d1f2SDave May #undef __FUNCT__
889fe39f135SDave May #define __FUNCT__ "DMSwarmCollectViewCreate"
890fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm)
8912712d1f2SDave May {
8922712d1f2SDave May   PetscErrorCode ierr;
8932712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8942712d1f2SDave May   PetscInt ng;
8952712d1f2SDave May 
896480eef7bSDave May   if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active");
8972712d1f2SDave May 
898480eef7bSDave May   ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr);
899480eef7bSDave May   switch (swarm->collect_type) {
900f0cdbbbaSDave May 
901480eef7bSDave May     case DMSWARM_COLLECT_BASIC:
9022712d1f2SDave May       ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr);
903480eef7bSDave May       break;
904f0cdbbbaSDave May 
905480eef7bSDave May     case DMSWARM_COLLECT_DMDABOUNDINGBOX:
906f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented");
907fe39f135SDave May       //ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr);
908480eef7bSDave May       break;
909f0cdbbbaSDave May 
910480eef7bSDave May     case DMSWARM_COLLECT_GENERAL:
911f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented");
912fe39f135SDave May       //ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr);
913480eef7bSDave May       break;
914480eef7bSDave May 
915480eef7bSDave May     default:
916f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown");
917480eef7bSDave May       break;
918480eef7bSDave May   }
919480eef7bSDave May 
920480eef7bSDave May   swarm->collect_view_active = PETSC_TRUE;
921480eef7bSDave May   swarm->collect_view_reset_nlocal = ng;
9222712d1f2SDave May 
9232712d1f2SDave May   PetscFunctionReturn(0);
9242712d1f2SDave May }
9252712d1f2SDave May 
926d3a51819SDave May /*@C
927d3a51819SDave May 
928d3a51819SDave May  DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate()
929d3a51819SDave May 
930d3a51819SDave May  Collective on DM
931d3a51819SDave May 
932d3a51819SDave May  Input parameters:
933d3a51819SDave May  . dm - the DMSwarm
934d3a51819SDave May 
935d3a51819SDave May  Notes:
936d3a51819SDave May  Users should call DMSwarmCollectViewCreate() before this function is called.
937d3a51819SDave May 
938d3a51819SDave May  Level: advanced
939d3a51819SDave May 
940d3a51819SDave May  . seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType()
941d3a51819SDave May 
942d3a51819SDave May @*/
9432712d1f2SDave May #undef __FUNCT__
944fe39f135SDave May #define __FUNCT__ "DMSwarmCollectViewDestroy"
945fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm)
9462712d1f2SDave May {
9472712d1f2SDave May   PetscErrorCode ierr;
9482712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9492712d1f2SDave May 
950480eef7bSDave May   if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active");
951480eef7bSDave May   ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr);
952480eef7bSDave May   swarm->collect_view_active = PETSC_FALSE;
9532712d1f2SDave May 
9542712d1f2SDave May   PetscFunctionReturn(0);
9552712d1f2SDave May }
9563454631fSDave May 
9573454631fSDave May #undef __FUNCT__
958f0cdbbbaSDave May #define __FUNCT__ "DMSwarmSetUpPIC"
959f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm)
960f0cdbbbaSDave May {
961f0cdbbbaSDave May   PetscInt dim;
962f0cdbbbaSDave May   PetscErrorCode ierr;
963f0cdbbbaSDave May 
964f0cdbbbaSDave May   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
965f0cdbbbaSDave May   if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
966f0cdbbbaSDave May   if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
967f0cdbbbaSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr);
968f0cdbbbaSDave May   PetscFunctionReturn(0);
969f0cdbbbaSDave May }
970f0cdbbbaSDave May 
971d3a51819SDave May /*@C
972d3a51819SDave May 
973d3a51819SDave May  DMSwarmSetType - Set particular flavor of DMSwarm
974d3a51819SDave May 
975d3a51819SDave May  Collective on DM
976d3a51819SDave May 
977d3a51819SDave May  Input parameters:
978d3a51819SDave May  . dm - the DMSwarm
979d3a51819SDave May  . stype - the DMSwarm type (e.g. DMSWARM_PIC)
980d3a51819SDave May 
981d3a51819SDave May  Level: advanced
982d3a51819SDave May 
983d3a51819SDave May  . seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType()
984d3a51819SDave May 
985d3a51819SDave May @*/
986cac75b86SDave May #undef __FUNCT__
987f0cdbbbaSDave May #define __FUNCT__ "DMSwarmSetType"
988f0cdbbbaSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype)
989f0cdbbbaSDave May {
990f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
991f0cdbbbaSDave May   PetscErrorCode ierr;
992f0cdbbbaSDave May 
993f0cdbbbaSDave May   swarm->swarm_type = stype;
994f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
995f0cdbbbaSDave May     ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr);
996f0cdbbbaSDave May   }
997f0cdbbbaSDave May   PetscFunctionReturn(0);
998f0cdbbbaSDave May }
999f0cdbbbaSDave May 
1000f0cdbbbaSDave May #undef __FUNCT__
10013454631fSDave May #define __FUNCT__ "DMSetup_Swarm"
10023454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm)
10033454631fSDave May {
10043454631fSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
10053454631fSDave May   PetscErrorCode ierr;
10063454631fSDave May   PetscMPIInt rank;
10073454631fSDave May   PetscInt p,npoints,*rankval;
10083454631fSDave May 
10093454631fSDave May   if (swarm->issetup) PetscFunctionReturn(0);
10103454631fSDave May 
10113454631fSDave May   swarm->issetup = PETSC_TRUE;
10123454631fSDave May 
1013f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
1014f0cdbbbaSDave May     /* check dmcell exists */
1015f0cdbbbaSDave May     if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM");
1016f0cdbbbaSDave May 
1017f0cdbbbaSDave May     if (swarm->dmcell->ops->locatepointssubdomain) {
1018f0cdbbbaSDave May       /* check methods exists for exact ownership identificiation */
1019f0cdbbbaSDave May       PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");
1020f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT;
1021f0cdbbbaSDave May     } else {
1022f0cdbbbaSDave May       /* check methods exist for point location AND rank neighbor identification */
1023f0cdbbbaSDave May       if (swarm->dmcell->ops->locatepoints) {
1024f0cdbbbaSDave May         PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->LocatePoints\n");
1025f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined");
1026f0cdbbbaSDave May 
1027f0cdbbbaSDave May       if (swarm->dmcell->ops->getneighbors) {
1028f0cdbbbaSDave May         PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->GetNeigbors\n");
1029f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined");
1030f0cdbbbaSDave May 
1031f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER;
1032f0cdbbbaSDave May     }
1033f0cdbbbaSDave May   }
1034f0cdbbbaSDave May 
1035f0cdbbbaSDave May   ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr);
1036f0cdbbbaSDave May 
10373454631fSDave May   /* check some fields were registered */
10383454631fSDave May   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
10393454631fSDave May 
10403454631fSDave May   /* check local sizes were set */
10413454631fSDave May   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
10423454631fSDave May 
10433454631fSDave May   /* initialize values in pid and rank placeholders */
10443454631fSDave May   /* TODO: [pid - use MPI_Scan] */
10453454631fSDave May 
10463454631fSDave May   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
10473454631fSDave May   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
1048f0cdbbbaSDave May   ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10493454631fSDave May   for (p=0; p<npoints; p++) {
10503454631fSDave May     rankval[p] = (PetscInt)rank;
10513454631fSDave May   }
1052f0cdbbbaSDave May   ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10533454631fSDave May 
10543454631fSDave May   PetscFunctionReturn(0);
10553454631fSDave May }
10563454631fSDave May 
1057b62e03f8SDave May #undef __FUNCT__
105857795646SDave May #define __FUNCT__ "DMDestroy_Swarm"
105957795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm)
106057795646SDave May {
106157795646SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
106257795646SDave May   PetscErrorCode ierr;
106357795646SDave May 
106457795646SDave May   PetscFunctionBegin;
10656845f8f5SDave May   ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr);
106657795646SDave May   ierr = PetscFree(swarm);CHKERRQ(ierr);
106757795646SDave May   PetscFunctionReturn(0);
106857795646SDave May }
106957795646SDave May 
107057795646SDave May #undef __FUNCT__
1071a9ee3421SMatthew G. Knepley #define __FUNCT__ "DMSwarmView_Draw"
1072a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer)
1073a9ee3421SMatthew G. Knepley {
1074a9ee3421SMatthew G. Knepley   DM             cdm;
1075a9ee3421SMatthew G. Knepley   PetscDraw      draw;
1076a9ee3421SMatthew G. Knepley   PetscReal     *coords, oldPause;
1077a9ee3421SMatthew G. Knepley   PetscInt       Np, p, bs;
1078a9ee3421SMatthew G. Knepley   PetscErrorCode ierr;
1079a9ee3421SMatthew G. Knepley 
1080a9ee3421SMatthew G. Knepley   PetscFunctionBegin;
1081a9ee3421SMatthew G. Knepley   ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr);
1082a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr);
1083a9ee3421SMatthew G. Knepley   ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr);
1084a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr);
1085a9ee3421SMatthew G. Knepley   ierr = DMView(cdm, viewer);CHKERRQ(ierr);
1086a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr);
1087a9ee3421SMatthew G. Knepley 
1088a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr);
1089a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1090a9ee3421SMatthew G. Knepley   for (p = 0; p < Np; ++p) {
1091a9ee3421SMatthew G. Knepley     const PetscInt i = p*bs;
1092a9ee3421SMatthew G. Knepley 
1093a9ee3421SMatthew G. Knepley     ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], 0.01, 0.01, PETSC_DRAW_BLUE);CHKERRQ(ierr);
1094a9ee3421SMatthew G. Knepley   }
1095a9ee3421SMatthew G. Knepley   ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1096a9ee3421SMatthew G. Knepley   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
1097a9ee3421SMatthew G. Knepley   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
1098a9ee3421SMatthew G. Knepley   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1099a9ee3421SMatthew G. Knepley   PetscFunctionReturn(0);
1100a9ee3421SMatthew G. Knepley }
1101a9ee3421SMatthew G. Knepley 
1102a9ee3421SMatthew G. Knepley #undef __FUNCT__
11035f50eb2eSDave May #define __FUNCT__ "DMView_Swarm"
11045f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
11055f50eb2eSDave May {
11065f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1107a9ee3421SMatthew G. Knepley   PetscBool      iascii,ibinary,ishdf5,isvtk,isdraw;
11085f50eb2eSDave May   PetscErrorCode ierr;
11095f50eb2eSDave May 
11105f50eb2eSDave May   PetscFunctionBegin;
11115f50eb2eSDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
11125f50eb2eSDave May   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
11135f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
11145f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
11155f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
11165f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1117a9ee3421SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW,  &isdraw);CHKERRQ(ierr);
11185f50eb2eSDave May   if (iascii) {
11196845f8f5SDave May     ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
11205f50eb2eSDave May   } else if (ibinary) {
1121a9ee3421SMatthew G. Knepley     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support");
11225f50eb2eSDave May   } else if (ishdf5) {
11235f50eb2eSDave May #if defined(PETSC_HAVE_HDF5)
11245f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
11255f50eb2eSDave May #else
11265f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
11275f50eb2eSDave May #endif
11285f50eb2eSDave May   } else if (isvtk) {
11295f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
1130a9ee3421SMatthew G. Knepley   } else if (isdraw) {
1131a9ee3421SMatthew G. Knepley     ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr);
11325f50eb2eSDave May   }
11335f50eb2eSDave May   PetscFunctionReturn(0);
11345f50eb2eSDave May }
11355f50eb2eSDave May 
1136d3a51819SDave May /*MC
1137d3a51819SDave May 
1138d3a51819SDave May  DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type.
1139d3a51819SDave May  This implementation was designed for particle-in-cell type methods in which the underlying
1140d3a51819SDave May  data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type.
1141d3a51819SDave May 
1142d3a51819SDave May  User data can be represented by DMSwarm through a registring "fields".
1143d3a51819SDave May  To register a field, the user must provide:
1144d3a51819SDave May  (a) a unique name
1145d3a51819SDave May  (b) the data type (or size in bytes)
1146d3a51819SDave May  (c) the block size of the data
1147d3a51819SDave May 
1148d3a51819SDave May  For example, suppose the application requires a unique id, energy, momentum and density to be stored
1149d3a51819SDave May  on a set of of particles. Then the following application could be used
1150d3a51819SDave May 
1151d3a51819SDave May  DMSwarmInitializeFieldRegister(dm)
1152d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG);
1153d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL);
1154d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL);
1155d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT);
1156d3a51819SDave May  DMSwarmFinalizeFieldRegister(dm)
1157d3a51819SDave May 
1158d3a51819SDave May  The fields represented by DMSwarm are dynamic and can be re-sized at any time.
1159d3a51819SDave May  The only restriction imposed by DMSwarm is that all fields contain the same number of points
1160d3a51819SDave May 
1161d3a51819SDave May  To support particle methods, "migration" techniques are provided. These methods migrate data
1162d3a51819SDave May  between MPI-ranks.
1163d3a51819SDave May 
1164d3a51819SDave May  DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector().
1165d3a51819SDave May  As a DMSwarm may internally define and store values of different data types,
1166d3a51819SDave May  before calling DMCreate{Global/Local}Vector() the user must inform DMSwarm which
1167d3a51819SDave May  fields should be used to define a Vec object via
1168d3a51819SDave May    DMSwarmVectorDefineField()
1169d3a51819SDave May  The specified field can can changed be changed at any time - thereby permitting vectors
1170d3a51819SDave May  compatable with different fields to be created.
1171d3a51819SDave May 
1172d3a51819SDave May  A dual representation of fields in the DMSwarm and a Vec object are permitted via
1173d3a51819SDave May    DMSwarmCreateGlobalVectorFromField()
1174d3a51819SDave May  Here the data defining the field in the DMSwarm is shared with a Vec.
1175d3a51819SDave May  This is inherently unsafe if you alter the size of the field at any time between
1176d3a51819SDave May  calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField().
1177cc651181SDave May  If the local size of the DMSwarm does not match the localsize of the global vector
1178cc651181SDave May  when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown.
1179d3a51819SDave May 
1180d3a51819SDave May  Level: beginner
1181d3a51819SDave May 
1182d3a51819SDave May  .seealso: DMType, DMCreate(), DMSetType()
1183d3a51819SDave May 
1184d3a51819SDave May M*/
11855f50eb2eSDave May #undef __FUNCT__
118657795646SDave May #define __FUNCT__ "DMCreate_Swarm"
118757795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
118857795646SDave May {
118957795646SDave May   DM_Swarm      *swarm;
119057795646SDave May   PetscErrorCode ierr;
119157795646SDave May 
119257795646SDave May   PetscFunctionBegin;
119357795646SDave May   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
119457795646SDave May   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
1195f0cdbbbaSDave May   dm->data = swarm;
119657795646SDave May 
11976845f8f5SDave May   ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr);
1198f0cdbbbaSDave May   ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr);
1199f0cdbbbaSDave May 
1200b5bcf523SDave May   swarm->vec_field_set = PETSC_FALSE;
12013454631fSDave May   swarm->issetup = PETSC_FALSE;
1202480eef7bSDave May   swarm->swarm_type = DMSWARM_BASIC;
1203480eef7bSDave May   swarm->migrate_type = DMSWARM_MIGRATE_BASIC;
1204480eef7bSDave May   swarm->collect_type = DMSWARM_COLLECT_BASIC;
120540c453e9SDave May   swarm->migrate_error_on_missing_point = PETSC_FALSE;
1206b62e03f8SDave May 
1207f0cdbbbaSDave May   swarm->dmcell = NULL;
1208f0cdbbbaSDave May   swarm->collect_view_active = PETSC_FALSE;
1209f0cdbbbaSDave May   swarm->collect_view_reset_nlocal = -1;
121057795646SDave May 
1211f0cdbbbaSDave May   dm->dim  = 0;
12125f50eb2eSDave May   dm->ops->view                            = DMView_Swarm;
121357795646SDave May   dm->ops->load                            = NULL;
121457795646SDave May   dm->ops->setfromoptions                  = NULL;
121557795646SDave May   dm->ops->clone                           = NULL;
12163454631fSDave May   dm->ops->setup                           = DMSetup_Swarm;
121757795646SDave May   dm->ops->createdefaultsection            = NULL;
121857795646SDave May   dm->ops->createdefaultconstraints        = NULL;
1219b5bcf523SDave May   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
1220b5bcf523SDave May   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
122157795646SDave May   dm->ops->getlocaltoglobalmapping         = NULL;
122257795646SDave May   dm->ops->createfieldis                   = NULL;
122357795646SDave May   dm->ops->createcoordinatedm              = NULL;
122457795646SDave May   dm->ops->getcoloring                     = NULL;
122557795646SDave May   dm->ops->creatematrix                    = NULL;
122657795646SDave May   dm->ops->createinterpolation             = NULL;
122757795646SDave May   dm->ops->getaggregates                   = NULL;
122857795646SDave May   dm->ops->getinjection                    = NULL;
122957795646SDave May   dm->ops->refine                          = NULL;
123057795646SDave May   dm->ops->coarsen                         = NULL;
123157795646SDave May   dm->ops->refinehierarchy                 = NULL;
123257795646SDave May   dm->ops->coarsenhierarchy                = NULL;
123357795646SDave May   dm->ops->globaltolocalbegin              = NULL;
123457795646SDave May   dm->ops->globaltolocalend                = NULL;
123557795646SDave May   dm->ops->localtoglobalbegin              = NULL;
123657795646SDave May   dm->ops->localtoglobalend                = NULL;
123757795646SDave May   dm->ops->destroy                         = DMDestroy_Swarm;
123857795646SDave May   dm->ops->createsubdm                     = NULL;
123957795646SDave May   dm->ops->getdimpoints                    = NULL;
124057795646SDave May   dm->ops->locatepoints                    = NULL;
124157795646SDave May 
124257795646SDave May   PetscFunctionReturn(0);
124357795646SDave May }
1244