xref: /petsc/src/dm/impls/swarm/swarm.c (revision 071900c8413cc4b96b21dcc59019789c8e0b4c95)
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);
105*071900c8SMatthew G. Knepley   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);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 
113fb1bcc12SMatthew G. Knepley #undef __FUNCT__
114fb1bcc12SMatthew G. Knepley #define __FUNCT__ "DMSwarmDestroyVectorFromField_Private"
115fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmDestroyVectorFromField_Private(DM dm, const char fieldname[], Vec *vec)
116fb1bcc12SMatthew G. Knepley {
117fb1bcc12SMatthew G. Knepley   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
118fb1bcc12SMatthew G. Knepley   DataField      gfield;
119fb1bcc12SMatthew G. Knepley   void         (*fptr)(void);
120fb1bcc12SMatthew G. Knepley   PetscInt       bs, nlocal;
121fb1bcc12SMatthew G. Knepley   char           name[PETSC_MAX_PATH_LEN];
122fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
123d3a51819SDave May 
124fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
125fb1bcc12SMatthew G. Knepley   ierr = VecGetLocalSize(*vec, &nlocal);CHKERRQ(ierr);
126fb1bcc12SMatthew G. Knepley   ierr = VecGetBlockSize(*vec, &bs);CHKERRQ(ierr);
127fb1bcc12SMatthew G. Knepley   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 */
128fb1bcc12SMatthew G. Knepley   ierr = DataBucketGetDataFieldByName(swarm->db, fieldname, &gfield);CHKERRQ(ierr);
129fb1bcc12SMatthew G. Knepley   /* check vector is an inplace array */
130fb1bcc12SMatthew G. Knepley   PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);
131fb1bcc12SMatthew G. Knepley   ierr = PetscObjectQueryFunction((PetscObject) *vec, name, &fptr);CHKERRQ(ierr);
132fb1bcc12SMatthew G. Knepley   if (!fptr) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Vector being destroyed was not created from DMSwarm field(%s)", fieldname);
133fb1bcc12SMatthew G. Knepley   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
134fb1bcc12SMatthew G. Knepley   ierr = VecDestroy(vec);CHKERRQ(ierr);
135fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
136fb1bcc12SMatthew G. Knepley }
137fb1bcc12SMatthew G. Knepley 
138fb1bcc12SMatthew G. Knepley #undef __FUNCT__
139fb1bcc12SMatthew G. Knepley #define __FUNCT__ "DMSwarmCreateVectorFromField_Private"
140fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmCreateVectorFromField_Private(DM dm, const char fieldname[], MPI_Comm comm, Vec *vec)
141fb1bcc12SMatthew G. Knepley {
142fb1bcc12SMatthew G. Knepley   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
143fb1bcc12SMatthew G. Knepley   DataField      gfield;
144fb1bcc12SMatthew G. Knepley   void         (*fptr)(void);
145fb1bcc12SMatthew G. Knepley   PetscDataType  type;
146fb1bcc12SMatthew G. Knepley   PetscScalar   *array;
147fb1bcc12SMatthew G. Knepley   PetscInt       bs, n;
148fb1bcc12SMatthew G. Knepley   char           name[PETSC_MAX_PATH_LEN];
149fb1bcc12SMatthew G. Knepley   PetscMPIInt    commsize;
150fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
151fb1bcc12SMatthew G. Knepley 
152fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
153fb1bcc12SMatthew G. Knepley   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
154fb1bcc12SMatthew G. Knepley   ierr = DataBucketGetSizes(swarm->db, &n, NULL, NULL);CHKERRQ(ierr);
155fb1bcc12SMatthew G. Knepley   ierr = DMSwarmGetField(dm, fieldname, &bs, &type, (void **) &array);CHKERRQ(ierr);
156fb1bcc12SMatthew G. Knepley   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Only valid for PETSC_REAL");
157fb1bcc12SMatthew G. Knepley 
158fb1bcc12SMatthew G. Knepley   ierr = MPI_Comm_size(comm, &commsize);CHKERRQ(ierr);
159fb1bcc12SMatthew G. Knepley   if (commsize == 1) {
160fb1bcc12SMatthew G. Knepley     ierr = VecCreateSeqWithArray(comm, bs, n*bs, array, vec);CHKERRQ(ierr);
161fb1bcc12SMatthew G. Knepley   } else {
162fb1bcc12SMatthew G. Knepley     ierr = VecCreateMPIWithArray(comm, bs, n*bs, PETSC_DETERMINE, array, vec);CHKERRQ(ierr);
163fb1bcc12SMatthew G. Knepley   }
164fb1bcc12SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarmSharedField_%s", fieldname);CHKERRQ(ierr);
165fb1bcc12SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) *vec, name);CHKERRQ(ierr);
166fb1bcc12SMatthew G. Knepley 
167fb1bcc12SMatthew G. Knepley   /* Set guard */
168fb1bcc12SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr);
169fb1bcc12SMatthew G. Knepley   ierr = PetscObjectComposeFunction((PetscObject) *vec, name, DMSwarmDestroyVectorFromField_Private);CHKERRQ(ierr);
170fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
171fb1bcc12SMatthew G. Knepley }
172fb1bcc12SMatthew G. Knepley 
173fb1bcc12SMatthew G. Knepley /*@C
174d3a51819SDave May   DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field
175d3a51819SDave May 
176d3a51819SDave May   Collective on DM
177d3a51819SDave May 
178d3a51819SDave May   Input parameters:
179d3a51819SDave May  . dm - a DMSwarm
180d3a51819SDave May  . fieldname - the textual name given to a registered field
181d3a51819SDave May 
182d3a51819SDave May  Output parameters:
183d3a51819SDave May  . vec - the vector
184d3a51819SDave May 
185d3a51819SDave May   Level: beginner
186d3a51819SDave May 
187d3a51819SDave May . seealso: DMSwarmRegisterPetscDatatypeField()
188d3a51819SDave May @*/
189b5bcf523SDave May #undef __FUNCT__
190b5bcf523SDave May #define __FUNCT__ "DMSwarmCreateGlobalVectorFromField"
191b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
192b5bcf523SDave May {
193fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PetscObjectComm((PetscObject) dm);
194b5bcf523SDave May   PetscErrorCode ierr;
195b5bcf523SDave May 
196fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
197fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
198b5bcf523SDave May   PetscFunctionReturn(0);
199b5bcf523SDave May }
200b5bcf523SDave May 
201d3a51819SDave May /*@C
202d3a51819SDave May   DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field
203d3a51819SDave May 
204d3a51819SDave May   Collective on DM
205d3a51819SDave May 
206d3a51819SDave May   Input parameters:
207d3a51819SDave May  . dm - a DMSwarm
208d3a51819SDave May  . fieldname - the textual name given to a registered field
209d3a51819SDave May 
210d3a51819SDave May   Output parameters:
211d3a51819SDave May  . vec - the vector
212d3a51819SDave May 
213d3a51819SDave May   Level: beginner
214d3a51819SDave May 
215d3a51819SDave May . seealso: DMSwarmRegisterPetscDatatypeField()
216d3a51819SDave May @*/
217b5bcf523SDave May #undef __FUNCT__
218b5bcf523SDave May #define __FUNCT__ "DMSwarmDestroyGlobalVectorFromField"
219b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
220b5bcf523SDave May {
221b5bcf523SDave May   PetscErrorCode ierr;
222cc651181SDave May 
223fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
224fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
225b5bcf523SDave May   PetscFunctionReturn(0);
226b5bcf523SDave May }
227b5bcf523SDave May 
228fb1bcc12SMatthew G. Knepley /*@C
229fb1bcc12SMatthew G. Knepley   DMSwarmCreateLocalVectorFromField - Creates a Vec object sharing the array associated with a given field
230fb1bcc12SMatthew G. Knepley 
231fb1bcc12SMatthew G. Knepley   Collective on DM
232fb1bcc12SMatthew G. Knepley 
233fb1bcc12SMatthew G. Knepley   Input parameters:
234fb1bcc12SMatthew G. Knepley  . dm - a DMSwarm
235fb1bcc12SMatthew G. Knepley  . fieldname - the textual name given to a registered field
236fb1bcc12SMatthew G. Knepley 
237fb1bcc12SMatthew G. Knepley  Output parameters:
238fb1bcc12SMatthew G. Knepley  . vec - the vector
239fb1bcc12SMatthew G. Knepley 
240fb1bcc12SMatthew G. Knepley   Level: beginner
241fb1bcc12SMatthew G. Knepley 
242fb1bcc12SMatthew G. Knepley . seealso: DMSwarmRegisterPetscDatatypeField()
243fb1bcc12SMatthew G. Knepley @*/
244bbe8250bSMatthew G. Knepley #undef __FUNCT__
245fb1bcc12SMatthew G. Knepley #define __FUNCT__ "DMSwarmCreateLocalVectorFromField"
246fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmCreateLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
247bbe8250bSMatthew G. Knepley {
248fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PETSC_COMM_SELF;
249bbe8250bSMatthew G. Knepley   PetscErrorCode ierr;
250bbe8250bSMatthew G. Knepley 
251fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
252fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
253fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
254bbe8250bSMatthew G. Knepley }
255fb1bcc12SMatthew G. Knepley 
256fb1bcc12SMatthew G. Knepley /*@C
257fb1bcc12SMatthew G. Knepley   DMSwarmDestroyLocalVectorFromField - Destroys the Vec object which share the array associated with a given field
258fb1bcc12SMatthew G. Knepley 
259fb1bcc12SMatthew G. Knepley   Collective on DM
260fb1bcc12SMatthew G. Knepley 
261fb1bcc12SMatthew G. Knepley   Input parameters:
262fb1bcc12SMatthew G. Knepley  . dm - a DMSwarm
263fb1bcc12SMatthew G. Knepley  . fieldname - the textual name given to a registered field
264fb1bcc12SMatthew G. Knepley 
265fb1bcc12SMatthew G. Knepley   Output parameters:
266fb1bcc12SMatthew G. Knepley  . vec - the vector
267fb1bcc12SMatthew G. Knepley 
268fb1bcc12SMatthew G. Knepley   Level: beginner
269fb1bcc12SMatthew G. Knepley 
270fb1bcc12SMatthew G. Knepley . seealso: DMSwarmRegisterPetscDatatypeField()
271fb1bcc12SMatthew G. Knepley @*/
272fb1bcc12SMatthew G. Knepley #undef __FUNCT__
273fb1bcc12SMatthew G. Knepley #define __FUNCT__ "DMSwarmDestroyLocalVectorFromField"
274fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmDestroyLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
275fb1bcc12SMatthew G. Knepley {
276fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
277fb1bcc12SMatthew G. Knepley 
278fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
279fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
280bbe8250bSMatthew G. Knepley   PetscFunctionReturn(0);
281bbe8250bSMatthew G. Knepley }
282bbe8250bSMatthew G. Knepley 
283b5bcf523SDave May /*
284b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec)
285b5bcf523SDave May {
286b5bcf523SDave May   PetscFunctionReturn(0);
287b5bcf523SDave May }
288b5bcf523SDave May 
289b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec)
290b5bcf523SDave May {
291b5bcf523SDave May   PetscFunctionReturn(0);
292b5bcf523SDave May }
293b5bcf523SDave May */
294b5bcf523SDave May 
295d3a51819SDave May 
296d3a51819SDave May /*@C
297d3a51819SDave May 
298d3a51819SDave May  DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm
299d3a51819SDave May 
300d3a51819SDave May  Collective on DM
301d3a51819SDave May 
302d3a51819SDave May  Input parameter:
303d3a51819SDave May  . dm - a DMSwarm
304d3a51819SDave May 
305d3a51819SDave May  Level: beginner
306d3a51819SDave May 
307d3a51819SDave May  Notes:
308d3a51819SDave May  After all fields have been registered, users should call DMSwarmFinalizeFieldRegister()
309d3a51819SDave May 
310d3a51819SDave May  . seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
311d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
312d3a51819SDave May 
313d3a51819SDave May @*/
314b5bcf523SDave May #undef __FUNCT__
3155f50eb2eSDave May #define __FUNCT__ "DMSwarmInitializeFieldRegister"
3165f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm)
3175f50eb2eSDave May {
3185f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3193454631fSDave May   PetscErrorCode ierr;
3203454631fSDave May 
321cc651181SDave May   if (!swarm->field_registration_initialized) {
3225f50eb2eSDave May     swarm->field_registration_initialized = PETSC_TRUE;
323f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */
324f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */
325cc651181SDave May   }
3263454631fSDave May 
3275f50eb2eSDave May   PetscFunctionReturn(0);
3285f50eb2eSDave May }
3295f50eb2eSDave May 
330d3a51819SDave May /*@C
331d3a51819SDave May 
332d3a51819SDave May  DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm
333d3a51819SDave May 
334d3a51819SDave May  Collective on DM
335d3a51819SDave May 
336d3a51819SDave May  Input parameter:
337d3a51819SDave May  . dm - a DMSwarm
338d3a51819SDave May 
339d3a51819SDave May  Level: beginner
340d3a51819SDave May 
341d3a51819SDave May  Notes:
342d3a51819SDave May  After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined
343d3a51819SDave May  on the DMSwarm
344d3a51819SDave May 
345d3a51819SDave May  . seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
346d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
347d3a51819SDave May 
348d3a51819SDave May @*/
3495f50eb2eSDave May #undef __FUNCT__
3505f50eb2eSDave May #define __FUNCT__ "DMSwarmFinalizeFieldRegister"
3515f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm)
3525f50eb2eSDave May {
3535f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3546845f8f5SDave May   PetscErrorCode ierr;
3556845f8f5SDave May 
356f0cdbbbaSDave May   if (!swarm->field_registration_finalized) {
3576845f8f5SDave May     ierr = DataBucketFinalize(swarm->db);CHKERRQ(ierr);
358f0cdbbbaSDave May   }
359f0cdbbbaSDave May   swarm->field_registration_finalized = PETSC_TRUE;
3605f50eb2eSDave May   PetscFunctionReturn(0);
3615f50eb2eSDave May }
3625f50eb2eSDave May 
363d3a51819SDave May /*@C
364d3a51819SDave May 
365d3a51819SDave May  DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm
366d3a51819SDave May 
367d3a51819SDave May  Not collective
368d3a51819SDave May 
369d3a51819SDave May  Input parameters:
370d3a51819SDave May  . dm - a DMSwarm
371d3a51819SDave May  . nlocal - the length of each registered field
372d3a51819SDave May  . buffer - the length of the buffer used to efficient dynamic re-sizing
373d3a51819SDave May 
374d3a51819SDave May  Level: beginner
375d3a51819SDave May 
376d3a51819SDave May  . seealso: DMSwarmGetLocalSize()
377d3a51819SDave May 
378d3a51819SDave May @*/
3795f50eb2eSDave May #undef __FUNCT__
3805f50eb2eSDave May #define __FUNCT__ "DMSwarmSetLocalSizes"
3815f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer)
3825f50eb2eSDave May {
3835f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3846845f8f5SDave May   PetscErrorCode ierr;
3855f50eb2eSDave May 
3866845f8f5SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr);
3875f50eb2eSDave May 
3885f50eb2eSDave May   PetscFunctionReturn(0);
3895f50eb2eSDave May }
3905f50eb2eSDave May 
391d3a51819SDave May /*@C
392d3a51819SDave May 
393d3a51819SDave May  DMSwarmSetCellDM - Attachs a DM to a DMSwarm
394d3a51819SDave May 
395d3a51819SDave May  Collective on DM
396d3a51819SDave May 
397d3a51819SDave May  Input parameters:
398d3a51819SDave May  . dm - a DMSwarm
399d3a51819SDave May  . dmcell - the DM to attach to the DMSwarm
400d3a51819SDave May 
401d3a51819SDave May  Level: beginner
402d3a51819SDave May 
403d3a51819SDave May  Notes:
404d3a51819SDave May  The attached DM (dmcell) will be queried for pointlocation and
405d3a51819SDave May  neighbor MPI-rank information if DMSwarmMigrate() is called
406d3a51819SDave May 
407d3a51819SDave May  . seealso: DMSwarmGetCellDM(), DMSwarmMigrate()
408d3a51819SDave May 
409d3a51819SDave May @*/
4105f50eb2eSDave May #undef __FUNCT__
411b16650c8SDave May #define __FUNCT__ "DMSwarmSetCellDM"
412b16650c8SDave May PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell)
413b16650c8SDave May {
414b16650c8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
415b16650c8SDave May   swarm->dmcell = dmcell;
416b16650c8SDave May   PetscFunctionReturn(0);
417b16650c8SDave May }
418b16650c8SDave May 
419d3a51819SDave May /*@C
420d3a51819SDave May 
421d3a51819SDave May  DMSwarmGetCellDM - Fetches the attached cell DM
422d3a51819SDave May 
423d3a51819SDave May  Collective on DM
424d3a51819SDave May 
425d3a51819SDave May  Input parameter:
426d3a51819SDave May  . dm - a DMSwarm
427d3a51819SDave May 
428d3a51819SDave May  Output parameter:
429d3a51819SDave May  . dmcell - the DM which was attached to the DMSwarm
430d3a51819SDave May 
431d3a51819SDave May  Level: beginner
432d3a51819SDave May 
433d3a51819SDave May  Notes:
434d3a51819SDave May  The attached DM (dmcell) will be queried for pointlocation and
435d3a51819SDave May  neighbor MPI-rank information if DMSwarmMigrate() is called
436d3a51819SDave May 
437d3a51819SDave May  . seealso: DMSwarmSetCellDM()
438d3a51819SDave May 
439d3a51819SDave May @*/
440b16650c8SDave May #undef __FUNCT__
441fe39f135SDave May #define __FUNCT__ "DMSwarmGetCellDM"
442fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell)
443fe39f135SDave May {
444fe39f135SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
445fe39f135SDave May   *dmcell = swarm->dmcell;
446fe39f135SDave May   PetscFunctionReturn(0);
447fe39f135SDave May }
448fe39f135SDave May 
449d3a51819SDave May /*@C
450d3a51819SDave May 
451d3a51819SDave May  DMSwarmGetLocalSize - Retrives the local length of fields registered
452d3a51819SDave May 
453d3a51819SDave May  Not collective
454d3a51819SDave May 
455d3a51819SDave May  Input parameter:
456d3a51819SDave May  . dm - a DMSwarm
457d3a51819SDave May 
458d3a51819SDave May  Output parameter:
459d3a51819SDave May  . nlocal - the length of each registered field
460d3a51819SDave May 
461d3a51819SDave May  Level: beginner
462d3a51819SDave May 
463d3a51819SDave May  . seealso: DMSwarmSetLocalSizes()
464d3a51819SDave May 
465d3a51819SDave May @*/
466fe39f135SDave May #undef __FUNCT__
467dcf43ee8SDave May #define __FUNCT__ "DMSwarmGetLocalSize"
468dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal)
469dcf43ee8SDave May {
470dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
471dcf43ee8SDave May   PetscErrorCode ierr;
472dcf43ee8SDave May 
473dcf43ee8SDave May   if (nlocal) {
474dcf43ee8SDave May     ierr = DataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);
475dcf43ee8SDave May   }
476dcf43ee8SDave May 
477dcf43ee8SDave May   PetscFunctionReturn(0);
478dcf43ee8SDave May }
479dcf43ee8SDave May 
480d3a51819SDave May /*@C
481d3a51819SDave May 
482d3a51819SDave May  DMSwarmGetSize - Retrives the total length of fields registered
483d3a51819SDave May 
484d3a51819SDave May  Collective on DM
485d3a51819SDave May 
486d3a51819SDave May  Input parameter:
487d3a51819SDave May  . dm - a DMSwarm
488d3a51819SDave May 
489d3a51819SDave May  Output parameter:
490d3a51819SDave May  . n - the total length of each registered field
491d3a51819SDave May 
492d3a51819SDave May  Level: beginner
493d3a51819SDave May 
494d3a51819SDave May  Note:
495d3a51819SDave May  This calls MPI_Allreduce upon each call (inefficient but safe)
496d3a51819SDave May 
497d3a51819SDave May  . seealso: DMSwarmGetLocalSize()
498d3a51819SDave May 
499d3a51819SDave May @*/
500dcf43ee8SDave May #undef __FUNCT__
501dcf43ee8SDave May #define __FUNCT__ "DMSwarmGetSize"
502dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n)
503dcf43ee8SDave May {
504dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
505dcf43ee8SDave May   PetscErrorCode ierr;
506dcf43ee8SDave May   PetscInt nlocal,ng;
507dcf43ee8SDave May 
508dcf43ee8SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
509dcf43ee8SDave May   ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
510dcf43ee8SDave May   if (n) { *n = ng; }
511dcf43ee8SDave May   PetscFunctionReturn(0);
512dcf43ee8SDave May }
513dcf43ee8SDave May 
514d3a51819SDave May /*@C
515d3a51819SDave May 
516d3a51819SDave May  DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm
517d3a51819SDave May 
518d3a51819SDave May  Collective on DM
519d3a51819SDave May 
520d3a51819SDave May  Input parameters:
521d3a51819SDave May  . dm - a DMSwarm
522d3a51819SDave May  . fieldname - the textual name to identify this field
523d3a51819SDave May  . blocksize - the number of each data type
524d3a51819SDave May  . type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG)
525d3a51819SDave May 
526d3a51819SDave May  Level: beginner
527d3a51819SDave May 
528d3a51819SDave May  Notes:
529d3a51819SDave May  The textual name for each registered field must be unique
530d3a51819SDave May 
531d3a51819SDave May  . seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
532d3a51819SDave May 
533d3a51819SDave May @*/
534dcf43ee8SDave May #undef __FUNCT__
535b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterPetscDatatypeField"
5365f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
537b62e03f8SDave May {
5382eac95f8SDave May   PetscErrorCode ierr;
539b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
540b62e03f8SDave May   size_t size;
541b62e03f8SDave May 
5425f50eb2eSDave May   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
5435f50eb2eSDave May   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
5445f50eb2eSDave May 
5455f50eb2eSDave May   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5465f50eb2eSDave May   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5475f50eb2eSDave May   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5485f50eb2eSDave May   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5495f50eb2eSDave May   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
550b62e03f8SDave May 
5512ddcf43eSMatthew G. Knepley   ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr);
552b62e03f8SDave May 
553b62e03f8SDave May   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
55452c3ed93SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
55552c3ed93SDave May   {
55652c3ed93SDave May     DataField gfield;
55752c3ed93SDave May 
55852c3ed93SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
55952c3ed93SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
56052c3ed93SDave May   }
561b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
562b62e03f8SDave May 
563b62e03f8SDave May   PetscFunctionReturn(0);
564b62e03f8SDave May }
565b62e03f8SDave May 
566d3a51819SDave May /*@C
567d3a51819SDave May 
568d3a51819SDave May  DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm
569d3a51819SDave May 
570d3a51819SDave May  Collective on DM
571d3a51819SDave May 
572d3a51819SDave May  Input parameters:
573d3a51819SDave May  . dm - a DMSwarm
574d3a51819SDave May  . fieldname - the textual name to identify this field
575d3a51819SDave May  . size - the size in bytes of the user struct of each data type
576d3a51819SDave May 
577d3a51819SDave May  Level: beginner
578d3a51819SDave May 
579d3a51819SDave May  Notes:
580d3a51819SDave May  The textual name for each registered field must be unique
581d3a51819SDave May 
582d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField()
583d3a51819SDave May 
584d3a51819SDave May @*/
585b62e03f8SDave May #undef __FUNCT__
586b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterUserStructField"
5875f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
588b62e03f8SDave May {
5892eac95f8SDave May   PetscErrorCode ierr;
590b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
591b62e03f8SDave May 
5922eac95f8SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
593b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
594b62e03f8SDave May 
595b62e03f8SDave May   PetscFunctionReturn(0);
596b62e03f8SDave May }
597b62e03f8SDave May 
598d3a51819SDave May /*@C
599d3a51819SDave May 
600d3a51819SDave May  DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm
601d3a51819SDave May 
602d3a51819SDave May  Collective on DM
603d3a51819SDave May 
604d3a51819SDave May  Input parameters:
605d3a51819SDave May  . dm - a DMSwarm
606d3a51819SDave May  . fieldname - the textual name to identify this field
607d3a51819SDave May  . size - the size in bytes of the user data type
608d3a51819SDave May  . blocksize - the number of each data type
609d3a51819SDave May 
610d3a51819SDave May  Level: beginner
611d3a51819SDave May 
612d3a51819SDave May  Notes:
613d3a51819SDave May  The textual name for each registered field must be unique
614d3a51819SDave May 
615d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
616d3a51819SDave May 
617d3a51819SDave May @*/
618b62e03f8SDave May #undef __FUNCT__
619b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterUserDatatypeField"
620320740a0SDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize)
621b62e03f8SDave May {
622b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
6236845f8f5SDave May   PetscErrorCode ierr;
624b62e03f8SDave May 
625320740a0SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
626320740a0SDave May   {
627320740a0SDave May     DataField gfield;
628320740a0SDave May 
629320740a0SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
630320740a0SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
631320740a0SDave May   }
632b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
633b62e03f8SDave May 
634b62e03f8SDave May   PetscFunctionReturn(0);
635b62e03f8SDave May }
636b62e03f8SDave May 
637d3a51819SDave May /*@C
638d3a51819SDave May 
639d3a51819SDave May  DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field
640d3a51819SDave May 
641d3a51819SDave May  Not collective
642d3a51819SDave May 
643d3a51819SDave May  Input parameters:
644d3a51819SDave May  . dm - a DMSwarm
645d3a51819SDave May  . fieldname - the textual name to identify this field
646d3a51819SDave May 
647d3a51819SDave May  Output parameters:
648d3a51819SDave May  . blocksize - the number of each data type
649d3a51819SDave May  . type - the data type
650d3a51819SDave May  . data - pointer to raw array
651d3a51819SDave May 
652d3a51819SDave May  Level: beginner
653d3a51819SDave May 
654d3a51819SDave May  Notes:
655d3a51819SDave May  The user must call DMSwarmRestoreField()
656d3a51819SDave May 
657d3a51819SDave May  . seealso: DMSwarmRestoreField()
658d3a51819SDave May 
659d3a51819SDave May @*/
660b62e03f8SDave May #undef __FUNCT__
661b62e03f8SDave May #define __FUNCT__ "DMSwarmGetField"
6625f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
663b62e03f8SDave May {
664b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
665b62e03f8SDave May   DataField gfield;
6662eac95f8SDave May   PetscErrorCode ierr;
667b62e03f8SDave May 
6683454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
6693454631fSDave May 
6702eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6716845f8f5SDave May   ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr);
6726845f8f5SDave May   ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr);
6731b1ea282SDave May   if (blocksize) {*blocksize = gfield->bs; }
674b5bcf523SDave May   if (type) { *type = gfield->petsc_type; }
675b62e03f8SDave May 
676b62e03f8SDave May   PetscFunctionReturn(0);
677b62e03f8SDave May }
678b62e03f8SDave May 
679d3a51819SDave May /*@C
680d3a51819SDave May 
681d3a51819SDave May  DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field
682d3a51819SDave May 
683d3a51819SDave May  Not collective
684d3a51819SDave May 
685d3a51819SDave May  Input parameters:
686d3a51819SDave May  . dm - a DMSwarm
687d3a51819SDave May  . fieldname - the textual name to identify this field
688d3a51819SDave May 
689d3a51819SDave May  Output parameters:
690d3a51819SDave May  . blocksize - the number of each data type
691d3a51819SDave May  . type - the data type
692d3a51819SDave May  . data - pointer to raw array
693d3a51819SDave May 
694d3a51819SDave May  Level: beginner
695d3a51819SDave May 
696d3a51819SDave May  Notes:
697d3a51819SDave May  The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField()
698d3a51819SDave May 
699d3a51819SDave May  . seealso: DMSwarmGetField()
700d3a51819SDave May 
701d3a51819SDave May @*/
702b62e03f8SDave May #undef __FUNCT__
703b62e03f8SDave May #define __FUNCT__ "DMSwarmRestoreField"
7045f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
705b62e03f8SDave May {
706b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
707b62e03f8SDave May   DataField gfield;
7082eac95f8SDave May   PetscErrorCode ierr;
709b62e03f8SDave May 
7102eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
7116845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
712b62e03f8SDave May   if (data) *data = NULL;
713b62e03f8SDave May 
714b62e03f8SDave May   PetscFunctionReturn(0);
715b62e03f8SDave May }
716b62e03f8SDave May 
717d3a51819SDave May /*@C
718d3a51819SDave May 
719d3a51819SDave May  DMSwarmAddPoint - Add space for one new point in the DMSwarm
720d3a51819SDave May 
721d3a51819SDave May  Not collective
722d3a51819SDave May 
723d3a51819SDave May  Input parameter:
724d3a51819SDave May  . dm - a DMSwarm
725d3a51819SDave May 
726d3a51819SDave May  Level: beginner
727d3a51819SDave May 
728d3a51819SDave May  Notes:
729d3a51819SDave May  The new point will have all fields initialized to zero
730d3a51819SDave May 
731d3a51819SDave May  . seealso: DMSwarmAddNPoints()
732d3a51819SDave May 
733d3a51819SDave May @*/
734cb1d1399SDave May #undef __FUNCT__
735cb1d1399SDave May #define __FUNCT__ "DMSwarmAddPoint"
736cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
737cb1d1399SDave May {
738cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
739cb1d1399SDave May   PetscErrorCode ierr;
740cb1d1399SDave May 
7413454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
742cb1d1399SDave May   ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr);
743cb1d1399SDave May   PetscFunctionReturn(0);
744cb1d1399SDave May }
745cb1d1399SDave May 
746d3a51819SDave May /*@C
747d3a51819SDave May 
748d3a51819SDave May  DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm
749d3a51819SDave May 
750d3a51819SDave May  Not collective
751d3a51819SDave May 
752d3a51819SDave May  Input parameters:
753d3a51819SDave May  . dm - a DMSwarm
754d3a51819SDave May  . npoints - the number of new points to add
755d3a51819SDave May 
756d3a51819SDave May  Level: beginner
757d3a51819SDave May 
758d3a51819SDave May  Notes:
759d3a51819SDave May  The new point will have all fields initialized to zero
760d3a51819SDave May 
761d3a51819SDave May  . seealso: DMSwarmAddPoint()
762d3a51819SDave May 
763d3a51819SDave May @*/
764cb1d1399SDave May #undef __FUNCT__
765cb1d1399SDave May #define __FUNCT__ "DMSwarmAddNPoints"
766cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
767cb1d1399SDave May {
768cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
769cb1d1399SDave May   PetscErrorCode ierr;
770cb1d1399SDave May   PetscInt nlocal;
771cb1d1399SDave May 
772cb1d1399SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
773cb1d1399SDave May   nlocal = nlocal + npoints;
774cb1d1399SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,-1);CHKERRQ(ierr);
775cb1d1399SDave May   PetscFunctionReturn(0);
776cb1d1399SDave May }
777cb1d1399SDave May 
778d3a51819SDave May /*@C
779d3a51819SDave May 
780d3a51819SDave May  DMSwarmRemovePoint - Remove the last point from the DMSwarm
781d3a51819SDave May 
782d3a51819SDave May  Not collective
783d3a51819SDave May 
784d3a51819SDave May  Input parameter:
785d3a51819SDave May  . dm - a DMSwarm
786d3a51819SDave May 
787d3a51819SDave May  Level: beginner
788d3a51819SDave May 
789d3a51819SDave May  . seealso: DMSwarmRemovePointAtIndex()
790d3a51819SDave May 
791d3a51819SDave May @*/
792cb1d1399SDave May #undef __FUNCT__
793cb1d1399SDave May #define __FUNCT__ "DMSwarmRemovePoint"
794cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
795cb1d1399SDave May {
796cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
797cb1d1399SDave May   PetscErrorCode ierr;
798cb1d1399SDave May 
799cb1d1399SDave May   ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
800cb1d1399SDave May   PetscFunctionReturn(0);
801cb1d1399SDave May }
802cb1d1399SDave May 
803d3a51819SDave May /*@C
804d3a51819SDave May 
805d3a51819SDave May  DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm
806d3a51819SDave May 
807d3a51819SDave May  Not collective
808d3a51819SDave May 
809d3a51819SDave May  Input parameters:
810d3a51819SDave May  . dm - a DMSwarm
811d3a51819SDave May  . idx - index of point to remove
812d3a51819SDave May 
813d3a51819SDave May  Level: beginner
814d3a51819SDave May 
815d3a51819SDave May  . seealso: DMSwarmRemovePoint()
816d3a51819SDave May 
817d3a51819SDave May @*/
818cb1d1399SDave May #undef __FUNCT__
819cb1d1399SDave May #define __FUNCT__ "DMSwarmRemovePointAtIndex"
820cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
821cb1d1399SDave May {
822cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
823cb1d1399SDave May   PetscErrorCode ierr;
824cb1d1399SDave May 
825cb1d1399SDave May   ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
826cb1d1399SDave May   PetscFunctionReturn(0);
827cb1d1399SDave May }
828b62e03f8SDave May 
8293454631fSDave May #undef __FUNCT__
830095059a4SDave May #define __FUNCT__ "DMSwarmMigrate_Basic"
831095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points)
8323454631fSDave May {
833dcf43ee8SDave May   PetscErrorCode ierr;
834dcf43ee8SDave May   ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr);
8353454631fSDave May   PetscFunctionReturn(0);
8363454631fSDave May }
8373454631fSDave May 
838f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_CellDMScatter(DM dm,PetscBool remove_sent_points);
839f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_CellDMExact(DM dm,PetscBool remove_sent_points);
840f0cdbbbaSDave May 
841d3a51819SDave May /*@C
842d3a51819SDave May 
843d3a51819SDave May  DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks
844d3a51819SDave May 
845d3a51819SDave May  Collective on DM
846d3a51819SDave May 
847d3a51819SDave May  Input parameters:
848d3a51819SDave May  . dm - the DMSwarm
849d3a51819SDave May  . remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank
850d3a51819SDave May 
851d3a51819SDave May  Notes:
852d3a51819SDave May  The DM wil be modified to accomodate received points.
853d3a51819SDave May  If remove_sent_points = PETSC_TRUE, send points will be removed from the DM
854d3a51819SDave May  Different styles of migration are supported. See DMSwarmSetMigrateType()
855d3a51819SDave May 
856d3a51819SDave May  Level: advanced
857d3a51819SDave May 
858d3a51819SDave May  . seealso: DMSwarmSetMigrateType()
859d3a51819SDave May 
860d3a51819SDave May @*/
8613454631fSDave May #undef __FUNCT__
862095059a4SDave May #define __FUNCT__ "DMSwarmMigrate"
863095059a4SDave May PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points)
8643454631fSDave May {
865f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8663454631fSDave May   PetscErrorCode ierr;
867f0cdbbbaSDave May 
868f0cdbbbaSDave May   switch (swarm->migrate_type) {
869f0cdbbbaSDave May 
870f0cdbbbaSDave May     case DMSWARM_MIGRATE_BASIC:
871095059a4SDave May       ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr);
872f0cdbbbaSDave May       break;
873f0cdbbbaSDave May 
874f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLNSCATTER:
875f0cdbbbaSDave May       ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr);
876f0cdbbbaSDave May       break;
877f0cdbbbaSDave May 
878f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLEXACT:
879f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented");
880f0cdbbbaSDave May       //ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr);
881f0cdbbbaSDave May       break;
882f0cdbbbaSDave May 
883f0cdbbbaSDave May     case DMSWARM_MIGRATE_USER:
884f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented");
885f0cdbbbaSDave May       //ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr);
886f0cdbbbaSDave May       break;
887f0cdbbbaSDave May 
888f0cdbbbaSDave May     default:
889f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown");
890f0cdbbbaSDave May       break;
891f0cdbbbaSDave May   }
8923454631fSDave May   PetscFunctionReturn(0);
8933454631fSDave May }
8943454631fSDave May 
895f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize);
896f0cdbbbaSDave May 
897d3a51819SDave May /*
898d3a51819SDave May  DMSwarmCollectViewCreate
899d3a51819SDave May 
900d3a51819SDave May  * Applies a collection method and gathers point neighbour points into dm
901d3a51819SDave May 
902d3a51819SDave May  Notes:
903d3a51819SDave May  - Users should call DMSwarmCollectViewDestroy() after
904d3a51819SDave May  they have finished computations associated with the collected points
905d3a51819SDave May */
906d3a51819SDave May 
907d3a51819SDave May /*@C
908d3a51819SDave May 
909d3a51819SDave May  DMSwarmCollectViewCreate - Applies a collection method and gathers points
910d3a51819SDave May  in neighbour MPI-ranks into the DMSwarm
911d3a51819SDave May 
912d3a51819SDave May  Collective on DM
913d3a51819SDave May 
914d3a51819SDave May  Input parameter:
915d3a51819SDave May  . dm - the DMSwarm
916d3a51819SDave May 
917d3a51819SDave May  Notes:
918d3a51819SDave May  Users should call DMSwarmCollectViewDestroy() after
919d3a51819SDave May  they have finished computations associated with the collected points
920d3a51819SDave May  Different collect methods are supported. See DMSwarmSetCollectType()
921d3a51819SDave May 
922d3a51819SDave May  Level: advanced
923d3a51819SDave May 
924d3a51819SDave May  . seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType()
925d3a51819SDave May 
926d3a51819SDave May @*/
9272712d1f2SDave May #undef __FUNCT__
928fe39f135SDave May #define __FUNCT__ "DMSwarmCollectViewCreate"
929fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm)
9302712d1f2SDave May {
9312712d1f2SDave May   PetscErrorCode ierr;
9322712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9332712d1f2SDave May   PetscInt ng;
9342712d1f2SDave May 
935480eef7bSDave May   if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active");
9362712d1f2SDave May 
937480eef7bSDave May   ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr);
938480eef7bSDave May   switch (swarm->collect_type) {
939f0cdbbbaSDave May 
940480eef7bSDave May     case DMSWARM_COLLECT_BASIC:
9412712d1f2SDave May       ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr);
942480eef7bSDave May       break;
943f0cdbbbaSDave May 
944480eef7bSDave May     case DMSWARM_COLLECT_DMDABOUNDINGBOX:
945f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented");
946fe39f135SDave May       //ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr);
947480eef7bSDave May       break;
948f0cdbbbaSDave May 
949480eef7bSDave May     case DMSWARM_COLLECT_GENERAL:
950f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented");
951fe39f135SDave May       //ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr);
952480eef7bSDave May       break;
953480eef7bSDave May 
954480eef7bSDave May     default:
955f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown");
956480eef7bSDave May       break;
957480eef7bSDave May   }
958480eef7bSDave May 
959480eef7bSDave May   swarm->collect_view_active = PETSC_TRUE;
960480eef7bSDave May   swarm->collect_view_reset_nlocal = ng;
9612712d1f2SDave May 
9622712d1f2SDave May   PetscFunctionReturn(0);
9632712d1f2SDave May }
9642712d1f2SDave May 
965d3a51819SDave May /*@C
966d3a51819SDave May 
967d3a51819SDave May  DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate()
968d3a51819SDave May 
969d3a51819SDave May  Collective on DM
970d3a51819SDave May 
971d3a51819SDave May  Input parameters:
972d3a51819SDave May  . dm - the DMSwarm
973d3a51819SDave May 
974d3a51819SDave May  Notes:
975d3a51819SDave May  Users should call DMSwarmCollectViewCreate() before this function is called.
976d3a51819SDave May 
977d3a51819SDave May  Level: advanced
978d3a51819SDave May 
979d3a51819SDave May  . seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType()
980d3a51819SDave May 
981d3a51819SDave May @*/
9822712d1f2SDave May #undef __FUNCT__
983fe39f135SDave May #define __FUNCT__ "DMSwarmCollectViewDestroy"
984fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm)
9852712d1f2SDave May {
9862712d1f2SDave May   PetscErrorCode ierr;
9872712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9882712d1f2SDave May 
989480eef7bSDave May   if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active");
990480eef7bSDave May   ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr);
991480eef7bSDave May   swarm->collect_view_active = PETSC_FALSE;
9922712d1f2SDave May 
9932712d1f2SDave May   PetscFunctionReturn(0);
9942712d1f2SDave May }
9953454631fSDave May 
9963454631fSDave May #undef __FUNCT__
997f0cdbbbaSDave May #define __FUNCT__ "DMSwarmSetUpPIC"
998f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm)
999f0cdbbbaSDave May {
1000f0cdbbbaSDave May   PetscInt dim;
1001f0cdbbbaSDave May   PetscErrorCode ierr;
1002f0cdbbbaSDave May 
1003f0cdbbbaSDave May   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
1004f0cdbbbaSDave May   if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
1005f0cdbbbaSDave May   if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
1006f0cdbbbaSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr);
1007f0cdbbbaSDave May   PetscFunctionReturn(0);
1008f0cdbbbaSDave May }
1009f0cdbbbaSDave May 
1010d3a51819SDave May /*@C
1011d3a51819SDave May 
1012d3a51819SDave May  DMSwarmSetType - Set particular flavor of DMSwarm
1013d3a51819SDave May 
1014d3a51819SDave May  Collective on DM
1015d3a51819SDave May 
1016d3a51819SDave May  Input parameters:
1017d3a51819SDave May  . dm - the DMSwarm
1018d3a51819SDave May  . stype - the DMSwarm type (e.g. DMSWARM_PIC)
1019d3a51819SDave May 
1020d3a51819SDave May  Level: advanced
1021d3a51819SDave May 
1022d3a51819SDave May  . seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType()
1023d3a51819SDave May 
1024d3a51819SDave May @*/
1025cac75b86SDave May #undef __FUNCT__
1026f0cdbbbaSDave May #define __FUNCT__ "DMSwarmSetType"
1027f0cdbbbaSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype)
1028f0cdbbbaSDave May {
1029f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1030f0cdbbbaSDave May   PetscErrorCode ierr;
1031f0cdbbbaSDave May 
1032f0cdbbbaSDave May   swarm->swarm_type = stype;
1033f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
1034f0cdbbbaSDave May     ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr);
1035f0cdbbbaSDave May   }
1036f0cdbbbaSDave May   PetscFunctionReturn(0);
1037f0cdbbbaSDave May }
1038f0cdbbbaSDave May 
1039f0cdbbbaSDave May #undef __FUNCT__
10403454631fSDave May #define __FUNCT__ "DMSetup_Swarm"
10413454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm)
10423454631fSDave May {
10433454631fSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
10443454631fSDave May   PetscErrorCode ierr;
10453454631fSDave May   PetscMPIInt rank;
10463454631fSDave May   PetscInt p,npoints,*rankval;
10473454631fSDave May 
10483454631fSDave May   if (swarm->issetup) PetscFunctionReturn(0);
10493454631fSDave May 
10503454631fSDave May   swarm->issetup = PETSC_TRUE;
10513454631fSDave May 
1052f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
1053f0cdbbbaSDave May     /* check dmcell exists */
1054f0cdbbbaSDave May     if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM");
1055f0cdbbbaSDave May 
1056f0cdbbbaSDave May     if (swarm->dmcell->ops->locatepointssubdomain) {
1057f0cdbbbaSDave May       /* check methods exists for exact ownership identificiation */
1058f0cdbbbaSDave May       PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");
1059f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT;
1060f0cdbbbaSDave May     } else {
1061f0cdbbbaSDave May       /* check methods exist for point location AND rank neighbor identification */
1062f0cdbbbaSDave May       if (swarm->dmcell->ops->locatepoints) {
1063f0cdbbbaSDave May         PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->LocatePoints\n");
1064f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined");
1065f0cdbbbaSDave May 
1066f0cdbbbaSDave May       if (swarm->dmcell->ops->getneighbors) {
1067f0cdbbbaSDave May         PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->GetNeigbors\n");
1068f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined");
1069f0cdbbbaSDave May 
1070f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER;
1071f0cdbbbaSDave May     }
1072f0cdbbbaSDave May   }
1073f0cdbbbaSDave May 
1074f0cdbbbaSDave May   ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr);
1075f0cdbbbaSDave May 
10763454631fSDave May   /* check some fields were registered */
10773454631fSDave May   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
10783454631fSDave May 
10793454631fSDave May   /* check local sizes were set */
10803454631fSDave May   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
10813454631fSDave May 
10823454631fSDave May   /* initialize values in pid and rank placeholders */
10833454631fSDave May   /* TODO: [pid - use MPI_Scan] */
10843454631fSDave May 
10853454631fSDave May   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
10863454631fSDave May   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
1087f0cdbbbaSDave May   ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10883454631fSDave May   for (p=0; p<npoints; p++) {
10893454631fSDave May     rankval[p] = (PetscInt)rank;
10903454631fSDave May   }
1091f0cdbbbaSDave May   ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10923454631fSDave May 
10933454631fSDave May   PetscFunctionReturn(0);
10943454631fSDave May }
10953454631fSDave May 
1096b62e03f8SDave May #undef __FUNCT__
109757795646SDave May #define __FUNCT__ "DMDestroy_Swarm"
109857795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm)
109957795646SDave May {
110057795646SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
110157795646SDave May   PetscErrorCode ierr;
110257795646SDave May 
110357795646SDave May   PetscFunctionBegin;
11046845f8f5SDave May   ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr);
110557795646SDave May   ierr = PetscFree(swarm);CHKERRQ(ierr);
110657795646SDave May   PetscFunctionReturn(0);
110757795646SDave May }
110857795646SDave May 
110957795646SDave May #undef __FUNCT__
1110a9ee3421SMatthew G. Knepley #define __FUNCT__ "DMSwarmView_Draw"
1111a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer)
1112a9ee3421SMatthew G. Knepley {
1113a9ee3421SMatthew G. Knepley   DM             cdm;
1114a9ee3421SMatthew G. Knepley   PetscDraw      draw;
1115a9ee3421SMatthew G. Knepley   PetscReal     *coords, oldPause;
1116a9ee3421SMatthew G. Knepley   PetscInt       Np, p, bs;
1117a9ee3421SMatthew G. Knepley   PetscErrorCode ierr;
1118a9ee3421SMatthew G. Knepley 
1119a9ee3421SMatthew G. Knepley   PetscFunctionBegin;
1120a9ee3421SMatthew G. Knepley   ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr);
1121a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr);
1122a9ee3421SMatthew G. Knepley   ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr);
1123a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr);
1124a9ee3421SMatthew G. Knepley   ierr = DMView(cdm, viewer);CHKERRQ(ierr);
1125a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr);
1126a9ee3421SMatthew G. Knepley 
1127a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr);
1128a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1129a9ee3421SMatthew G. Knepley   for (p = 0; p < Np; ++p) {
1130a9ee3421SMatthew G. Knepley     const PetscInt i = p*bs;
1131a9ee3421SMatthew G. Knepley 
1132a9ee3421SMatthew G. Knepley     ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], 0.01, 0.01, PETSC_DRAW_BLUE);CHKERRQ(ierr);
1133a9ee3421SMatthew G. Knepley   }
1134a9ee3421SMatthew G. Knepley   ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1135a9ee3421SMatthew G. Knepley   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
1136a9ee3421SMatthew G. Knepley   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
1137a9ee3421SMatthew G. Knepley   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1138a9ee3421SMatthew G. Knepley   PetscFunctionReturn(0);
1139a9ee3421SMatthew G. Knepley }
1140a9ee3421SMatthew G. Knepley 
1141a9ee3421SMatthew G. Knepley #undef __FUNCT__
11425f50eb2eSDave May #define __FUNCT__ "DMView_Swarm"
11435f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
11445f50eb2eSDave May {
11455f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1146a9ee3421SMatthew G. Knepley   PetscBool      iascii,ibinary,ishdf5,isvtk,isdraw;
11475f50eb2eSDave May   PetscErrorCode ierr;
11485f50eb2eSDave May 
11495f50eb2eSDave May   PetscFunctionBegin;
11505f50eb2eSDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
11515f50eb2eSDave May   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
11525f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
11535f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
11545f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
11555f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1156a9ee3421SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW,  &isdraw);CHKERRQ(ierr);
11575f50eb2eSDave May   if (iascii) {
11586845f8f5SDave May     ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
11595f50eb2eSDave May   } else if (ibinary) {
1160a9ee3421SMatthew G. Knepley     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support");
11615f50eb2eSDave May   } else if (ishdf5) {
11625f50eb2eSDave May #if defined(PETSC_HAVE_HDF5)
11635f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
11645f50eb2eSDave May #else
11655f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
11665f50eb2eSDave May #endif
11675f50eb2eSDave May   } else if (isvtk) {
11685f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
1169a9ee3421SMatthew G. Knepley   } else if (isdraw) {
1170a9ee3421SMatthew G. Knepley     ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr);
11715f50eb2eSDave May   }
11725f50eb2eSDave May   PetscFunctionReturn(0);
11735f50eb2eSDave May }
11745f50eb2eSDave May 
1175d3a51819SDave May /*MC
1176d3a51819SDave May 
1177d3a51819SDave May  DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type.
1178d3a51819SDave May  This implementation was designed for particle-in-cell type methods in which the underlying
1179d3a51819SDave May  data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type.
1180d3a51819SDave May 
1181d3a51819SDave May  User data can be represented by DMSwarm through a registring "fields".
1182d3a51819SDave May  To register a field, the user must provide:
1183d3a51819SDave May  (a) a unique name
1184d3a51819SDave May  (b) the data type (or size in bytes)
1185d3a51819SDave May  (c) the block size of the data
1186d3a51819SDave May 
1187d3a51819SDave May  For example, suppose the application requires a unique id, energy, momentum and density to be stored
1188d3a51819SDave May  on a set of of particles. Then the following application could be used
1189d3a51819SDave May 
1190d3a51819SDave May  DMSwarmInitializeFieldRegister(dm)
1191d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG);
1192d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL);
1193d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL);
1194d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT);
1195d3a51819SDave May  DMSwarmFinalizeFieldRegister(dm)
1196d3a51819SDave May 
1197d3a51819SDave May  The fields represented by DMSwarm are dynamic and can be re-sized at any time.
1198d3a51819SDave May  The only restriction imposed by DMSwarm is that all fields contain the same number of points
1199d3a51819SDave May 
1200d3a51819SDave May  To support particle methods, "migration" techniques are provided. These methods migrate data
1201d3a51819SDave May  between MPI-ranks.
1202d3a51819SDave May 
1203d3a51819SDave May  DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector().
1204d3a51819SDave May  As a DMSwarm may internally define and store values of different data types,
1205d3a51819SDave May  before calling DMCreate{Global/Local}Vector() the user must inform DMSwarm which
1206d3a51819SDave May  fields should be used to define a Vec object via
1207d3a51819SDave May    DMSwarmVectorDefineField()
1208d3a51819SDave May  The specified field can can changed be changed at any time - thereby permitting vectors
1209d3a51819SDave May  compatable with different fields to be created.
1210d3a51819SDave May 
1211d3a51819SDave May  A dual representation of fields in the DMSwarm and a Vec object are permitted via
1212d3a51819SDave May    DMSwarmCreateGlobalVectorFromField()
1213d3a51819SDave May  Here the data defining the field in the DMSwarm is shared with a Vec.
1214d3a51819SDave May  This is inherently unsafe if you alter the size of the field at any time between
1215d3a51819SDave May  calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField().
1216cc651181SDave May  If the local size of the DMSwarm does not match the localsize of the global vector
1217cc651181SDave May  when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown.
1218d3a51819SDave May 
1219d3a51819SDave May  Level: beginner
1220d3a51819SDave May 
1221d3a51819SDave May  .seealso: DMType, DMCreate(), DMSetType()
1222d3a51819SDave May 
1223d3a51819SDave May M*/
12245f50eb2eSDave May #undef __FUNCT__
122557795646SDave May #define __FUNCT__ "DMCreate_Swarm"
122657795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
122757795646SDave May {
122857795646SDave May   DM_Swarm      *swarm;
122957795646SDave May   PetscErrorCode ierr;
123057795646SDave May 
123157795646SDave May   PetscFunctionBegin;
123257795646SDave May   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
123357795646SDave May   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
1234f0cdbbbaSDave May   dm->data = swarm;
123557795646SDave May 
12366845f8f5SDave May   ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr);
1237f0cdbbbaSDave May   ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr);
1238f0cdbbbaSDave May 
1239b5bcf523SDave May   swarm->vec_field_set = PETSC_FALSE;
12403454631fSDave May   swarm->issetup = PETSC_FALSE;
1241480eef7bSDave May   swarm->swarm_type = DMSWARM_BASIC;
1242480eef7bSDave May   swarm->migrate_type = DMSWARM_MIGRATE_BASIC;
1243480eef7bSDave May   swarm->collect_type = DMSWARM_COLLECT_BASIC;
124440c453e9SDave May   swarm->migrate_error_on_missing_point = PETSC_FALSE;
1245b62e03f8SDave May 
1246f0cdbbbaSDave May   swarm->dmcell = NULL;
1247f0cdbbbaSDave May   swarm->collect_view_active = PETSC_FALSE;
1248f0cdbbbaSDave May   swarm->collect_view_reset_nlocal = -1;
124957795646SDave May 
1250f0cdbbbaSDave May   dm->dim  = 0;
12515f50eb2eSDave May   dm->ops->view                            = DMView_Swarm;
125257795646SDave May   dm->ops->load                            = NULL;
125357795646SDave May   dm->ops->setfromoptions                  = NULL;
125457795646SDave May   dm->ops->clone                           = NULL;
12553454631fSDave May   dm->ops->setup                           = DMSetup_Swarm;
125657795646SDave May   dm->ops->createdefaultsection            = NULL;
125757795646SDave May   dm->ops->createdefaultconstraints        = NULL;
1258b5bcf523SDave May   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
1259b5bcf523SDave May   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
126057795646SDave May   dm->ops->getlocaltoglobalmapping         = NULL;
126157795646SDave May   dm->ops->createfieldis                   = NULL;
126257795646SDave May   dm->ops->createcoordinatedm              = NULL;
126357795646SDave May   dm->ops->getcoloring                     = NULL;
126457795646SDave May   dm->ops->creatematrix                    = NULL;
126557795646SDave May   dm->ops->createinterpolation             = NULL;
126657795646SDave May   dm->ops->getaggregates                   = NULL;
126757795646SDave May   dm->ops->getinjection                    = NULL;
126857795646SDave May   dm->ops->refine                          = NULL;
126957795646SDave May   dm->ops->coarsen                         = NULL;
127057795646SDave May   dm->ops->refinehierarchy                 = NULL;
127157795646SDave May   dm->ops->coarsenhierarchy                = NULL;
127257795646SDave May   dm->ops->globaltolocalbegin              = NULL;
127357795646SDave May   dm->ops->globaltolocalend                = NULL;
127457795646SDave May   dm->ops->localtoglobalbegin              = NULL;
127557795646SDave May   dm->ops->localtoglobalend                = NULL;
127657795646SDave May   dm->ops->destroy                         = DMDestroy_Swarm;
127757795646SDave May   dm->ops->createsubdm                     = NULL;
127857795646SDave May   dm->ops->getdimpoints                    = NULL;
127957795646SDave May   dm->ops->locatepoints                    = NULL;
128057795646SDave May 
128157795646SDave May   PetscFunctionReturn(0);
128257795646SDave May }
1283