xref: /petsc/src/dm/impls/swarm/swarm.c (revision 521f74f943dc34ae95e235ce2ca1c57681f333aa)
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 
14d3a51819SDave May /*@C
15dcf43ee8SDave May 
16d3a51819SDave May   DMSwarmVectorDefineField - Sets the field from which to define a Vec object
1757795646SDave May 
18d3a51819SDave May   Collective on DM
1957795646SDave May 
20d3a51819SDave May   Input parameters:
21d3a51819SDave May . dm - a DMSwarm
22d3a51819SDave May . fieldname - The textual name given to a registered field
2357795646SDave May 
24d3a51819SDave May   Level: beginner
2557795646SDave May 
26d3a51819SDave May   Notes:
27d3a51819SDave May   The field with name fieldname must be defined as having a data type of PetscScalar
28d3a51819SDave May   This function must be called prior to calling DMCreateLocalVector(), DMCreateGlobalVector().
29d3a51819SDave May   Mutiple calls to DMSwarmVectorDefineField() are permitted.
3057795646SDave May 
31d3a51819SDave May . seealso: DMSwarmRegisterPetscDatatypeField()
3257795646SDave May 
33d3a51819SDave May @*/
3457795646SDave May #undef __FUNCT__
35b5bcf523SDave May #define __FUNCT__ "DMSwarmVectorDefineField"
36b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmVectorDefineField(DM dm,const char fieldname[])
37b5bcf523SDave May {
38b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
39b5bcf523SDave May   PetscErrorCode ierr;
40b5bcf523SDave May   PetscInt bs,n;
41b5bcf523SDave May   PetscScalar *array;
42b5bcf523SDave May   PetscDataType type;
43b5bcf523SDave May 
44a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
453454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
466845f8f5SDave May   ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr);
47b5bcf523SDave May   ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
48b5bcf523SDave May 
49b5bcf523SDave May   /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */
50b5bcf523SDave May   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL");
51*521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(swarm->vec_field_name,PETSC_MAX_PATH_LEN-1,"%s",fieldname);CHKERRQ(ierr);
52b5bcf523SDave May   swarm->vec_field_set = PETSC_TRUE;
531b1ea282SDave May   swarm->vec_field_bs = bs;
54b5bcf523SDave May   swarm->vec_field_nlocal = n;
55dcf43ee8SDave May   ierr = DMSwarmRestoreField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
56b5bcf523SDave May   PetscFunctionReturn(0);
57b5bcf523SDave May }
58b5bcf523SDave May 
59cc651181SDave May /* requires DMSwarmDefineFieldVector has been called */
60b5bcf523SDave May #undef __FUNCT__
61b5bcf523SDave May #define __FUNCT__ "DMCreateGlobalVector_Swarm"
62b5bcf523SDave May PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec)
63b5bcf523SDave May {
64b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
65b5bcf523SDave May   PetscErrorCode ierr;
66b5bcf523SDave May   Vec x;
67b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
68b5bcf523SDave May 
69a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
703454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
71b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
72cc651181SDave 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 */
73cc651181SDave May 
74*521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr);
75b5bcf523SDave May   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr);
76b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
771b1ea282SDave May   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr);
78b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
79b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
80b5bcf523SDave May   *vec = x;
81b5bcf523SDave May   PetscFunctionReturn(0);
82b5bcf523SDave May }
83b5bcf523SDave May 
84b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */
85b5bcf523SDave May #undef __FUNCT__
86b5bcf523SDave May #define __FUNCT__ "DMCreateLocalVector_Swarm"
87b5bcf523SDave May PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec)
88b5bcf523SDave May {
89b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
90b5bcf523SDave May   PetscErrorCode ierr;
91b5bcf523SDave May   Vec x;
92b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
93b5bcf523SDave May 
94a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
953454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
96b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
97cc651181SDave 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 */
98cc651181SDave May 
99*521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr);
100b5bcf523SDave May   ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr);
101b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
102071900c8SMatthew G. Knepley   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr);
103b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
104b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
105b5bcf523SDave May   *vec = x;
106b5bcf523SDave May   PetscFunctionReturn(0);
107b5bcf523SDave May }
108b5bcf523SDave May 
109fb1bcc12SMatthew G. Knepley #undef __FUNCT__
110fb1bcc12SMatthew G. Knepley #define __FUNCT__ "DMSwarmDestroyVectorFromField_Private"
111fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmDestroyVectorFromField_Private(DM dm, const char fieldname[], Vec *vec)
112fb1bcc12SMatthew G. Knepley {
113fb1bcc12SMatthew G. Knepley   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
114fb1bcc12SMatthew G. Knepley   DataField      gfield;
115fb1bcc12SMatthew G. Knepley   void         (*fptr)(void);
116fb1bcc12SMatthew G. Knepley   PetscInt       bs, nlocal;
117fb1bcc12SMatthew G. Knepley   char           name[PETSC_MAX_PATH_LEN];
118fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
119d3a51819SDave May 
120fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
121fb1bcc12SMatthew G. Knepley   ierr = VecGetLocalSize(*vec, &nlocal);CHKERRQ(ierr);
122fb1bcc12SMatthew G. Knepley   ierr = VecGetBlockSize(*vec, &bs);CHKERRQ(ierr);
123fb1bcc12SMatthew 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 */
124fb1bcc12SMatthew G. Knepley   ierr = DataBucketGetDataFieldByName(swarm->db, fieldname, &gfield);CHKERRQ(ierr);
125fb1bcc12SMatthew G. Knepley   /* check vector is an inplace array */
126*521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr);
127fb1bcc12SMatthew G. Knepley   ierr = PetscObjectQueryFunction((PetscObject) *vec, name, &fptr);CHKERRQ(ierr);
128fb1bcc12SMatthew G. Knepley   if (!fptr) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Vector being destroyed was not created from DMSwarm field(%s)", fieldname);
129fb1bcc12SMatthew G. Knepley   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
130fb1bcc12SMatthew G. Knepley   ierr = VecDestroy(vec);CHKERRQ(ierr);
131fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
132fb1bcc12SMatthew G. Knepley }
133fb1bcc12SMatthew G. Knepley 
134fb1bcc12SMatthew G. Knepley #undef __FUNCT__
135fb1bcc12SMatthew G. Knepley #define __FUNCT__ "DMSwarmCreateVectorFromField_Private"
136fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmCreateVectorFromField_Private(DM dm, const char fieldname[], MPI_Comm comm, Vec *vec)
137fb1bcc12SMatthew G. Knepley {
138fb1bcc12SMatthew G. Knepley   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
139fb1bcc12SMatthew G. Knepley   PetscDataType  type;
140fb1bcc12SMatthew G. Knepley   PetscScalar   *array;
141fb1bcc12SMatthew G. Knepley   PetscInt       bs, n;
142fb1bcc12SMatthew G. Knepley   char           name[PETSC_MAX_PATH_LEN];
143fb1bcc12SMatthew G. Knepley   PetscMPIInt    commsize;
144fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
145fb1bcc12SMatthew G. Knepley 
146fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
147fb1bcc12SMatthew G. Knepley   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
148fb1bcc12SMatthew G. Knepley   ierr = DataBucketGetSizes(swarm->db, &n, NULL, NULL);CHKERRQ(ierr);
149fb1bcc12SMatthew G. Knepley   ierr = DMSwarmGetField(dm, fieldname, &bs, &type, (void **) &array);CHKERRQ(ierr);
150fb1bcc12SMatthew G. Knepley   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Only valid for PETSC_REAL");
151fb1bcc12SMatthew G. Knepley 
152fb1bcc12SMatthew G. Knepley   ierr = MPI_Comm_size(comm, &commsize);CHKERRQ(ierr);
153fb1bcc12SMatthew G. Knepley   if (commsize == 1) {
154fb1bcc12SMatthew G. Knepley     ierr = VecCreateSeqWithArray(comm, bs, n*bs, array, vec);CHKERRQ(ierr);
155fb1bcc12SMatthew G. Knepley   } else {
156fb1bcc12SMatthew G. Knepley     ierr = VecCreateMPIWithArray(comm, bs, n*bs, PETSC_DETERMINE, array, vec);CHKERRQ(ierr);
157fb1bcc12SMatthew G. Knepley   }
158fb1bcc12SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarmSharedField_%s", fieldname);CHKERRQ(ierr);
159fb1bcc12SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) *vec, name);CHKERRQ(ierr);
160fb1bcc12SMatthew G. Knepley 
161fb1bcc12SMatthew G. Knepley   /* Set guard */
162fb1bcc12SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr);
163fb1bcc12SMatthew G. Knepley   ierr = PetscObjectComposeFunction((PetscObject) *vec, name, DMSwarmDestroyVectorFromField_Private);CHKERRQ(ierr);
164fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
165fb1bcc12SMatthew G. Knepley }
166fb1bcc12SMatthew G. Knepley 
167fb1bcc12SMatthew G. Knepley /*@C
168d3a51819SDave May   DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field
169d3a51819SDave May 
170d3a51819SDave May   Collective on DM
171d3a51819SDave May 
172d3a51819SDave May   Input parameters:
173d3a51819SDave May  . dm - a DMSwarm
174d3a51819SDave May  . fieldname - the textual name given to a registered field
175d3a51819SDave May 
176d3a51819SDave May  Output parameters:
177d3a51819SDave May  . vec - the vector
178d3a51819SDave May 
179d3a51819SDave May   Level: beginner
180d3a51819SDave May 
181d3a51819SDave May . seealso: DMSwarmRegisterPetscDatatypeField()
182d3a51819SDave May @*/
183b5bcf523SDave May #undef __FUNCT__
184b5bcf523SDave May #define __FUNCT__ "DMSwarmCreateGlobalVectorFromField"
185b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
186b5bcf523SDave May {
187fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PetscObjectComm((PetscObject) dm);
188b5bcf523SDave May   PetscErrorCode ierr;
189b5bcf523SDave May 
190fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
191fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
192b5bcf523SDave May   PetscFunctionReturn(0);
193b5bcf523SDave May }
194b5bcf523SDave May 
195d3a51819SDave May /*@C
196d3a51819SDave May   DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field
197d3a51819SDave May 
198d3a51819SDave May   Collective on DM
199d3a51819SDave May 
200d3a51819SDave May   Input parameters:
201d3a51819SDave May  . dm - a DMSwarm
202d3a51819SDave May  . fieldname - the textual name given to a registered field
203d3a51819SDave May 
204d3a51819SDave May   Output parameters:
205d3a51819SDave May  . vec - the vector
206d3a51819SDave May 
207d3a51819SDave May   Level: beginner
208d3a51819SDave May 
209d3a51819SDave May . seealso: DMSwarmRegisterPetscDatatypeField()
210d3a51819SDave May @*/
211b5bcf523SDave May #undef __FUNCT__
212b5bcf523SDave May #define __FUNCT__ "DMSwarmDestroyGlobalVectorFromField"
213b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
214b5bcf523SDave May {
215b5bcf523SDave May   PetscErrorCode ierr;
216cc651181SDave May 
217fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
218fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
219b5bcf523SDave May   PetscFunctionReturn(0);
220b5bcf523SDave May }
221b5bcf523SDave May 
222fb1bcc12SMatthew G. Knepley /*@C
223fb1bcc12SMatthew G. Knepley   DMSwarmCreateLocalVectorFromField - Creates a Vec object sharing the array associated with a given field
224fb1bcc12SMatthew G. Knepley 
225fb1bcc12SMatthew G. Knepley   Collective on DM
226fb1bcc12SMatthew G. Knepley 
227fb1bcc12SMatthew G. Knepley   Input parameters:
228fb1bcc12SMatthew G. Knepley  . dm - a DMSwarm
229fb1bcc12SMatthew G. Knepley  . fieldname - the textual name given to a registered field
230fb1bcc12SMatthew G. Knepley 
231fb1bcc12SMatthew G. Knepley  Output parameters:
232fb1bcc12SMatthew G. Knepley  . vec - the vector
233fb1bcc12SMatthew G. Knepley 
234fb1bcc12SMatthew G. Knepley   Level: beginner
235fb1bcc12SMatthew G. Knepley 
236fb1bcc12SMatthew G. Knepley . seealso: DMSwarmRegisterPetscDatatypeField()
237fb1bcc12SMatthew G. Knepley @*/
238bbe8250bSMatthew G. Knepley #undef __FUNCT__
239fb1bcc12SMatthew G. Knepley #define __FUNCT__ "DMSwarmCreateLocalVectorFromField"
240fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmCreateLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
241bbe8250bSMatthew G. Knepley {
242fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PETSC_COMM_SELF;
243bbe8250bSMatthew G. Knepley   PetscErrorCode ierr;
244bbe8250bSMatthew G. Knepley 
245fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
246fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
247fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
248bbe8250bSMatthew G. Knepley }
249fb1bcc12SMatthew G. Knepley 
250fb1bcc12SMatthew G. Knepley /*@C
251fb1bcc12SMatthew G. Knepley   DMSwarmDestroyLocalVectorFromField - Destroys the Vec object which share the array associated with a given field
252fb1bcc12SMatthew G. Knepley 
253fb1bcc12SMatthew G. Knepley   Collective on DM
254fb1bcc12SMatthew G. Knepley 
255fb1bcc12SMatthew G. Knepley   Input parameters:
256fb1bcc12SMatthew G. Knepley  . dm - a DMSwarm
257fb1bcc12SMatthew G. Knepley  . fieldname - the textual name given to a registered field
258fb1bcc12SMatthew G. Knepley 
259fb1bcc12SMatthew G. Knepley   Output parameters:
260fb1bcc12SMatthew G. Knepley  . vec - the vector
261fb1bcc12SMatthew G. Knepley 
262fb1bcc12SMatthew G. Knepley   Level: beginner
263fb1bcc12SMatthew G. Knepley 
264fb1bcc12SMatthew G. Knepley . seealso: DMSwarmRegisterPetscDatatypeField()
265fb1bcc12SMatthew G. Knepley @*/
266fb1bcc12SMatthew G. Knepley #undef __FUNCT__
267fb1bcc12SMatthew G. Knepley #define __FUNCT__ "DMSwarmDestroyLocalVectorFromField"
268fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmDestroyLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
269fb1bcc12SMatthew G. Knepley {
270fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
271fb1bcc12SMatthew G. Knepley 
272fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
273fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
274bbe8250bSMatthew G. Knepley   PetscFunctionReturn(0);
275bbe8250bSMatthew G. Knepley }
276bbe8250bSMatthew G. Knepley 
277b5bcf523SDave May /*
278b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec)
279b5bcf523SDave May {
280b5bcf523SDave May   PetscFunctionReturn(0);
281b5bcf523SDave May }
282b5bcf523SDave May 
283b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec)
284b5bcf523SDave May {
285b5bcf523SDave May   PetscFunctionReturn(0);
286b5bcf523SDave May }
287b5bcf523SDave May */
288b5bcf523SDave May 
289d3a51819SDave May /*@C
290d3a51819SDave May 
291d3a51819SDave May  DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm
292d3a51819SDave May 
293d3a51819SDave May  Collective on DM
294d3a51819SDave May 
295d3a51819SDave May  Input parameter:
296d3a51819SDave May  . dm - a DMSwarm
297d3a51819SDave May 
298d3a51819SDave May  Level: beginner
299d3a51819SDave May 
300d3a51819SDave May  Notes:
301d3a51819SDave May  After all fields have been registered, users should call DMSwarmFinalizeFieldRegister()
302d3a51819SDave May 
303d3a51819SDave May  . seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
304d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
305d3a51819SDave May @*/
306b5bcf523SDave May #undef __FUNCT__
3075f50eb2eSDave May #define __FUNCT__ "DMSwarmInitializeFieldRegister"
3085f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm)
3095f50eb2eSDave May {
3105f50eb2eSDave May   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
3113454631fSDave May   PetscErrorCode ierr;
3123454631fSDave May 
313*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
314cc651181SDave May   if (!swarm->field_registration_initialized) {
3155f50eb2eSDave May     swarm->field_registration_initialized = PETSC_TRUE;
316f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */
317f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */
318cc651181SDave May   }
3195f50eb2eSDave May   PetscFunctionReturn(0);
3205f50eb2eSDave May }
3215f50eb2eSDave May 
322d3a51819SDave May /*@C
323d3a51819SDave May 
324d3a51819SDave May  DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm
325d3a51819SDave May 
326d3a51819SDave May  Collective on DM
327d3a51819SDave May 
328d3a51819SDave May  Input parameter:
329d3a51819SDave May  . dm - a DMSwarm
330d3a51819SDave May 
331d3a51819SDave May  Level: beginner
332d3a51819SDave May 
333d3a51819SDave May  Notes:
334d3a51819SDave May  After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined
335d3a51819SDave May  on the DMSwarm
336d3a51819SDave May 
337d3a51819SDave May  . seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
338d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
339d3a51819SDave May @*/
3405f50eb2eSDave May #undef __FUNCT__
3415f50eb2eSDave May #define __FUNCT__ "DMSwarmFinalizeFieldRegister"
3425f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm)
3435f50eb2eSDave May {
3445f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3456845f8f5SDave May   PetscErrorCode ierr;
3466845f8f5SDave May 
347*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
348f0cdbbbaSDave May   if (!swarm->field_registration_finalized) {
3496845f8f5SDave May     ierr = DataBucketFinalize(swarm->db);CHKERRQ(ierr);
350f0cdbbbaSDave May   }
351f0cdbbbaSDave May   swarm->field_registration_finalized = PETSC_TRUE;
3525f50eb2eSDave May   PetscFunctionReturn(0);
3535f50eb2eSDave May }
3545f50eb2eSDave May 
355d3a51819SDave May /*@C
356d3a51819SDave May 
357d3a51819SDave May  DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm
358d3a51819SDave May 
359d3a51819SDave May  Not collective
360d3a51819SDave May 
361d3a51819SDave May  Input parameters:
362d3a51819SDave May  . dm - a DMSwarm
363d3a51819SDave May  . nlocal - the length of each registered field
364d3a51819SDave May  . buffer - the length of the buffer used to efficient dynamic re-sizing
365d3a51819SDave May 
366d3a51819SDave May  Level: beginner
367d3a51819SDave May 
368d3a51819SDave May  . seealso: DMSwarmGetLocalSize()
369d3a51819SDave May 
370d3a51819SDave May @*/
3715f50eb2eSDave May #undef __FUNCT__
3725f50eb2eSDave May #define __FUNCT__ "DMSwarmSetLocalSizes"
3735f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer)
3745f50eb2eSDave May {
3755f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3766845f8f5SDave May   PetscErrorCode ierr;
3775f50eb2eSDave May 
378*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
3796845f8f5SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr);
3805f50eb2eSDave May   PetscFunctionReturn(0);
3815f50eb2eSDave May }
3825f50eb2eSDave May 
383d3a51819SDave May /*@C
384d3a51819SDave May 
385d3a51819SDave May  DMSwarmSetCellDM - Attachs a DM to a DMSwarm
386d3a51819SDave May 
387d3a51819SDave May  Collective on DM
388d3a51819SDave May 
389d3a51819SDave May  Input parameters:
390d3a51819SDave May  . dm - a DMSwarm
391d3a51819SDave May  . dmcell - the DM to attach to the DMSwarm
392d3a51819SDave May 
393d3a51819SDave May  Level: beginner
394d3a51819SDave May 
395d3a51819SDave May  Notes:
396d3a51819SDave May  The attached DM (dmcell) will be queried for pointlocation and
397d3a51819SDave May  neighbor MPI-rank information if DMSwarmMigrate() is called
398d3a51819SDave May 
399d3a51819SDave May .seealso: DMSwarmGetCellDM(), DMSwarmMigrate()
400d3a51819SDave May @*/
4015f50eb2eSDave May #undef __FUNCT__
402b16650c8SDave May #define __FUNCT__ "DMSwarmSetCellDM"
403b16650c8SDave May PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell)
404b16650c8SDave May {
405b16650c8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
406*521f74f9SMatthew G. Knepley 
407*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
408b16650c8SDave May   swarm->dmcell = dmcell;
409b16650c8SDave May   PetscFunctionReturn(0);
410b16650c8SDave May }
411b16650c8SDave May 
412d3a51819SDave May /*@C
413d3a51819SDave May 
414d3a51819SDave May  DMSwarmGetCellDM - Fetches the attached cell DM
415d3a51819SDave May 
416d3a51819SDave May  Collective on DM
417d3a51819SDave May 
418d3a51819SDave May  Input parameter:
419d3a51819SDave May  . dm - a DMSwarm
420d3a51819SDave May 
421d3a51819SDave May  Output parameter:
422d3a51819SDave May  . dmcell - the DM which was attached to the DMSwarm
423d3a51819SDave May 
424d3a51819SDave May  Level: beginner
425d3a51819SDave May 
426d3a51819SDave May  Notes:
427d3a51819SDave May  The attached DM (dmcell) will be queried for pointlocation and
428d3a51819SDave May  neighbor MPI-rank information if DMSwarmMigrate() is called
429d3a51819SDave May 
430d3a51819SDave May .seealso: DMSwarmSetCellDM()
431d3a51819SDave May @*/
432b16650c8SDave May #undef __FUNCT__
433fe39f135SDave May #define __FUNCT__ "DMSwarmGetCellDM"
434fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell)
435fe39f135SDave May {
436fe39f135SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
437*521f74f9SMatthew G. Knepley 
438*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
439fe39f135SDave May   *dmcell = swarm->dmcell;
440fe39f135SDave May   PetscFunctionReturn(0);
441fe39f135SDave May }
442fe39f135SDave May 
443d3a51819SDave May /*@C
444d3a51819SDave May 
445d3a51819SDave May  DMSwarmGetLocalSize - Retrives the local length of fields registered
446d3a51819SDave May 
447d3a51819SDave May  Not collective
448d3a51819SDave May 
449d3a51819SDave May  Input parameter:
450d3a51819SDave May  . dm - a DMSwarm
451d3a51819SDave May 
452d3a51819SDave May  Output parameter:
453d3a51819SDave May  . nlocal - the length of each registered field
454d3a51819SDave May 
455d3a51819SDave May  Level: beginner
456d3a51819SDave May 
457d3a51819SDave May .seealso: DMSwarmSetLocalSizes()
458d3a51819SDave May @*/
459fe39f135SDave May #undef __FUNCT__
460dcf43ee8SDave May #define __FUNCT__ "DMSwarmGetLocalSize"
461dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal)
462dcf43ee8SDave May {
463dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
464dcf43ee8SDave May   PetscErrorCode ierr;
465dcf43ee8SDave May 
466*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
467*521f74f9SMatthew G. Knepley   if (nlocal) {ierr = DataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);}
468dcf43ee8SDave May   PetscFunctionReturn(0);
469dcf43ee8SDave May }
470dcf43ee8SDave May 
471d3a51819SDave May /*@C
472d3a51819SDave May 
473d3a51819SDave May  DMSwarmGetSize - Retrives the total length of fields registered
474d3a51819SDave May 
475d3a51819SDave May  Collective on DM
476d3a51819SDave May 
477d3a51819SDave May  Input parameter:
478d3a51819SDave May  . dm - a DMSwarm
479d3a51819SDave May 
480d3a51819SDave May  Output parameter:
481d3a51819SDave May  . n - the total length of each registered field
482d3a51819SDave May 
483d3a51819SDave May  Level: beginner
484d3a51819SDave May 
485d3a51819SDave May  Note:
486d3a51819SDave May  This calls MPI_Allreduce upon each call (inefficient but safe)
487d3a51819SDave May 
488d3a51819SDave May .seealso: DMSwarmGetLocalSize()
489d3a51819SDave May @*/
490dcf43ee8SDave May #undef __FUNCT__
491dcf43ee8SDave May #define __FUNCT__ "DMSwarmGetSize"
492dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n)
493dcf43ee8SDave May {
494dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
495dcf43ee8SDave May   PetscErrorCode ierr;
496dcf43ee8SDave May   PetscInt nlocal,ng;
497dcf43ee8SDave May 
498*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
499dcf43ee8SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
500dcf43ee8SDave May   ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
501dcf43ee8SDave May   if (n) { *n = ng; }
502dcf43ee8SDave May   PetscFunctionReturn(0);
503dcf43ee8SDave May }
504dcf43ee8SDave May 
505d3a51819SDave May /*@C
506d3a51819SDave May 
507d3a51819SDave May  DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm
508d3a51819SDave May 
509d3a51819SDave May  Collective on DM
510d3a51819SDave May 
511d3a51819SDave May  Input parameters:
512d3a51819SDave May  . dm - a DMSwarm
513d3a51819SDave May  . fieldname - the textual name to identify this field
514d3a51819SDave May  . blocksize - the number of each data type
515d3a51819SDave May  . type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG)
516d3a51819SDave May 
517d3a51819SDave May  Level: beginner
518d3a51819SDave May 
519d3a51819SDave May  Notes:
520d3a51819SDave May  The textual name for each registered field must be unique
521d3a51819SDave May 
522d3a51819SDave May .seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
523d3a51819SDave May @*/
524dcf43ee8SDave May #undef __FUNCT__
525b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterPetscDatatypeField"
5265f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
527b62e03f8SDave May {
5282eac95f8SDave May   PetscErrorCode ierr;
529b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
530b62e03f8SDave May   size_t size;
531b62e03f8SDave May 
532*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
5335f50eb2eSDave May   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
5345f50eb2eSDave May   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
5355f50eb2eSDave May 
5365f50eb2eSDave May   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5375f50eb2eSDave May   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5385f50eb2eSDave May   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5395f50eb2eSDave May   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5405f50eb2eSDave May   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
541b62e03f8SDave May 
5422ddcf43eSMatthew G. Knepley   ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr);
543b62e03f8SDave May   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
54452c3ed93SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
54552c3ed93SDave May   {
54652c3ed93SDave May     DataField gfield;
54752c3ed93SDave May 
54852c3ed93SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
54952c3ed93SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
55052c3ed93SDave May   }
551b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
552b62e03f8SDave May   PetscFunctionReturn(0);
553b62e03f8SDave May }
554b62e03f8SDave May 
555d3a51819SDave May /*@C
556d3a51819SDave May 
557d3a51819SDave May  DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm
558d3a51819SDave May 
559d3a51819SDave May  Collective on DM
560d3a51819SDave May 
561d3a51819SDave May  Input parameters:
562d3a51819SDave May  . dm - a DMSwarm
563d3a51819SDave May  . fieldname - the textual name to identify this field
564d3a51819SDave May  . size - the size in bytes of the user struct of each data type
565d3a51819SDave May 
566d3a51819SDave May  Level: beginner
567d3a51819SDave May 
568d3a51819SDave May  Notes:
569d3a51819SDave May  The textual name for each registered field must be unique
570d3a51819SDave May 
571d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField()
572d3a51819SDave May @*/
573b62e03f8SDave May #undef __FUNCT__
574b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterUserStructField"
5755f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
576b62e03f8SDave May {
5772eac95f8SDave May   PetscErrorCode ierr;
578b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
579b62e03f8SDave May 
580*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
5812eac95f8SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
582b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
583b62e03f8SDave May   PetscFunctionReturn(0);
584b62e03f8SDave May }
585b62e03f8SDave May 
586d3a51819SDave May /*@C
587d3a51819SDave May 
588d3a51819SDave May  DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm
589d3a51819SDave May 
590d3a51819SDave May  Collective on DM
591d3a51819SDave May 
592d3a51819SDave May  Input parameters:
593d3a51819SDave May  . dm - a DMSwarm
594d3a51819SDave May  . fieldname - the textual name to identify this field
595d3a51819SDave May  . size - the size in bytes of the user data type
596d3a51819SDave May  . blocksize - the number of each data type
597d3a51819SDave May 
598d3a51819SDave May  Level: beginner
599d3a51819SDave May 
600d3a51819SDave May  Notes:
601d3a51819SDave May  The textual name for each registered field must be unique
602d3a51819SDave May 
603d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
604d3a51819SDave May @*/
605b62e03f8SDave May #undef __FUNCT__
606b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterUserDatatypeField"
607320740a0SDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize)
608b62e03f8SDave May {
609b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
6106845f8f5SDave May   PetscErrorCode ierr;
611b62e03f8SDave May 
612*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
613320740a0SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
614320740a0SDave May   {
615320740a0SDave May     DataField gfield;
616320740a0SDave May 
617320740a0SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
618320740a0SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
619320740a0SDave May   }
620b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
621b62e03f8SDave May   PetscFunctionReturn(0);
622b62e03f8SDave May }
623b62e03f8SDave May 
624d3a51819SDave May /*@C
625d3a51819SDave May 
626d3a51819SDave May  DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field
627d3a51819SDave May 
628d3a51819SDave May  Not collective
629d3a51819SDave May 
630d3a51819SDave May  Input parameters:
631d3a51819SDave May  . dm - a DMSwarm
632d3a51819SDave May  . fieldname - the textual name to identify this field
633d3a51819SDave May 
634d3a51819SDave May  Output parameters:
635d3a51819SDave May  . blocksize - the number of each data type
636d3a51819SDave May  . type - the data type
637d3a51819SDave May  . data - pointer to raw array
638d3a51819SDave May 
639d3a51819SDave May  Level: beginner
640d3a51819SDave May 
641d3a51819SDave May  Notes:
642d3a51819SDave May  The user must call DMSwarmRestoreField()
643d3a51819SDave May 
644d3a51819SDave May .seealso: DMSwarmRestoreField()
645d3a51819SDave May @*/
646b62e03f8SDave May #undef __FUNCT__
647b62e03f8SDave May #define __FUNCT__ "DMSwarmGetField"
6485f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
649b62e03f8SDave May {
650b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
651b62e03f8SDave May   DataField gfield;
6522eac95f8SDave May   PetscErrorCode ierr;
653b62e03f8SDave May 
654*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6553454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
6562eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6576845f8f5SDave May   ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr);
6586845f8f5SDave May   ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr);
6591b1ea282SDave May   if (blocksize) {*blocksize = gfield->bs; }
660b5bcf523SDave May   if (type) { *type = gfield->petsc_type; }
661b62e03f8SDave May   PetscFunctionReturn(0);
662b62e03f8SDave May }
663b62e03f8SDave May 
664d3a51819SDave May /*@C
665d3a51819SDave May 
666d3a51819SDave May  DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field
667d3a51819SDave May 
668d3a51819SDave May  Not collective
669d3a51819SDave May 
670d3a51819SDave May  Input parameters:
671d3a51819SDave May  . dm - a DMSwarm
672d3a51819SDave May  . fieldname - the textual name to identify this field
673d3a51819SDave May 
674d3a51819SDave May  Output parameters:
675d3a51819SDave May  . blocksize - the number of each data type
676d3a51819SDave May  . type - the data type
677d3a51819SDave May  . data - pointer to raw array
678d3a51819SDave May 
679d3a51819SDave May  Level: beginner
680d3a51819SDave May 
681d3a51819SDave May  Notes:
682d3a51819SDave May  The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField()
683d3a51819SDave May 
684d3a51819SDave May .seealso: DMSwarmGetField()
685d3a51819SDave May @*/
686b62e03f8SDave May #undef __FUNCT__
687b62e03f8SDave May #define __FUNCT__ "DMSwarmRestoreField"
6885f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
689b62e03f8SDave May {
690b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
691b62e03f8SDave May   DataField gfield;
6922eac95f8SDave May   PetscErrorCode ierr;
693b62e03f8SDave May 
694*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6952eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6966845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
697b62e03f8SDave May   if (data) *data = NULL;
698b62e03f8SDave May   PetscFunctionReturn(0);
699b62e03f8SDave May }
700b62e03f8SDave May 
701d3a51819SDave May /*@C
702d3a51819SDave May 
703d3a51819SDave May  DMSwarmAddPoint - Add space for one new point in the DMSwarm
704d3a51819SDave May 
705d3a51819SDave May  Not collective
706d3a51819SDave May 
707d3a51819SDave May  Input parameter:
708d3a51819SDave May  . dm - a DMSwarm
709d3a51819SDave May 
710d3a51819SDave May  Level: beginner
711d3a51819SDave May 
712d3a51819SDave May  Notes:
713d3a51819SDave May  The new point will have all fields initialized to zero
714d3a51819SDave May 
715d3a51819SDave May .seealso: DMSwarmAddNPoints()
716d3a51819SDave May @*/
717cb1d1399SDave May #undef __FUNCT__
718cb1d1399SDave May #define __FUNCT__ "DMSwarmAddPoint"
719cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
720cb1d1399SDave May {
721cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
722cb1d1399SDave May   PetscErrorCode ierr;
723cb1d1399SDave May 
724*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
7253454631fSDave May   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
726cb1d1399SDave May   ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr);
727cb1d1399SDave May   PetscFunctionReturn(0);
728cb1d1399SDave May }
729cb1d1399SDave May 
730d3a51819SDave May /*@C
731d3a51819SDave May 
732d3a51819SDave May  DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm
733d3a51819SDave May 
734d3a51819SDave May  Not collective
735d3a51819SDave May 
736d3a51819SDave May  Input parameters:
737d3a51819SDave May  . dm - a DMSwarm
738d3a51819SDave May  . npoints - the number of new points to add
739d3a51819SDave May 
740d3a51819SDave May  Level: beginner
741d3a51819SDave May 
742d3a51819SDave May  Notes:
743d3a51819SDave May  The new point will have all fields initialized to zero
744d3a51819SDave May 
745d3a51819SDave May .seealso: DMSwarmAddPoint()
746d3a51819SDave May @*/
747cb1d1399SDave May #undef __FUNCT__
748cb1d1399SDave May #define __FUNCT__ "DMSwarmAddNPoints"
749cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
750cb1d1399SDave May {
751cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
752cb1d1399SDave May   PetscErrorCode ierr;
753cb1d1399SDave May   PetscInt nlocal;
754cb1d1399SDave May 
755*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
756cb1d1399SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
757cb1d1399SDave May   nlocal = nlocal + npoints;
758cb1d1399SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,-1);CHKERRQ(ierr);
759cb1d1399SDave May   PetscFunctionReturn(0);
760cb1d1399SDave May }
761cb1d1399SDave May 
762d3a51819SDave May /*@C
763d3a51819SDave May 
764d3a51819SDave May  DMSwarmRemovePoint - Remove the last point from the DMSwarm
765d3a51819SDave May 
766d3a51819SDave May  Not collective
767d3a51819SDave May 
768d3a51819SDave May  Input parameter:
769d3a51819SDave May  . dm - a DMSwarm
770d3a51819SDave May 
771d3a51819SDave May  Level: beginner
772d3a51819SDave May 
773d3a51819SDave May .seealso: DMSwarmRemovePointAtIndex()
774d3a51819SDave May @*/
775cb1d1399SDave May #undef __FUNCT__
776cb1d1399SDave May #define __FUNCT__ "DMSwarmRemovePoint"
777cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
778cb1d1399SDave May {
779cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
780cb1d1399SDave May   PetscErrorCode ierr;
781cb1d1399SDave May 
782*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
783cb1d1399SDave May   ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
784cb1d1399SDave May   PetscFunctionReturn(0);
785cb1d1399SDave May }
786cb1d1399SDave May 
787d3a51819SDave May /*@C
788d3a51819SDave May  DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm
789d3a51819SDave May 
790d3a51819SDave May  Not collective
791d3a51819SDave May 
792d3a51819SDave May  Input parameters:
793d3a51819SDave May  . dm - a DMSwarm
794d3a51819SDave May  . idx - index of point to remove
795d3a51819SDave May 
796d3a51819SDave May  Level: beginner
797d3a51819SDave May 
798d3a51819SDave May .seealso: DMSwarmRemovePoint()
799d3a51819SDave May @*/
800cb1d1399SDave May #undef __FUNCT__
801cb1d1399SDave May #define __FUNCT__ "DMSwarmRemovePointAtIndex"
802cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
803cb1d1399SDave May {
804cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
805cb1d1399SDave May   PetscErrorCode ierr;
806cb1d1399SDave May 
807*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
808cb1d1399SDave May   ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
809cb1d1399SDave May   PetscFunctionReturn(0);
810cb1d1399SDave May }
811b62e03f8SDave May 
8123454631fSDave May #undef __FUNCT__
813095059a4SDave May #define __FUNCT__ "DMSwarmMigrate_Basic"
814095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points)
8153454631fSDave May {
816dcf43ee8SDave May   PetscErrorCode ierr;
817*521f74f9SMatthew G. Knepley 
818*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
819dcf43ee8SDave May   ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr);
8203454631fSDave May   PetscFunctionReturn(0);
8213454631fSDave May }
8223454631fSDave May 
823d3a51819SDave May /*@C
824d3a51819SDave May 
825d3a51819SDave May  DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks
826d3a51819SDave May 
827d3a51819SDave May  Collective on DM
828d3a51819SDave May 
829d3a51819SDave May  Input parameters:
830d3a51819SDave May  . dm - the DMSwarm
831d3a51819SDave May  . remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank
832d3a51819SDave May 
833d3a51819SDave May  Notes:
834d3a51819SDave May  The DM wil be modified to accomodate received points.
835d3a51819SDave May  If remove_sent_points = PETSC_TRUE, send points will be removed from the DM
836d3a51819SDave May  Different styles of migration are supported. See DMSwarmSetMigrateType()
837d3a51819SDave May 
838d3a51819SDave May  Level: advanced
839d3a51819SDave May 
840d3a51819SDave May .seealso: DMSwarmSetMigrateType()
841d3a51819SDave May @*/
8423454631fSDave May #undef __FUNCT__
843095059a4SDave May #define __FUNCT__ "DMSwarmMigrate"
844095059a4SDave May PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points)
8453454631fSDave May {
846f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8473454631fSDave May   PetscErrorCode ierr;
848f0cdbbbaSDave May 
849*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
850f0cdbbbaSDave May   switch (swarm->migrate_type) {
851f0cdbbbaSDave May     case DMSWARM_MIGRATE_BASIC:
852095059a4SDave May       ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr);
853f0cdbbbaSDave May       break;
854f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLNSCATTER:
855f0cdbbbaSDave May       ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr);
856f0cdbbbaSDave May       break;
857f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLEXACT:
858f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented");
859*521f74f9SMatthew G. Knepley       /*ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr);*/
860f0cdbbbaSDave May       break;
861f0cdbbbaSDave May     case DMSWARM_MIGRATE_USER:
862f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented");
863*521f74f9SMatthew G. Knepley       /*ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr);*/
864f0cdbbbaSDave May       break;
865f0cdbbbaSDave May     default:
866f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown");
867f0cdbbbaSDave May       break;
868f0cdbbbaSDave May   }
8693454631fSDave May   PetscFunctionReturn(0);
8703454631fSDave May }
8713454631fSDave May 
872f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize);
873f0cdbbbaSDave May 
874d3a51819SDave May /*
875d3a51819SDave May  DMSwarmCollectViewCreate
876d3a51819SDave May 
877d3a51819SDave May  * Applies a collection method and gathers point neighbour points into dm
878d3a51819SDave May 
879d3a51819SDave May  Notes:
880d3a51819SDave May  - Users should call DMSwarmCollectViewDestroy() after
881d3a51819SDave May  they have finished computations associated with the collected points
882d3a51819SDave May */
883d3a51819SDave May 
884d3a51819SDave May /*@C
885d3a51819SDave May 
886d3a51819SDave May  DMSwarmCollectViewCreate - Applies a collection method and gathers points
887d3a51819SDave May  in neighbour MPI-ranks into the DMSwarm
888d3a51819SDave May 
889d3a51819SDave May  Collective on DM
890d3a51819SDave May 
891d3a51819SDave May  Input parameter:
892d3a51819SDave May  . dm - the DMSwarm
893d3a51819SDave May 
894d3a51819SDave May  Notes:
895d3a51819SDave May  Users should call DMSwarmCollectViewDestroy() after
896d3a51819SDave May  they have finished computations associated with the collected points
897d3a51819SDave May  Different collect methods are supported. See DMSwarmSetCollectType()
898d3a51819SDave May 
899d3a51819SDave May  Level: advanced
900d3a51819SDave May 
901d3a51819SDave May .seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType()
902d3a51819SDave May @*/
9032712d1f2SDave May #undef __FUNCT__
904fe39f135SDave May #define __FUNCT__ "DMSwarmCollectViewCreate"
905fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm)
9062712d1f2SDave May {
9072712d1f2SDave May   PetscErrorCode ierr;
9082712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9092712d1f2SDave May   PetscInt ng;
9102712d1f2SDave May 
911*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
912480eef7bSDave May   if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active");
913480eef7bSDave May   ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr);
914480eef7bSDave May   switch (swarm->collect_type) {
915f0cdbbbaSDave May 
916480eef7bSDave May     case DMSWARM_COLLECT_BASIC:
9172712d1f2SDave May       ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr);
918480eef7bSDave May       break;
919480eef7bSDave May     case DMSWARM_COLLECT_DMDABOUNDINGBOX:
920f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented");
921*521f74f9SMatthew G. Knepley       /*ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr);*/
922480eef7bSDave May       break;
923480eef7bSDave May     case DMSWARM_COLLECT_GENERAL:
924f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented");
925*521f74f9SMatthew G. Knepley       /*ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr);*/
926480eef7bSDave May       break;
927480eef7bSDave May     default:
928f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown");
929480eef7bSDave May       break;
930480eef7bSDave May   }
931480eef7bSDave May   swarm->collect_view_active = PETSC_TRUE;
932480eef7bSDave May   swarm->collect_view_reset_nlocal = ng;
9332712d1f2SDave May   PetscFunctionReturn(0);
9342712d1f2SDave May }
9352712d1f2SDave May 
936d3a51819SDave May /*@C
937d3a51819SDave May 
938d3a51819SDave May  DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate()
939d3a51819SDave May 
940d3a51819SDave May  Collective on DM
941d3a51819SDave May 
942d3a51819SDave May  Input parameters:
943d3a51819SDave May  . dm - the DMSwarm
944d3a51819SDave May 
945d3a51819SDave May  Notes:
946d3a51819SDave May  Users should call DMSwarmCollectViewCreate() before this function is called.
947d3a51819SDave May 
948d3a51819SDave May  Level: advanced
949d3a51819SDave May 
950d3a51819SDave May .seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType()
951d3a51819SDave May @*/
9522712d1f2SDave May #undef __FUNCT__
953fe39f135SDave May #define __FUNCT__ "DMSwarmCollectViewDestroy"
954fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm)
9552712d1f2SDave May {
9562712d1f2SDave May   PetscErrorCode ierr;
9572712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9582712d1f2SDave May 
959*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
960480eef7bSDave May   if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active");
961480eef7bSDave May   ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr);
962480eef7bSDave May   swarm->collect_view_active = PETSC_FALSE;
9632712d1f2SDave May   PetscFunctionReturn(0);
9642712d1f2SDave May }
9653454631fSDave May 
9663454631fSDave May #undef __FUNCT__
967f0cdbbbaSDave May #define __FUNCT__ "DMSwarmSetUpPIC"
968f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm)
969f0cdbbbaSDave May {
970f0cdbbbaSDave May   PetscInt dim;
971f0cdbbbaSDave May   PetscErrorCode ierr;
972f0cdbbbaSDave May 
973*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
974f0cdbbbaSDave May   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
975f0cdbbbaSDave May   if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
976f0cdbbbaSDave May   if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
977f0cdbbbaSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr);
978f0cdbbbaSDave May   PetscFunctionReturn(0);
979f0cdbbbaSDave May }
980f0cdbbbaSDave May 
981d3a51819SDave May /*@C
982d3a51819SDave May 
983d3a51819SDave May  DMSwarmSetType - Set particular flavor of DMSwarm
984d3a51819SDave May 
985d3a51819SDave May  Collective on DM
986d3a51819SDave May 
987d3a51819SDave May  Input parameters:
988d3a51819SDave May . dm - the DMSwarm
989d3a51819SDave May . stype - the DMSwarm type (e.g. DMSWARM_PIC)
990d3a51819SDave May 
991d3a51819SDave May  Level: advanced
992d3a51819SDave May 
993d3a51819SDave May .seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType()
994d3a51819SDave May @*/
995cac75b86SDave May #undef __FUNCT__
996f0cdbbbaSDave May #define __FUNCT__ "DMSwarmSetType"
997f0cdbbbaSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype)
998f0cdbbbaSDave May {
999f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1000f0cdbbbaSDave May   PetscErrorCode ierr;
1001f0cdbbbaSDave May 
1002*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1003f0cdbbbaSDave May   swarm->swarm_type = stype;
1004f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
1005f0cdbbbaSDave May     ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr);
1006f0cdbbbaSDave May   }
1007f0cdbbbaSDave May   PetscFunctionReturn(0);
1008f0cdbbbaSDave May }
1009f0cdbbbaSDave May 
1010f0cdbbbaSDave May #undef __FUNCT__
10113454631fSDave May #define __FUNCT__ "DMSetup_Swarm"
10123454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm)
10133454631fSDave May {
10143454631fSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
10153454631fSDave May   PetscErrorCode ierr;
10163454631fSDave May   PetscMPIInt rank;
10173454631fSDave May   PetscInt p,npoints,*rankval;
10183454631fSDave May 
1019*521f74f9SMatthew G. Knepley   PetscFunctionBegin;
10203454631fSDave May   if (swarm->issetup) PetscFunctionReturn(0);
10213454631fSDave May 
10223454631fSDave May   swarm->issetup = PETSC_TRUE;
10233454631fSDave May 
1024f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
1025f0cdbbbaSDave May     /* check dmcell exists */
1026f0cdbbbaSDave May     if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM");
1027f0cdbbbaSDave May 
1028f0cdbbbaSDave May     if (swarm->dmcell->ops->locatepointssubdomain) {
1029f0cdbbbaSDave May       /* check methods exists for exact ownership identificiation */
1030*521f74f9SMatthew G. Knepley       ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");CHKERRQ(ierr);
1031f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT;
1032f0cdbbbaSDave May     } else {
1033f0cdbbbaSDave May       /* check methods exist for point location AND rank neighbor identification */
1034f0cdbbbaSDave May       if (swarm->dmcell->ops->locatepoints) {
1035*521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->LocatePoints\n");CHKERRQ(ierr);
1036f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined");
1037f0cdbbbaSDave May 
1038f0cdbbbaSDave May       if (swarm->dmcell->ops->getneighbors) {
1039*521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->GetNeigbors\n");CHKERRQ(ierr);
1040f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined");
1041f0cdbbbaSDave May 
1042f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER;
1043f0cdbbbaSDave May     }
1044f0cdbbbaSDave May   }
1045f0cdbbbaSDave May 
1046f0cdbbbaSDave May   ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr);
1047f0cdbbbaSDave May 
10483454631fSDave May   /* check some fields were registered */
10493454631fSDave May   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
10503454631fSDave May 
10513454631fSDave May   /* check local sizes were set */
10523454631fSDave May   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
10533454631fSDave May 
10543454631fSDave May   /* initialize values in pid and rank placeholders */
10553454631fSDave May   /* TODO: [pid - use MPI_Scan] */
10563454631fSDave May   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
10573454631fSDave May   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
1058f0cdbbbaSDave May   ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10593454631fSDave May   for (p=0; p<npoints; p++) {
10603454631fSDave May     rankval[p] = (PetscInt)rank;
10613454631fSDave May   }
1062f0cdbbbaSDave May   ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10633454631fSDave May   PetscFunctionReturn(0);
10643454631fSDave May }
10653454631fSDave May 
1066b62e03f8SDave May #undef __FUNCT__
106757795646SDave May #define __FUNCT__ "DMDestroy_Swarm"
106857795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm)
106957795646SDave May {
107057795646SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
107157795646SDave May   PetscErrorCode ierr;
107257795646SDave May 
107357795646SDave May   PetscFunctionBegin;
10746845f8f5SDave May   ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr);
107557795646SDave May   ierr = PetscFree(swarm);CHKERRQ(ierr);
107657795646SDave May   PetscFunctionReturn(0);
107757795646SDave May }
107857795646SDave May 
107957795646SDave May #undef __FUNCT__
1080a9ee3421SMatthew G. Knepley #define __FUNCT__ "DMSwarmView_Draw"
1081a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer)
1082a9ee3421SMatthew G. Knepley {
1083a9ee3421SMatthew G. Knepley   DM             cdm;
1084a9ee3421SMatthew G. Knepley   PetscDraw      draw;
1085a9ee3421SMatthew G. Knepley   PetscReal     *coords, oldPause;
1086a9ee3421SMatthew G. Knepley   PetscInt       Np, p, bs;
1087a9ee3421SMatthew G. Knepley   PetscErrorCode ierr;
1088a9ee3421SMatthew G. Knepley 
1089a9ee3421SMatthew G. Knepley   PetscFunctionBegin;
1090a9ee3421SMatthew G. Knepley   ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr);
1091a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr);
1092a9ee3421SMatthew G. Knepley   ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr);
1093a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr);
1094a9ee3421SMatthew G. Knepley   ierr = DMView(cdm, viewer);CHKERRQ(ierr);
1095a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr);
1096a9ee3421SMatthew G. Knepley 
1097a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr);
1098a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1099a9ee3421SMatthew G. Knepley   for (p = 0; p < Np; ++p) {
1100a9ee3421SMatthew G. Knepley     const PetscInt i = p*bs;
1101a9ee3421SMatthew G. Knepley 
1102a9ee3421SMatthew G. Knepley     ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], 0.01, 0.01, PETSC_DRAW_BLUE);CHKERRQ(ierr);
1103a9ee3421SMatthew G. Knepley   }
1104a9ee3421SMatthew G. Knepley   ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1105a9ee3421SMatthew G. Knepley   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
1106a9ee3421SMatthew G. Knepley   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
1107a9ee3421SMatthew G. Knepley   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1108a9ee3421SMatthew G. Knepley   PetscFunctionReturn(0);
1109a9ee3421SMatthew G. Knepley }
1110a9ee3421SMatthew G. Knepley 
1111a9ee3421SMatthew G. Knepley #undef __FUNCT__
11125f50eb2eSDave May #define __FUNCT__ "DMView_Swarm"
11135f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
11145f50eb2eSDave May {
11155f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1116a9ee3421SMatthew G. Knepley   PetscBool      iascii,ibinary,ishdf5,isvtk,isdraw;
11175f50eb2eSDave May   PetscErrorCode ierr;
11185f50eb2eSDave May 
11195f50eb2eSDave May   PetscFunctionBegin;
11205f50eb2eSDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
11215f50eb2eSDave May   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
11225f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
11235f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
11245f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
11255f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1126a9ee3421SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW,  &isdraw);CHKERRQ(ierr);
11275f50eb2eSDave May   if (iascii) {
11286845f8f5SDave May     ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
11295f50eb2eSDave May   } else if (ibinary) {
1130a9ee3421SMatthew G. Knepley     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support");
11315f50eb2eSDave May   } else if (ishdf5) {
11325f50eb2eSDave May #if defined(PETSC_HAVE_HDF5)
11335f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
11345f50eb2eSDave May #else
11355f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
11365f50eb2eSDave May #endif
11375f50eb2eSDave May   } else if (isvtk) {
11385f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
1139a9ee3421SMatthew G. Knepley   } else if (isdraw) {
1140a9ee3421SMatthew G. Knepley     ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr);
11415f50eb2eSDave May   }
11425f50eb2eSDave May   PetscFunctionReturn(0);
11435f50eb2eSDave May }
11445f50eb2eSDave May 
1145d3a51819SDave May /*MC
1146d3a51819SDave May 
1147d3a51819SDave May  DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type.
1148d3a51819SDave May  This implementation was designed for particle-in-cell type methods in which the underlying
1149d3a51819SDave May  data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type.
1150d3a51819SDave May 
1151d3a51819SDave May  User data can be represented by DMSwarm through a registring "fields".
1152d3a51819SDave May  To register a field, the user must provide:
1153d3a51819SDave May  (a) a unique name
1154d3a51819SDave May  (b) the data type (or size in bytes)
1155d3a51819SDave May  (c) the block size of the data
1156d3a51819SDave May 
1157d3a51819SDave May  For example, suppose the application requires a unique id, energy, momentum and density to be stored
1158d3a51819SDave May  on a set of of particles. Then the following application could be used
1159d3a51819SDave May 
1160d3a51819SDave May  DMSwarmInitializeFieldRegister(dm)
1161d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG);
1162d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL);
1163d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL);
1164d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT);
1165d3a51819SDave May  DMSwarmFinalizeFieldRegister(dm)
1166d3a51819SDave May 
1167d3a51819SDave May  The fields represented by DMSwarm are dynamic and can be re-sized at any time.
1168d3a51819SDave May  The only restriction imposed by DMSwarm is that all fields contain the same number of points
1169d3a51819SDave May 
1170d3a51819SDave May  To support particle methods, "migration" techniques are provided. These methods migrate data
1171d3a51819SDave May  between MPI-ranks.
1172d3a51819SDave May 
1173d3a51819SDave May  DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector().
1174d3a51819SDave May  As a DMSwarm may internally define and store values of different data types,
1175d3a51819SDave May  before calling DMCreate{Global/Local}Vector() the user must inform DMSwarm which
1176d3a51819SDave May  fields should be used to define a Vec object via
1177d3a51819SDave May    DMSwarmVectorDefineField()
1178d3a51819SDave May  The specified field can can changed be changed at any time - thereby permitting vectors
1179d3a51819SDave May  compatable with different fields to be created.
1180d3a51819SDave May 
1181d3a51819SDave May  A dual representation of fields in the DMSwarm and a Vec object are permitted via
1182d3a51819SDave May    DMSwarmCreateGlobalVectorFromField()
1183d3a51819SDave May  Here the data defining the field in the DMSwarm is shared with a Vec.
1184d3a51819SDave May  This is inherently unsafe if you alter the size of the field at any time between
1185d3a51819SDave May  calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField().
1186cc651181SDave May  If the local size of the DMSwarm does not match the localsize of the global vector
1187cc651181SDave May  when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown.
1188d3a51819SDave May 
1189d3a51819SDave May  Level: beginner
1190d3a51819SDave May 
1191d3a51819SDave May .seealso: DMType, DMCreate(), DMSetType()
1192d3a51819SDave May M*/
11935f50eb2eSDave May #undef __FUNCT__
119457795646SDave May #define __FUNCT__ "DMCreate_Swarm"
119557795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
119657795646SDave May {
119757795646SDave May   DM_Swarm      *swarm;
119857795646SDave May   PetscErrorCode ierr;
119957795646SDave May 
120057795646SDave May   PetscFunctionBegin;
120157795646SDave May   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
120257795646SDave May   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
1203f0cdbbbaSDave May   dm->data = swarm;
120457795646SDave May 
12056845f8f5SDave May   ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr);
1206f0cdbbbaSDave May   ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr);
1207f0cdbbbaSDave May 
1208b5bcf523SDave May   swarm->vec_field_set = PETSC_FALSE;
12093454631fSDave May   swarm->issetup = PETSC_FALSE;
1210480eef7bSDave May   swarm->swarm_type = DMSWARM_BASIC;
1211480eef7bSDave May   swarm->migrate_type = DMSWARM_MIGRATE_BASIC;
1212480eef7bSDave May   swarm->collect_type = DMSWARM_COLLECT_BASIC;
121340c453e9SDave May   swarm->migrate_error_on_missing_point = PETSC_FALSE;
1214b62e03f8SDave May 
1215f0cdbbbaSDave May   swarm->dmcell = NULL;
1216f0cdbbbaSDave May   swarm->collect_view_active = PETSC_FALSE;
1217f0cdbbbaSDave May   swarm->collect_view_reset_nlocal = -1;
121857795646SDave May 
1219f0cdbbbaSDave May   dm->dim  = 0;
12205f50eb2eSDave May   dm->ops->view                            = DMView_Swarm;
122157795646SDave May   dm->ops->load                            = NULL;
122257795646SDave May   dm->ops->setfromoptions                  = NULL;
122357795646SDave May   dm->ops->clone                           = NULL;
12243454631fSDave May   dm->ops->setup                           = DMSetup_Swarm;
122557795646SDave May   dm->ops->createdefaultsection            = NULL;
122657795646SDave May   dm->ops->createdefaultconstraints        = NULL;
1227b5bcf523SDave May   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
1228b5bcf523SDave May   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
122957795646SDave May   dm->ops->getlocaltoglobalmapping         = NULL;
123057795646SDave May   dm->ops->createfieldis                   = NULL;
123157795646SDave May   dm->ops->createcoordinatedm              = NULL;
123257795646SDave May   dm->ops->getcoloring                     = NULL;
123357795646SDave May   dm->ops->creatematrix                    = NULL;
123457795646SDave May   dm->ops->createinterpolation             = NULL;
123557795646SDave May   dm->ops->getaggregates                   = NULL;
123657795646SDave May   dm->ops->getinjection                    = NULL;
123757795646SDave May   dm->ops->refine                          = NULL;
123857795646SDave May   dm->ops->coarsen                         = NULL;
123957795646SDave May   dm->ops->refinehierarchy                 = NULL;
124057795646SDave May   dm->ops->coarsenhierarchy                = NULL;
124157795646SDave May   dm->ops->globaltolocalbegin              = NULL;
124257795646SDave May   dm->ops->globaltolocalend                = NULL;
124357795646SDave May   dm->ops->localtoglobalbegin              = NULL;
124457795646SDave May   dm->ops->localtoglobalend                = NULL;
124557795646SDave May   dm->ops->destroy                         = DMDestroy_Swarm;
124657795646SDave May   dm->ops->createsubdm                     = NULL;
124757795646SDave May   dm->ops->getdimpoints                    = NULL;
124857795646SDave May   dm->ops->locatepoints                    = NULL;
124957795646SDave May   PetscFunctionReturn(0);
125057795646SDave May }
1251