xref: /petsc/src/dm/impls/swarm/swarm.c (revision a9cbaee5c2994e378c681fd43fb188524e305334)
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 
47*a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
483454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
496845f8f5SDave May   ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr);
50b5bcf523SDave May   ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
51b5bcf523SDave May 
52b5bcf523SDave May   /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */
53b5bcf523SDave May   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL");
54b5bcf523SDave May 
55b5bcf523SDave May   PetscSNPrintf(swarm->vec_field_name,PETSC_MAX_PATH_LEN-1,"%s",fieldname);
56b5bcf523SDave May   swarm->vec_field_set = PETSC_TRUE;
571b1ea282SDave May   swarm->vec_field_bs = bs;
58b5bcf523SDave May   swarm->vec_field_nlocal = n;
59dcf43ee8SDave May   ierr = DMSwarmRestoreField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
60b5bcf523SDave May 
61b5bcf523SDave May   PetscFunctionReturn(0);
62b5bcf523SDave May }
63b5bcf523SDave May 
64cc651181SDave May /* requires DMSwarmDefineFieldVector has been called */
65b5bcf523SDave May #undef __FUNCT__
66b5bcf523SDave May #define __FUNCT__ "DMCreateGlobalVector_Swarm"
67b5bcf523SDave May PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec)
68b5bcf523SDave May {
69b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
70b5bcf523SDave May   PetscErrorCode ierr;
71b5bcf523SDave May   Vec x;
72b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
73b5bcf523SDave May 
74*a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
753454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
76b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
77cc651181SDave 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 */
78cc651181SDave May 
79b5bcf523SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);
80b5bcf523SDave May   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr);
81b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
821b1ea282SDave May   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr);
83b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
84b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
85b5bcf523SDave May   *vec = x;
86b5bcf523SDave May 
87b5bcf523SDave May   PetscFunctionReturn(0);
88b5bcf523SDave May }
89b5bcf523SDave May 
90b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */
91b5bcf523SDave May #undef __FUNCT__
92b5bcf523SDave May #define __FUNCT__ "DMCreateLocalVector_Swarm"
93b5bcf523SDave May PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec)
94b5bcf523SDave May {
95b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
96b5bcf523SDave May   PetscErrorCode ierr;
97b5bcf523SDave May   Vec x;
98b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
99b5bcf523SDave May 
100*a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
1013454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
102b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
103cc651181SDave 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 */
104cc651181SDave May 
105b5bcf523SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);
106b5bcf523SDave May   ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr);
107b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
108071900c8SMatthew G. Knepley   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr);
109b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
110b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
111b5bcf523SDave May   *vec = x;
112b5bcf523SDave May 
113b5bcf523SDave May   PetscFunctionReturn(0);
114b5bcf523SDave May }
115b5bcf523SDave May 
116fb1bcc12SMatthew G. Knepley #undef __FUNCT__
117fb1bcc12SMatthew G. Knepley #define __FUNCT__ "DMSwarmDestroyVectorFromField_Private"
118fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmDestroyVectorFromField_Private(DM dm, const char fieldname[], Vec *vec)
119fb1bcc12SMatthew G. Knepley {
120fb1bcc12SMatthew G. Knepley   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
121fb1bcc12SMatthew G. Knepley   DataField      gfield;
122fb1bcc12SMatthew G. Knepley   void         (*fptr)(void);
123fb1bcc12SMatthew G. Knepley   PetscInt       bs, nlocal;
124fb1bcc12SMatthew G. Knepley   char           name[PETSC_MAX_PATH_LEN];
125fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
126d3a51819SDave May 
127fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
128fb1bcc12SMatthew G. Knepley   ierr = VecGetLocalSize(*vec, &nlocal);CHKERRQ(ierr);
129fb1bcc12SMatthew G. Knepley   ierr = VecGetBlockSize(*vec, &bs);CHKERRQ(ierr);
130fb1bcc12SMatthew 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 */
131fb1bcc12SMatthew G. Knepley   ierr = DataBucketGetDataFieldByName(swarm->db, fieldname, &gfield);CHKERRQ(ierr);
132fb1bcc12SMatthew G. Knepley   /* check vector is an inplace array */
133fb1bcc12SMatthew G. Knepley   PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);
134fb1bcc12SMatthew G. Knepley   ierr = PetscObjectQueryFunction((PetscObject) *vec, name, &fptr);CHKERRQ(ierr);
135fb1bcc12SMatthew G. Knepley   if (!fptr) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Vector being destroyed was not created from DMSwarm field(%s)", fieldname);
136fb1bcc12SMatthew G. Knepley   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
137fb1bcc12SMatthew G. Knepley   ierr = VecDestroy(vec);CHKERRQ(ierr);
138fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
139fb1bcc12SMatthew G. Knepley }
140fb1bcc12SMatthew G. Knepley 
141fb1bcc12SMatthew G. Knepley #undef __FUNCT__
142fb1bcc12SMatthew G. Knepley #define __FUNCT__ "DMSwarmCreateVectorFromField_Private"
143fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmCreateVectorFromField_Private(DM dm, const char fieldname[], MPI_Comm comm, Vec *vec)
144fb1bcc12SMatthew G. Knepley {
145fb1bcc12SMatthew G. Knepley   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
146fb1bcc12SMatthew G. Knepley   DataField      gfield;
147fb1bcc12SMatthew G. Knepley   void         (*fptr)(void);
148fb1bcc12SMatthew G. Knepley   PetscDataType  type;
149fb1bcc12SMatthew G. Knepley   PetscScalar   *array;
150fb1bcc12SMatthew G. Knepley   PetscInt       bs, n;
151fb1bcc12SMatthew G. Knepley   char           name[PETSC_MAX_PATH_LEN];
152fb1bcc12SMatthew G. Knepley   PetscMPIInt    commsize;
153fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
154fb1bcc12SMatthew G. Knepley 
155fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
156fb1bcc12SMatthew G. Knepley   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
157fb1bcc12SMatthew G. Knepley   ierr = DataBucketGetSizes(swarm->db, &n, NULL, NULL);CHKERRQ(ierr);
158fb1bcc12SMatthew G. Knepley   ierr = DMSwarmGetField(dm, fieldname, &bs, &type, (void **) &array);CHKERRQ(ierr);
159fb1bcc12SMatthew G. Knepley   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Only valid for PETSC_REAL");
160fb1bcc12SMatthew G. Knepley 
161fb1bcc12SMatthew G. Knepley   ierr = MPI_Comm_size(comm, &commsize);CHKERRQ(ierr);
162fb1bcc12SMatthew G. Knepley   if (commsize == 1) {
163fb1bcc12SMatthew G. Knepley     ierr = VecCreateSeqWithArray(comm, bs, n*bs, array, vec);CHKERRQ(ierr);
164fb1bcc12SMatthew G. Knepley   } else {
165fb1bcc12SMatthew G. Knepley     ierr = VecCreateMPIWithArray(comm, bs, n*bs, PETSC_DETERMINE, array, vec);CHKERRQ(ierr);
166fb1bcc12SMatthew G. Knepley   }
167fb1bcc12SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarmSharedField_%s", fieldname);CHKERRQ(ierr);
168fb1bcc12SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) *vec, name);CHKERRQ(ierr);
169fb1bcc12SMatthew G. Knepley 
170fb1bcc12SMatthew G. Knepley   /* Set guard */
171fb1bcc12SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr);
172fb1bcc12SMatthew G. Knepley   ierr = PetscObjectComposeFunction((PetscObject) *vec, name, DMSwarmDestroyVectorFromField_Private);CHKERRQ(ierr);
173fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
174fb1bcc12SMatthew G. Knepley }
175fb1bcc12SMatthew G. Knepley 
176fb1bcc12SMatthew G. Knepley /*@C
177d3a51819SDave May   DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field
178d3a51819SDave May 
179d3a51819SDave May   Collective on DM
180d3a51819SDave May 
181d3a51819SDave May   Input parameters:
182d3a51819SDave May  . dm - a DMSwarm
183d3a51819SDave May  . fieldname - the textual name given to a registered field
184d3a51819SDave May 
185d3a51819SDave May  Output parameters:
186d3a51819SDave May  . vec - the vector
187d3a51819SDave May 
188d3a51819SDave May   Level: beginner
189d3a51819SDave May 
190d3a51819SDave May . seealso: DMSwarmRegisterPetscDatatypeField()
191d3a51819SDave May @*/
192b5bcf523SDave May #undef __FUNCT__
193b5bcf523SDave May #define __FUNCT__ "DMSwarmCreateGlobalVectorFromField"
194b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
195b5bcf523SDave May {
196fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PetscObjectComm((PetscObject) dm);
197b5bcf523SDave May   PetscErrorCode ierr;
198b5bcf523SDave May 
199fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
200fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
201b5bcf523SDave May   PetscFunctionReturn(0);
202b5bcf523SDave May }
203b5bcf523SDave May 
204d3a51819SDave May /*@C
205d3a51819SDave May   DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field
206d3a51819SDave May 
207d3a51819SDave May   Collective on DM
208d3a51819SDave May 
209d3a51819SDave May   Input parameters:
210d3a51819SDave May  . dm - a DMSwarm
211d3a51819SDave May  . fieldname - the textual name given to a registered field
212d3a51819SDave May 
213d3a51819SDave May   Output parameters:
214d3a51819SDave May  . vec - the vector
215d3a51819SDave May 
216d3a51819SDave May   Level: beginner
217d3a51819SDave May 
218d3a51819SDave May . seealso: DMSwarmRegisterPetscDatatypeField()
219d3a51819SDave May @*/
220b5bcf523SDave May #undef __FUNCT__
221b5bcf523SDave May #define __FUNCT__ "DMSwarmDestroyGlobalVectorFromField"
222b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
223b5bcf523SDave May {
224b5bcf523SDave May   PetscErrorCode ierr;
225cc651181SDave May 
226fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
227fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
228b5bcf523SDave May   PetscFunctionReturn(0);
229b5bcf523SDave May }
230b5bcf523SDave May 
231fb1bcc12SMatthew G. Knepley /*@C
232fb1bcc12SMatthew G. Knepley   DMSwarmCreateLocalVectorFromField - Creates a Vec object sharing the array associated with a given field
233fb1bcc12SMatthew G. Knepley 
234fb1bcc12SMatthew G. Knepley   Collective on DM
235fb1bcc12SMatthew G. Knepley 
236fb1bcc12SMatthew G. Knepley   Input parameters:
237fb1bcc12SMatthew G. Knepley  . dm - a DMSwarm
238fb1bcc12SMatthew G. Knepley  . fieldname - the textual name given to a registered field
239fb1bcc12SMatthew G. Knepley 
240fb1bcc12SMatthew G. Knepley  Output parameters:
241fb1bcc12SMatthew G. Knepley  . vec - the vector
242fb1bcc12SMatthew G. Knepley 
243fb1bcc12SMatthew G. Knepley   Level: beginner
244fb1bcc12SMatthew G. Knepley 
245fb1bcc12SMatthew G. Knepley . seealso: DMSwarmRegisterPetscDatatypeField()
246fb1bcc12SMatthew G. Knepley @*/
247bbe8250bSMatthew G. Knepley #undef __FUNCT__
248fb1bcc12SMatthew G. Knepley #define __FUNCT__ "DMSwarmCreateLocalVectorFromField"
249fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmCreateLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
250bbe8250bSMatthew G. Knepley {
251fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PETSC_COMM_SELF;
252bbe8250bSMatthew G. Knepley   PetscErrorCode ierr;
253bbe8250bSMatthew G. Knepley 
254fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
255fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
256fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
257bbe8250bSMatthew G. Knepley }
258fb1bcc12SMatthew G. Knepley 
259fb1bcc12SMatthew G. Knepley /*@C
260fb1bcc12SMatthew G. Knepley   DMSwarmDestroyLocalVectorFromField - Destroys the Vec object which share the array associated with a given field
261fb1bcc12SMatthew G. Knepley 
262fb1bcc12SMatthew G. Knepley   Collective on DM
263fb1bcc12SMatthew G. Knepley 
264fb1bcc12SMatthew G. Knepley   Input parameters:
265fb1bcc12SMatthew G. Knepley  . dm - a DMSwarm
266fb1bcc12SMatthew G. Knepley  . fieldname - the textual name given to a registered field
267fb1bcc12SMatthew G. Knepley 
268fb1bcc12SMatthew G. Knepley   Output parameters:
269fb1bcc12SMatthew G. Knepley  . vec - the vector
270fb1bcc12SMatthew G. Knepley 
271fb1bcc12SMatthew G. Knepley   Level: beginner
272fb1bcc12SMatthew G. Knepley 
273fb1bcc12SMatthew G. Knepley . seealso: DMSwarmRegisterPetscDatatypeField()
274fb1bcc12SMatthew G. Knepley @*/
275fb1bcc12SMatthew G. Knepley #undef __FUNCT__
276fb1bcc12SMatthew G. Knepley #define __FUNCT__ "DMSwarmDestroyLocalVectorFromField"
277fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmDestroyLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
278fb1bcc12SMatthew G. Knepley {
279fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
280fb1bcc12SMatthew G. Knepley 
281fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
282fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
283bbe8250bSMatthew G. Knepley   PetscFunctionReturn(0);
284bbe8250bSMatthew G. Knepley }
285bbe8250bSMatthew G. Knepley 
286b5bcf523SDave May /*
287b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec)
288b5bcf523SDave May {
289b5bcf523SDave May   PetscFunctionReturn(0);
290b5bcf523SDave May }
291b5bcf523SDave May 
292b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec)
293b5bcf523SDave May {
294b5bcf523SDave May   PetscFunctionReturn(0);
295b5bcf523SDave May }
296b5bcf523SDave May */
297b5bcf523SDave May 
298d3a51819SDave May 
299d3a51819SDave May /*@C
300d3a51819SDave May 
301d3a51819SDave May  DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm
302d3a51819SDave May 
303d3a51819SDave May  Collective on DM
304d3a51819SDave May 
305d3a51819SDave May  Input parameter:
306d3a51819SDave May  . dm - a DMSwarm
307d3a51819SDave May 
308d3a51819SDave May  Level: beginner
309d3a51819SDave May 
310d3a51819SDave May  Notes:
311d3a51819SDave May  After all fields have been registered, users should call DMSwarmFinalizeFieldRegister()
312d3a51819SDave May 
313d3a51819SDave May  . seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
314d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
315d3a51819SDave May 
316d3a51819SDave May @*/
317b5bcf523SDave May #undef __FUNCT__
3185f50eb2eSDave May #define __FUNCT__ "DMSwarmInitializeFieldRegister"
3195f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm)
3205f50eb2eSDave May {
3215f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3223454631fSDave May   PetscErrorCode ierr;
3233454631fSDave May 
324cc651181SDave May   if (!swarm->field_registration_initialized) {
3255f50eb2eSDave May     swarm->field_registration_initialized = PETSC_TRUE;
326f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */
327f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */
328cc651181SDave May   }
3293454631fSDave May 
3305f50eb2eSDave May   PetscFunctionReturn(0);
3315f50eb2eSDave May }
3325f50eb2eSDave May 
333d3a51819SDave May /*@C
334d3a51819SDave May 
335d3a51819SDave May  DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm
336d3a51819SDave May 
337d3a51819SDave May  Collective on DM
338d3a51819SDave May 
339d3a51819SDave May  Input parameter:
340d3a51819SDave May  . dm - a DMSwarm
341d3a51819SDave May 
342d3a51819SDave May  Level: beginner
343d3a51819SDave May 
344d3a51819SDave May  Notes:
345d3a51819SDave May  After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined
346d3a51819SDave May  on the DMSwarm
347d3a51819SDave May 
348d3a51819SDave May  . seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
349d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
350d3a51819SDave May 
351d3a51819SDave May @*/
3525f50eb2eSDave May #undef __FUNCT__
3535f50eb2eSDave May #define __FUNCT__ "DMSwarmFinalizeFieldRegister"
3545f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm)
3555f50eb2eSDave May {
3565f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3576845f8f5SDave May   PetscErrorCode ierr;
3586845f8f5SDave May 
359f0cdbbbaSDave May   if (!swarm->field_registration_finalized) {
3606845f8f5SDave May     ierr = DataBucketFinalize(swarm->db);CHKERRQ(ierr);
361f0cdbbbaSDave May   }
362f0cdbbbaSDave May   swarm->field_registration_finalized = PETSC_TRUE;
3635f50eb2eSDave May   PetscFunctionReturn(0);
3645f50eb2eSDave May }
3655f50eb2eSDave May 
366d3a51819SDave May /*@C
367d3a51819SDave May 
368d3a51819SDave May  DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm
369d3a51819SDave May 
370d3a51819SDave May  Not collective
371d3a51819SDave May 
372d3a51819SDave May  Input parameters:
373d3a51819SDave May  . dm - a DMSwarm
374d3a51819SDave May  . nlocal - the length of each registered field
375d3a51819SDave May  . buffer - the length of the buffer used to efficient dynamic re-sizing
376d3a51819SDave May 
377d3a51819SDave May  Level: beginner
378d3a51819SDave May 
379d3a51819SDave May  . seealso: DMSwarmGetLocalSize()
380d3a51819SDave May 
381d3a51819SDave May @*/
3825f50eb2eSDave May #undef __FUNCT__
3835f50eb2eSDave May #define __FUNCT__ "DMSwarmSetLocalSizes"
3845f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer)
3855f50eb2eSDave May {
3865f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3876845f8f5SDave May   PetscErrorCode ierr;
3885f50eb2eSDave May 
3896845f8f5SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr);
3905f50eb2eSDave May 
3915f50eb2eSDave May   PetscFunctionReturn(0);
3925f50eb2eSDave May }
3935f50eb2eSDave May 
394d3a51819SDave May /*@C
395d3a51819SDave May 
396d3a51819SDave May  DMSwarmSetCellDM - Attachs a DM to a DMSwarm
397d3a51819SDave May 
398d3a51819SDave May  Collective on DM
399d3a51819SDave May 
400d3a51819SDave May  Input parameters:
401d3a51819SDave May  . dm - a DMSwarm
402d3a51819SDave May  . dmcell - the DM to attach to the DMSwarm
403d3a51819SDave May 
404d3a51819SDave May  Level: beginner
405d3a51819SDave May 
406d3a51819SDave May  Notes:
407d3a51819SDave May  The attached DM (dmcell) will be queried for pointlocation and
408d3a51819SDave May  neighbor MPI-rank information if DMSwarmMigrate() is called
409d3a51819SDave May 
410d3a51819SDave May  . seealso: DMSwarmGetCellDM(), DMSwarmMigrate()
411d3a51819SDave May 
412d3a51819SDave May @*/
4135f50eb2eSDave May #undef __FUNCT__
414b16650c8SDave May #define __FUNCT__ "DMSwarmSetCellDM"
415b16650c8SDave May PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell)
416b16650c8SDave May {
417b16650c8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
418b16650c8SDave May   swarm->dmcell = dmcell;
419b16650c8SDave May   PetscFunctionReturn(0);
420b16650c8SDave May }
421b16650c8SDave May 
422d3a51819SDave May /*@C
423d3a51819SDave May 
424d3a51819SDave May  DMSwarmGetCellDM - Fetches the attached cell DM
425d3a51819SDave May 
426d3a51819SDave May  Collective on DM
427d3a51819SDave May 
428d3a51819SDave May  Input parameter:
429d3a51819SDave May  . dm - a DMSwarm
430d3a51819SDave May 
431d3a51819SDave May  Output parameter:
432d3a51819SDave May  . dmcell - the DM which was attached to the DMSwarm
433d3a51819SDave May 
434d3a51819SDave May  Level: beginner
435d3a51819SDave May 
436d3a51819SDave May  Notes:
437d3a51819SDave May  The attached DM (dmcell) will be queried for pointlocation and
438d3a51819SDave May  neighbor MPI-rank information if DMSwarmMigrate() is called
439d3a51819SDave May 
440d3a51819SDave May  . seealso: DMSwarmSetCellDM()
441d3a51819SDave May 
442d3a51819SDave May @*/
443b16650c8SDave May #undef __FUNCT__
444fe39f135SDave May #define __FUNCT__ "DMSwarmGetCellDM"
445fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell)
446fe39f135SDave May {
447fe39f135SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
448fe39f135SDave May   *dmcell = swarm->dmcell;
449fe39f135SDave May   PetscFunctionReturn(0);
450fe39f135SDave May }
451fe39f135SDave May 
452d3a51819SDave May /*@C
453d3a51819SDave May 
454d3a51819SDave May  DMSwarmGetLocalSize - Retrives the local length of fields registered
455d3a51819SDave May 
456d3a51819SDave May  Not collective
457d3a51819SDave May 
458d3a51819SDave May  Input parameter:
459d3a51819SDave May  . dm - a DMSwarm
460d3a51819SDave May 
461d3a51819SDave May  Output parameter:
462d3a51819SDave May  . nlocal - the length of each registered field
463d3a51819SDave May 
464d3a51819SDave May  Level: beginner
465d3a51819SDave May 
466d3a51819SDave May  . seealso: DMSwarmSetLocalSizes()
467d3a51819SDave May 
468d3a51819SDave May @*/
469fe39f135SDave May #undef __FUNCT__
470dcf43ee8SDave May #define __FUNCT__ "DMSwarmGetLocalSize"
471dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal)
472dcf43ee8SDave May {
473dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
474dcf43ee8SDave May   PetscErrorCode ierr;
475dcf43ee8SDave May 
476dcf43ee8SDave May   if (nlocal) {
477dcf43ee8SDave May     ierr = DataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);
478dcf43ee8SDave May   }
479dcf43ee8SDave May 
480dcf43ee8SDave May   PetscFunctionReturn(0);
481dcf43ee8SDave May }
482dcf43ee8SDave May 
483d3a51819SDave May /*@C
484d3a51819SDave May 
485d3a51819SDave May  DMSwarmGetSize - Retrives the total length of fields registered
486d3a51819SDave May 
487d3a51819SDave May  Collective on DM
488d3a51819SDave May 
489d3a51819SDave May  Input parameter:
490d3a51819SDave May  . dm - a DMSwarm
491d3a51819SDave May 
492d3a51819SDave May  Output parameter:
493d3a51819SDave May  . n - the total length of each registered field
494d3a51819SDave May 
495d3a51819SDave May  Level: beginner
496d3a51819SDave May 
497d3a51819SDave May  Note:
498d3a51819SDave May  This calls MPI_Allreduce upon each call (inefficient but safe)
499d3a51819SDave May 
500d3a51819SDave May  . seealso: DMSwarmGetLocalSize()
501d3a51819SDave May 
502d3a51819SDave May @*/
503dcf43ee8SDave May #undef __FUNCT__
504dcf43ee8SDave May #define __FUNCT__ "DMSwarmGetSize"
505dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n)
506dcf43ee8SDave May {
507dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
508dcf43ee8SDave May   PetscErrorCode ierr;
509dcf43ee8SDave May   PetscInt nlocal,ng;
510dcf43ee8SDave May 
511dcf43ee8SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
512dcf43ee8SDave May   ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
513dcf43ee8SDave May   if (n) { *n = ng; }
514dcf43ee8SDave May   PetscFunctionReturn(0);
515dcf43ee8SDave May }
516dcf43ee8SDave May 
517d3a51819SDave May /*@C
518d3a51819SDave May 
519d3a51819SDave May  DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm
520d3a51819SDave May 
521d3a51819SDave May  Collective on DM
522d3a51819SDave May 
523d3a51819SDave May  Input parameters:
524d3a51819SDave May  . dm - a DMSwarm
525d3a51819SDave May  . fieldname - the textual name to identify this field
526d3a51819SDave May  . blocksize - the number of each data type
527d3a51819SDave May  . type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG)
528d3a51819SDave May 
529d3a51819SDave May  Level: beginner
530d3a51819SDave May 
531d3a51819SDave May  Notes:
532d3a51819SDave May  The textual name for each registered field must be unique
533d3a51819SDave May 
534d3a51819SDave May  . seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
535d3a51819SDave May 
536d3a51819SDave May @*/
537dcf43ee8SDave May #undef __FUNCT__
538b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterPetscDatatypeField"
5395f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
540b62e03f8SDave May {
5412eac95f8SDave May   PetscErrorCode ierr;
542b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
543b62e03f8SDave May   size_t size;
544b62e03f8SDave May 
5455f50eb2eSDave May   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
5465f50eb2eSDave May   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
5475f50eb2eSDave May 
5485f50eb2eSDave May   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5495f50eb2eSDave May   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5505f50eb2eSDave May   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5515f50eb2eSDave May   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5525f50eb2eSDave May   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
553b62e03f8SDave May 
5542ddcf43eSMatthew G. Knepley   ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr);
555b62e03f8SDave May 
556b62e03f8SDave May   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
55752c3ed93SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
55852c3ed93SDave May   {
55952c3ed93SDave May     DataField gfield;
56052c3ed93SDave May 
56152c3ed93SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
56252c3ed93SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
56352c3ed93SDave May   }
564b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
565b62e03f8SDave May 
566b62e03f8SDave May   PetscFunctionReturn(0);
567b62e03f8SDave May }
568b62e03f8SDave May 
569d3a51819SDave May /*@C
570d3a51819SDave May 
571d3a51819SDave May  DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm
572d3a51819SDave May 
573d3a51819SDave May  Collective on DM
574d3a51819SDave May 
575d3a51819SDave May  Input parameters:
576d3a51819SDave May  . dm - a DMSwarm
577d3a51819SDave May  . fieldname - the textual name to identify this field
578d3a51819SDave May  . size - the size in bytes of the user struct of each data type
579d3a51819SDave May 
580d3a51819SDave May  Level: beginner
581d3a51819SDave May 
582d3a51819SDave May  Notes:
583d3a51819SDave May  The textual name for each registered field must be unique
584d3a51819SDave May 
585d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField()
586d3a51819SDave May 
587d3a51819SDave May @*/
588b62e03f8SDave May #undef __FUNCT__
589b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterUserStructField"
5905f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
591b62e03f8SDave May {
5922eac95f8SDave May   PetscErrorCode ierr;
593b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
594b62e03f8SDave May 
5952eac95f8SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
596b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
597b62e03f8SDave May 
598b62e03f8SDave May   PetscFunctionReturn(0);
599b62e03f8SDave May }
600b62e03f8SDave May 
601d3a51819SDave May /*@C
602d3a51819SDave May 
603d3a51819SDave May  DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm
604d3a51819SDave May 
605d3a51819SDave May  Collective on DM
606d3a51819SDave May 
607d3a51819SDave May  Input parameters:
608d3a51819SDave May  . dm - a DMSwarm
609d3a51819SDave May  . fieldname - the textual name to identify this field
610d3a51819SDave May  . size - the size in bytes of the user data type
611d3a51819SDave May  . blocksize - the number of each data type
612d3a51819SDave May 
613d3a51819SDave May  Level: beginner
614d3a51819SDave May 
615d3a51819SDave May  Notes:
616d3a51819SDave May  The textual name for each registered field must be unique
617d3a51819SDave May 
618d3a51819SDave May  . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
619d3a51819SDave May 
620d3a51819SDave May @*/
621b62e03f8SDave May #undef __FUNCT__
622b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterUserDatatypeField"
623320740a0SDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize)
624b62e03f8SDave May {
625b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
6266845f8f5SDave May   PetscErrorCode ierr;
627b62e03f8SDave May 
628320740a0SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
629320740a0SDave May   {
630320740a0SDave May     DataField gfield;
631320740a0SDave May 
632320740a0SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
633320740a0SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
634320740a0SDave May   }
635b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
636b62e03f8SDave May 
637b62e03f8SDave May   PetscFunctionReturn(0);
638b62e03f8SDave May }
639b62e03f8SDave May 
640d3a51819SDave May /*@C
641d3a51819SDave May 
642d3a51819SDave May  DMSwarmGetField - Get 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 DMSwarmRestoreField()
659d3a51819SDave May 
660d3a51819SDave May  . seealso: DMSwarmRestoreField()
661d3a51819SDave May 
662d3a51819SDave May @*/
663b62e03f8SDave May #undef __FUNCT__
664b62e03f8SDave May #define __FUNCT__ "DMSwarmGetField"
6655f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(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 
6713454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
6723454631fSDave May 
6732eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6746845f8f5SDave May   ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr);
6756845f8f5SDave May   ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr);
6761b1ea282SDave May   if (blocksize) {*blocksize = gfield->bs; }
677b5bcf523SDave May   if (type) { *type = gfield->petsc_type; }
678b62e03f8SDave May 
679b62e03f8SDave May   PetscFunctionReturn(0);
680b62e03f8SDave May }
681b62e03f8SDave May 
682d3a51819SDave May /*@C
683d3a51819SDave May 
684d3a51819SDave May  DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field
685d3a51819SDave May 
686d3a51819SDave May  Not collective
687d3a51819SDave May 
688d3a51819SDave May  Input parameters:
689d3a51819SDave May  . dm - a DMSwarm
690d3a51819SDave May  . fieldname - the textual name to identify this field
691d3a51819SDave May 
692d3a51819SDave May  Output parameters:
693d3a51819SDave May  . blocksize - the number of each data type
694d3a51819SDave May  . type - the data type
695d3a51819SDave May  . data - pointer to raw array
696d3a51819SDave May 
697d3a51819SDave May  Level: beginner
698d3a51819SDave May 
699d3a51819SDave May  Notes:
700d3a51819SDave May  The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField()
701d3a51819SDave May 
702d3a51819SDave May  . seealso: DMSwarmGetField()
703d3a51819SDave May 
704d3a51819SDave May @*/
705b62e03f8SDave May #undef __FUNCT__
706b62e03f8SDave May #define __FUNCT__ "DMSwarmRestoreField"
7075f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
708b62e03f8SDave May {
709b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
710b62e03f8SDave May   DataField gfield;
7112eac95f8SDave May   PetscErrorCode ierr;
712b62e03f8SDave May 
7132eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
7146845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
715b62e03f8SDave May   if (data) *data = NULL;
716b62e03f8SDave May 
717b62e03f8SDave May   PetscFunctionReturn(0);
718b62e03f8SDave May }
719b62e03f8SDave May 
720d3a51819SDave May /*@C
721d3a51819SDave May 
722d3a51819SDave May  DMSwarmAddPoint - Add space for one new point in the DMSwarm
723d3a51819SDave May 
724d3a51819SDave May  Not collective
725d3a51819SDave May 
726d3a51819SDave May  Input parameter:
727d3a51819SDave May  . dm - a DMSwarm
728d3a51819SDave May 
729d3a51819SDave May  Level: beginner
730d3a51819SDave May 
731d3a51819SDave May  Notes:
732d3a51819SDave May  The new point will have all fields initialized to zero
733d3a51819SDave May 
734d3a51819SDave May  . seealso: DMSwarmAddNPoints()
735d3a51819SDave May 
736d3a51819SDave May @*/
737cb1d1399SDave May #undef __FUNCT__
738cb1d1399SDave May #define __FUNCT__ "DMSwarmAddPoint"
739cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
740cb1d1399SDave May {
741cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
742cb1d1399SDave May   PetscErrorCode ierr;
743cb1d1399SDave May 
7443454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
745cb1d1399SDave May   ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr);
746cb1d1399SDave May   PetscFunctionReturn(0);
747cb1d1399SDave May }
748cb1d1399SDave May 
749d3a51819SDave May /*@C
750d3a51819SDave May 
751d3a51819SDave May  DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm
752d3a51819SDave May 
753d3a51819SDave May  Not collective
754d3a51819SDave May 
755d3a51819SDave May  Input parameters:
756d3a51819SDave May  . dm - a DMSwarm
757d3a51819SDave May  . npoints - the number of new points to add
758d3a51819SDave May 
759d3a51819SDave May  Level: beginner
760d3a51819SDave May 
761d3a51819SDave May  Notes:
762d3a51819SDave May  The new point will have all fields initialized to zero
763d3a51819SDave May 
764d3a51819SDave May  . seealso: DMSwarmAddPoint()
765d3a51819SDave May 
766d3a51819SDave May @*/
767cb1d1399SDave May #undef __FUNCT__
768cb1d1399SDave May #define __FUNCT__ "DMSwarmAddNPoints"
769cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
770cb1d1399SDave May {
771cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
772cb1d1399SDave May   PetscErrorCode ierr;
773cb1d1399SDave May   PetscInt nlocal;
774cb1d1399SDave May 
775cb1d1399SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
776cb1d1399SDave May   nlocal = nlocal + npoints;
777cb1d1399SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,-1);CHKERRQ(ierr);
778cb1d1399SDave May   PetscFunctionReturn(0);
779cb1d1399SDave May }
780cb1d1399SDave May 
781d3a51819SDave May /*@C
782d3a51819SDave May 
783d3a51819SDave May  DMSwarmRemovePoint - Remove the last point from the DMSwarm
784d3a51819SDave May 
785d3a51819SDave May  Not collective
786d3a51819SDave May 
787d3a51819SDave May  Input parameter:
788d3a51819SDave May  . dm - a DMSwarm
789d3a51819SDave May 
790d3a51819SDave May  Level: beginner
791d3a51819SDave May 
792d3a51819SDave May  . seealso: DMSwarmRemovePointAtIndex()
793d3a51819SDave May 
794d3a51819SDave May @*/
795cb1d1399SDave May #undef __FUNCT__
796cb1d1399SDave May #define __FUNCT__ "DMSwarmRemovePoint"
797cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
798cb1d1399SDave May {
799cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
800cb1d1399SDave May   PetscErrorCode ierr;
801cb1d1399SDave May 
802cb1d1399SDave May   ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
803cb1d1399SDave May   PetscFunctionReturn(0);
804cb1d1399SDave May }
805cb1d1399SDave May 
806d3a51819SDave May /*@C
807d3a51819SDave May 
808d3a51819SDave May  DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm
809d3a51819SDave May 
810d3a51819SDave May  Not collective
811d3a51819SDave May 
812d3a51819SDave May  Input parameters:
813d3a51819SDave May  . dm - a DMSwarm
814d3a51819SDave May  . idx - index of point to remove
815d3a51819SDave May 
816d3a51819SDave May  Level: beginner
817d3a51819SDave May 
818d3a51819SDave May  . seealso: DMSwarmRemovePoint()
819d3a51819SDave May 
820d3a51819SDave May @*/
821cb1d1399SDave May #undef __FUNCT__
822cb1d1399SDave May #define __FUNCT__ "DMSwarmRemovePointAtIndex"
823cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
824cb1d1399SDave May {
825cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
826cb1d1399SDave May   PetscErrorCode ierr;
827cb1d1399SDave May 
828cb1d1399SDave May   ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
829cb1d1399SDave May   PetscFunctionReturn(0);
830cb1d1399SDave May }
831b62e03f8SDave May 
8323454631fSDave May #undef __FUNCT__
833095059a4SDave May #define __FUNCT__ "DMSwarmMigrate_Basic"
834095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points)
8353454631fSDave May {
836dcf43ee8SDave May   PetscErrorCode ierr;
837dcf43ee8SDave May   ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr);
8383454631fSDave May   PetscFunctionReturn(0);
8393454631fSDave May }
8403454631fSDave May 
841f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_CellDMScatter(DM dm,PetscBool remove_sent_points);
842f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_CellDMExact(DM dm,PetscBool remove_sent_points);
843f0cdbbbaSDave May 
844d3a51819SDave May /*@C
845d3a51819SDave May 
846d3a51819SDave May  DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks
847d3a51819SDave May 
848d3a51819SDave May  Collective on DM
849d3a51819SDave May 
850d3a51819SDave May  Input parameters:
851d3a51819SDave May  . dm - the DMSwarm
852d3a51819SDave May  . remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank
853d3a51819SDave May 
854d3a51819SDave May  Notes:
855d3a51819SDave May  The DM wil be modified to accomodate received points.
856d3a51819SDave May  If remove_sent_points = PETSC_TRUE, send points will be removed from the DM
857d3a51819SDave May  Different styles of migration are supported. See DMSwarmSetMigrateType()
858d3a51819SDave May 
859d3a51819SDave May  Level: advanced
860d3a51819SDave May 
861d3a51819SDave May  . seealso: DMSwarmSetMigrateType()
862d3a51819SDave May 
863d3a51819SDave May @*/
8643454631fSDave May #undef __FUNCT__
865095059a4SDave May #define __FUNCT__ "DMSwarmMigrate"
866095059a4SDave May PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points)
8673454631fSDave May {
868f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8693454631fSDave May   PetscErrorCode ierr;
870f0cdbbbaSDave May 
871f0cdbbbaSDave May   switch (swarm->migrate_type) {
872f0cdbbbaSDave May 
873f0cdbbbaSDave May     case DMSWARM_MIGRATE_BASIC:
874095059a4SDave May       ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr);
875f0cdbbbaSDave May       break;
876f0cdbbbaSDave May 
877f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLNSCATTER:
878f0cdbbbaSDave May       ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr);
879f0cdbbbaSDave May       break;
880f0cdbbbaSDave May 
881f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLEXACT:
882f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented");
883f0cdbbbaSDave May       //ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr);
884f0cdbbbaSDave May       break;
885f0cdbbbaSDave May 
886f0cdbbbaSDave May     case DMSWARM_MIGRATE_USER:
887f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented");
888f0cdbbbaSDave May       //ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr);
889f0cdbbbaSDave May       break;
890f0cdbbbaSDave May 
891f0cdbbbaSDave May     default:
892f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown");
893f0cdbbbaSDave May       break;
894f0cdbbbaSDave May   }
8953454631fSDave May   PetscFunctionReturn(0);
8963454631fSDave May }
8973454631fSDave May 
898f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize);
899f0cdbbbaSDave May 
900d3a51819SDave May /*
901d3a51819SDave May  DMSwarmCollectViewCreate
902d3a51819SDave May 
903d3a51819SDave May  * Applies a collection method and gathers point neighbour points into dm
904d3a51819SDave May 
905d3a51819SDave May  Notes:
906d3a51819SDave May  - Users should call DMSwarmCollectViewDestroy() after
907d3a51819SDave May  they have finished computations associated with the collected points
908d3a51819SDave May */
909d3a51819SDave May 
910d3a51819SDave May /*@C
911d3a51819SDave May 
912d3a51819SDave May  DMSwarmCollectViewCreate - Applies a collection method and gathers points
913d3a51819SDave May  in neighbour MPI-ranks into the DMSwarm
914d3a51819SDave May 
915d3a51819SDave May  Collective on DM
916d3a51819SDave May 
917d3a51819SDave May  Input parameter:
918d3a51819SDave May  . dm - the DMSwarm
919d3a51819SDave May 
920d3a51819SDave May  Notes:
921d3a51819SDave May  Users should call DMSwarmCollectViewDestroy() after
922d3a51819SDave May  they have finished computations associated with the collected points
923d3a51819SDave May  Different collect methods are supported. See DMSwarmSetCollectType()
924d3a51819SDave May 
925d3a51819SDave May  Level: advanced
926d3a51819SDave May 
927d3a51819SDave May  . seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType()
928d3a51819SDave May 
929d3a51819SDave May @*/
9302712d1f2SDave May #undef __FUNCT__
931fe39f135SDave May #define __FUNCT__ "DMSwarmCollectViewCreate"
932fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm)
9332712d1f2SDave May {
9342712d1f2SDave May   PetscErrorCode ierr;
9352712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9362712d1f2SDave May   PetscInt ng;
9372712d1f2SDave May 
938480eef7bSDave May   if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active");
9392712d1f2SDave May 
940480eef7bSDave May   ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr);
941480eef7bSDave May   switch (swarm->collect_type) {
942f0cdbbbaSDave May 
943480eef7bSDave May     case DMSWARM_COLLECT_BASIC:
9442712d1f2SDave May       ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr);
945480eef7bSDave May       break;
946f0cdbbbaSDave May 
947480eef7bSDave May     case DMSWARM_COLLECT_DMDABOUNDINGBOX:
948f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented");
949fe39f135SDave May       //ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr);
950480eef7bSDave May       break;
951f0cdbbbaSDave May 
952480eef7bSDave May     case DMSWARM_COLLECT_GENERAL:
953f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented");
954fe39f135SDave May       //ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr);
955480eef7bSDave May       break;
956480eef7bSDave May 
957480eef7bSDave May     default:
958f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown");
959480eef7bSDave May       break;
960480eef7bSDave May   }
961480eef7bSDave May 
962480eef7bSDave May   swarm->collect_view_active = PETSC_TRUE;
963480eef7bSDave May   swarm->collect_view_reset_nlocal = ng;
9642712d1f2SDave May 
9652712d1f2SDave May   PetscFunctionReturn(0);
9662712d1f2SDave May }
9672712d1f2SDave May 
968d3a51819SDave May /*@C
969d3a51819SDave May 
970d3a51819SDave May  DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate()
971d3a51819SDave May 
972d3a51819SDave May  Collective on DM
973d3a51819SDave May 
974d3a51819SDave May  Input parameters:
975d3a51819SDave May  . dm - the DMSwarm
976d3a51819SDave May 
977d3a51819SDave May  Notes:
978d3a51819SDave May  Users should call DMSwarmCollectViewCreate() before this function is called.
979d3a51819SDave May 
980d3a51819SDave May  Level: advanced
981d3a51819SDave May 
982d3a51819SDave May  . seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType()
983d3a51819SDave May 
984d3a51819SDave May @*/
9852712d1f2SDave May #undef __FUNCT__
986fe39f135SDave May #define __FUNCT__ "DMSwarmCollectViewDestroy"
987fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm)
9882712d1f2SDave May {
9892712d1f2SDave May   PetscErrorCode ierr;
9902712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9912712d1f2SDave May 
992480eef7bSDave May   if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active");
993480eef7bSDave May   ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr);
994480eef7bSDave May   swarm->collect_view_active = PETSC_FALSE;
9952712d1f2SDave May 
9962712d1f2SDave May   PetscFunctionReturn(0);
9972712d1f2SDave May }
9983454631fSDave May 
9993454631fSDave May #undef __FUNCT__
1000f0cdbbbaSDave May #define __FUNCT__ "DMSwarmSetUpPIC"
1001f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm)
1002f0cdbbbaSDave May {
1003f0cdbbbaSDave May   PetscInt dim;
1004f0cdbbbaSDave May   PetscErrorCode ierr;
1005f0cdbbbaSDave May 
1006f0cdbbbaSDave May   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
1007f0cdbbbaSDave May   if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
1008f0cdbbbaSDave May   if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
1009f0cdbbbaSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr);
1010f0cdbbbaSDave May   PetscFunctionReturn(0);
1011f0cdbbbaSDave May }
1012f0cdbbbaSDave May 
1013d3a51819SDave May /*@C
1014d3a51819SDave May 
1015d3a51819SDave May  DMSwarmSetType - Set particular flavor of DMSwarm
1016d3a51819SDave May 
1017d3a51819SDave May  Collective on DM
1018d3a51819SDave May 
1019d3a51819SDave May  Input parameters:
1020d3a51819SDave May  . dm - the DMSwarm
1021d3a51819SDave May  . stype - the DMSwarm type (e.g. DMSWARM_PIC)
1022d3a51819SDave May 
1023d3a51819SDave May  Level: advanced
1024d3a51819SDave May 
1025d3a51819SDave May  . seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType()
1026d3a51819SDave May 
1027d3a51819SDave May @*/
1028cac75b86SDave May #undef __FUNCT__
1029f0cdbbbaSDave May #define __FUNCT__ "DMSwarmSetType"
1030f0cdbbbaSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype)
1031f0cdbbbaSDave May {
1032f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1033f0cdbbbaSDave May   PetscErrorCode ierr;
1034f0cdbbbaSDave May 
1035f0cdbbbaSDave May   swarm->swarm_type = stype;
1036f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
1037f0cdbbbaSDave May     ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr);
1038f0cdbbbaSDave May   }
1039f0cdbbbaSDave May   PetscFunctionReturn(0);
1040f0cdbbbaSDave May }
1041f0cdbbbaSDave May 
1042f0cdbbbaSDave May #undef __FUNCT__
10433454631fSDave May #define __FUNCT__ "DMSetup_Swarm"
10443454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm)
10453454631fSDave May {
10463454631fSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
10473454631fSDave May   PetscErrorCode ierr;
10483454631fSDave May   PetscMPIInt rank;
10493454631fSDave May   PetscInt p,npoints,*rankval;
10503454631fSDave May 
10513454631fSDave May   if (swarm->issetup) PetscFunctionReturn(0);
10523454631fSDave May 
10533454631fSDave May   swarm->issetup = PETSC_TRUE;
10543454631fSDave May 
1055f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
1056f0cdbbbaSDave May     /* check dmcell exists */
1057f0cdbbbaSDave May     if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM");
1058f0cdbbbaSDave May 
1059f0cdbbbaSDave May     if (swarm->dmcell->ops->locatepointssubdomain) {
1060f0cdbbbaSDave May       /* check methods exists for exact ownership identificiation */
1061f0cdbbbaSDave May       PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");
1062f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT;
1063f0cdbbbaSDave May     } else {
1064f0cdbbbaSDave May       /* check methods exist for point location AND rank neighbor identification */
1065f0cdbbbaSDave May       if (swarm->dmcell->ops->locatepoints) {
1066f0cdbbbaSDave May         PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->LocatePoints\n");
1067f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined");
1068f0cdbbbaSDave May 
1069f0cdbbbaSDave May       if (swarm->dmcell->ops->getneighbors) {
1070f0cdbbbaSDave May         PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->GetNeigbors\n");
1071f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined");
1072f0cdbbbaSDave May 
1073f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER;
1074f0cdbbbaSDave May     }
1075f0cdbbbaSDave May   }
1076f0cdbbbaSDave May 
1077f0cdbbbaSDave May   ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr);
1078f0cdbbbaSDave May 
10793454631fSDave May   /* check some fields were registered */
10803454631fSDave May   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
10813454631fSDave May 
10823454631fSDave May   /* check local sizes were set */
10833454631fSDave May   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
10843454631fSDave May 
10853454631fSDave May   /* initialize values in pid and rank placeholders */
10863454631fSDave May   /* TODO: [pid - use MPI_Scan] */
10873454631fSDave May 
10883454631fSDave May   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
10893454631fSDave May   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
1090f0cdbbbaSDave May   ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10913454631fSDave May   for (p=0; p<npoints; p++) {
10923454631fSDave May     rankval[p] = (PetscInt)rank;
10933454631fSDave May   }
1094f0cdbbbaSDave May   ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10953454631fSDave May 
10963454631fSDave May   PetscFunctionReturn(0);
10973454631fSDave May }
10983454631fSDave May 
1099b62e03f8SDave May #undef __FUNCT__
110057795646SDave May #define __FUNCT__ "DMDestroy_Swarm"
110157795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm)
110257795646SDave May {
110357795646SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
110457795646SDave May   PetscErrorCode ierr;
110557795646SDave May 
110657795646SDave May   PetscFunctionBegin;
11076845f8f5SDave May   ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr);
110857795646SDave May   ierr = PetscFree(swarm);CHKERRQ(ierr);
110957795646SDave May   PetscFunctionReturn(0);
111057795646SDave May }
111157795646SDave May 
111257795646SDave May #undef __FUNCT__
1113a9ee3421SMatthew G. Knepley #define __FUNCT__ "DMSwarmView_Draw"
1114a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer)
1115a9ee3421SMatthew G. Knepley {
1116a9ee3421SMatthew G. Knepley   DM             cdm;
1117a9ee3421SMatthew G. Knepley   PetscDraw      draw;
1118a9ee3421SMatthew G. Knepley   PetscReal     *coords, oldPause;
1119a9ee3421SMatthew G. Knepley   PetscInt       Np, p, bs;
1120a9ee3421SMatthew G. Knepley   PetscErrorCode ierr;
1121a9ee3421SMatthew G. Knepley 
1122a9ee3421SMatthew G. Knepley   PetscFunctionBegin;
1123a9ee3421SMatthew G. Knepley   ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr);
1124a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr);
1125a9ee3421SMatthew G. Knepley   ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr);
1126a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr);
1127a9ee3421SMatthew G. Knepley   ierr = DMView(cdm, viewer);CHKERRQ(ierr);
1128a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr);
1129a9ee3421SMatthew G. Knepley 
1130a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr);
1131a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1132a9ee3421SMatthew G. Knepley   for (p = 0; p < Np; ++p) {
1133a9ee3421SMatthew G. Knepley     const PetscInt i = p*bs;
1134a9ee3421SMatthew G. Knepley 
1135a9ee3421SMatthew G. Knepley     ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], 0.01, 0.01, PETSC_DRAW_BLUE);CHKERRQ(ierr);
1136a9ee3421SMatthew G. Knepley   }
1137a9ee3421SMatthew G. Knepley   ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1138a9ee3421SMatthew G. Knepley   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
1139a9ee3421SMatthew G. Knepley   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
1140a9ee3421SMatthew G. Knepley   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1141a9ee3421SMatthew G. Knepley   PetscFunctionReturn(0);
1142a9ee3421SMatthew G. Knepley }
1143a9ee3421SMatthew G. Knepley 
1144a9ee3421SMatthew G. Knepley #undef __FUNCT__
11455f50eb2eSDave May #define __FUNCT__ "DMView_Swarm"
11465f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
11475f50eb2eSDave May {
11485f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1149a9ee3421SMatthew G. Knepley   PetscBool      iascii,ibinary,ishdf5,isvtk,isdraw;
11505f50eb2eSDave May   PetscErrorCode ierr;
11515f50eb2eSDave May 
11525f50eb2eSDave May   PetscFunctionBegin;
11535f50eb2eSDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
11545f50eb2eSDave May   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
11555f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
11565f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
11575f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
11585f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1159a9ee3421SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW,  &isdraw);CHKERRQ(ierr);
11605f50eb2eSDave May   if (iascii) {
11616845f8f5SDave May     ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
11625f50eb2eSDave May   } else if (ibinary) {
1163a9ee3421SMatthew G. Knepley     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support");
11645f50eb2eSDave May   } else if (ishdf5) {
11655f50eb2eSDave May #if defined(PETSC_HAVE_HDF5)
11665f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
11675f50eb2eSDave May #else
11685f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
11695f50eb2eSDave May #endif
11705f50eb2eSDave May   } else if (isvtk) {
11715f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
1172a9ee3421SMatthew G. Knepley   } else if (isdraw) {
1173a9ee3421SMatthew G. Knepley     ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr);
11745f50eb2eSDave May   }
11755f50eb2eSDave May   PetscFunctionReturn(0);
11765f50eb2eSDave May }
11775f50eb2eSDave May 
1178d3a51819SDave May /*MC
1179d3a51819SDave May 
1180d3a51819SDave May  DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type.
1181d3a51819SDave May  This implementation was designed for particle-in-cell type methods in which the underlying
1182d3a51819SDave May  data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type.
1183d3a51819SDave May 
1184d3a51819SDave May  User data can be represented by DMSwarm through a registring "fields".
1185d3a51819SDave May  To register a field, the user must provide:
1186d3a51819SDave May  (a) a unique name
1187d3a51819SDave May  (b) the data type (or size in bytes)
1188d3a51819SDave May  (c) the block size of the data
1189d3a51819SDave May 
1190d3a51819SDave May  For example, suppose the application requires a unique id, energy, momentum and density to be stored
1191d3a51819SDave May  on a set of of particles. Then the following application could be used
1192d3a51819SDave May 
1193d3a51819SDave May  DMSwarmInitializeFieldRegister(dm)
1194d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG);
1195d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL);
1196d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL);
1197d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT);
1198d3a51819SDave May  DMSwarmFinalizeFieldRegister(dm)
1199d3a51819SDave May 
1200d3a51819SDave May  The fields represented by DMSwarm are dynamic and can be re-sized at any time.
1201d3a51819SDave May  The only restriction imposed by DMSwarm is that all fields contain the same number of points
1202d3a51819SDave May 
1203d3a51819SDave May  To support particle methods, "migration" techniques are provided. These methods migrate data
1204d3a51819SDave May  between MPI-ranks.
1205d3a51819SDave May 
1206d3a51819SDave May  DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector().
1207d3a51819SDave May  As a DMSwarm may internally define and store values of different data types,
1208d3a51819SDave May  before calling DMCreate{Global/Local}Vector() the user must inform DMSwarm which
1209d3a51819SDave May  fields should be used to define a Vec object via
1210d3a51819SDave May    DMSwarmVectorDefineField()
1211d3a51819SDave May  The specified field can can changed be changed at any time - thereby permitting vectors
1212d3a51819SDave May  compatable with different fields to be created.
1213d3a51819SDave May 
1214d3a51819SDave May  A dual representation of fields in the DMSwarm and a Vec object are permitted via
1215d3a51819SDave May    DMSwarmCreateGlobalVectorFromField()
1216d3a51819SDave May  Here the data defining the field in the DMSwarm is shared with a Vec.
1217d3a51819SDave May  This is inherently unsafe if you alter the size of the field at any time between
1218d3a51819SDave May  calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField().
1219cc651181SDave May  If the local size of the DMSwarm does not match the localsize of the global vector
1220cc651181SDave May  when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown.
1221d3a51819SDave May 
1222d3a51819SDave May  Level: beginner
1223d3a51819SDave May 
1224d3a51819SDave May  .seealso: DMType, DMCreate(), DMSetType()
1225d3a51819SDave May 
1226d3a51819SDave May M*/
12275f50eb2eSDave May #undef __FUNCT__
122857795646SDave May #define __FUNCT__ "DMCreate_Swarm"
122957795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
123057795646SDave May {
123157795646SDave May   DM_Swarm      *swarm;
123257795646SDave May   PetscErrorCode ierr;
123357795646SDave May 
123457795646SDave May   PetscFunctionBegin;
123557795646SDave May   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
123657795646SDave May   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
1237f0cdbbbaSDave May   dm->data = swarm;
123857795646SDave May 
12396845f8f5SDave May   ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr);
1240f0cdbbbaSDave May   ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr);
1241f0cdbbbaSDave May 
1242b5bcf523SDave May   swarm->vec_field_set = PETSC_FALSE;
12433454631fSDave May   swarm->issetup = PETSC_FALSE;
1244480eef7bSDave May   swarm->swarm_type = DMSWARM_BASIC;
1245480eef7bSDave May   swarm->migrate_type = DMSWARM_MIGRATE_BASIC;
1246480eef7bSDave May   swarm->collect_type = DMSWARM_COLLECT_BASIC;
124740c453e9SDave May   swarm->migrate_error_on_missing_point = PETSC_FALSE;
1248b62e03f8SDave May 
1249f0cdbbbaSDave May   swarm->dmcell = NULL;
1250f0cdbbbaSDave May   swarm->collect_view_active = PETSC_FALSE;
1251f0cdbbbaSDave May   swarm->collect_view_reset_nlocal = -1;
125257795646SDave May 
1253f0cdbbbaSDave May   dm->dim  = 0;
12545f50eb2eSDave May   dm->ops->view                            = DMView_Swarm;
125557795646SDave May   dm->ops->load                            = NULL;
125657795646SDave May   dm->ops->setfromoptions                  = NULL;
125757795646SDave May   dm->ops->clone                           = NULL;
12583454631fSDave May   dm->ops->setup                           = DMSetup_Swarm;
125957795646SDave May   dm->ops->createdefaultsection            = NULL;
126057795646SDave May   dm->ops->createdefaultconstraints        = NULL;
1261b5bcf523SDave May   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
1262b5bcf523SDave May   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
126357795646SDave May   dm->ops->getlocaltoglobalmapping         = NULL;
126457795646SDave May   dm->ops->createfieldis                   = NULL;
126557795646SDave May   dm->ops->createcoordinatedm              = NULL;
126657795646SDave May   dm->ops->getcoloring                     = NULL;
126757795646SDave May   dm->ops->creatematrix                    = NULL;
126857795646SDave May   dm->ops->createinterpolation             = NULL;
126957795646SDave May   dm->ops->getaggregates                   = NULL;
127057795646SDave May   dm->ops->getinjection                    = NULL;
127157795646SDave May   dm->ops->refine                          = NULL;
127257795646SDave May   dm->ops->coarsen                         = NULL;
127357795646SDave May   dm->ops->refinehierarchy                 = NULL;
127457795646SDave May   dm->ops->coarsenhierarchy                = NULL;
127557795646SDave May   dm->ops->globaltolocalbegin              = NULL;
127657795646SDave May   dm->ops->globaltolocalend                = NULL;
127757795646SDave May   dm->ops->localtoglobalbegin              = NULL;
127857795646SDave May   dm->ops->localtoglobalend                = NULL;
127957795646SDave May   dm->ops->destroy                         = DMDestroy_Swarm;
128057795646SDave May   dm->ops->createsubdm                     = NULL;
128157795646SDave May   dm->ops->getdimpoints                    = NULL;
128257795646SDave May   dm->ops->locatepoints                    = NULL;
128357795646SDave May 
128457795646SDave May   PetscFunctionReturn(0);
128557795646SDave May }
1286