xref: /petsc/src/dm/impls/swarm/swarm.c (revision 8b8a38133ccbbe422f9bb4853e2244107b396a99)
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 };
9e2d107dbSDave May const char* DMSwarmPICLayoutTypeNames[] = { "regular", "gauss", "subdivision", 0 };
10f0cdbbbaSDave May 
11f0cdbbbaSDave May const char DMSwarmField_pid[] = "DMSwarm_pid";
12f0cdbbbaSDave May const char DMSwarmField_rank[] = "DMSwarm_rank";
13f0cdbbbaSDave May const char DMSwarmPICField_coor[] = "DMSwarmPIC_coor";
14e2d107dbSDave May const char DMSwarmPICField_cellid[] = "DMSwarm_cellid";
15f0cdbbbaSDave May 
16d3a51819SDave May /*@C
17dcf43ee8SDave May 
18*8b8a3813SDave May   DMSwarmVectorDefineField - Sets the field from which to define a Vec object when DMCreate{Local,Global}Vector() is called
1957795646SDave May 
20d3a51819SDave May   Collective on DM
2157795646SDave May 
22d3a51819SDave May   Input parameters:
23d3a51819SDave May . dm - a DMSwarm
24d3a51819SDave May . fieldname - The textual name given to a registered field
2557795646SDave May 
26d3a51819SDave May   Level: beginner
2757795646SDave May 
28d3a51819SDave May   Notes:
29d3a51819SDave May   The field with name fieldname must be defined as having a data type of PetscScalar
30d3a51819SDave May   This function must be called prior to calling DMCreateLocalVector(), DMCreateGlobalVector().
31d3a51819SDave May   Mutiple calls to DMSwarmVectorDefineField() are permitted.
3257795646SDave May 
33*8b8a3813SDave May . seealso: DMSwarmRegisterPetscDatatypeField(), DMCreateGlobalVector(), DMCreateLocalVector()
3457795646SDave May 
35d3a51819SDave May @*/
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");
51521f74f9SMatthew 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 PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec)
61b5bcf523SDave May {
62b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
63b5bcf523SDave May   PetscErrorCode ierr;
64b5bcf523SDave May   Vec x;
65b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
66b5bcf523SDave May 
67a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
683454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
69b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
70cc651181SDave 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 */
71cc651181SDave May 
72521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr);
73b5bcf523SDave May   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr);
74b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
751b1ea282SDave May   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr);
76b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
77b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
78b5bcf523SDave May   *vec = x;
79b5bcf523SDave May   PetscFunctionReturn(0);
80b5bcf523SDave May }
81b5bcf523SDave May 
82b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */
83b5bcf523SDave May PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec)
84b5bcf523SDave May {
85b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
86b5bcf523SDave May   PetscErrorCode ierr;
87b5bcf523SDave May   Vec x;
88b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
89b5bcf523SDave May 
90a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
913454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
92b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
93cc651181SDave 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 */
94cc651181SDave May 
95521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr);
96b5bcf523SDave May   ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr);
97b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
98071900c8SMatthew G. Knepley   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr);
99b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
100b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
101b5bcf523SDave May   *vec = x;
102b5bcf523SDave May   PetscFunctionReturn(0);
103b5bcf523SDave May }
104b5bcf523SDave May 
105fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmDestroyVectorFromField_Private(DM dm, const char fieldname[], Vec *vec)
106fb1bcc12SMatthew G. Knepley {
107fb1bcc12SMatthew G. Knepley   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
108fb1bcc12SMatthew G. Knepley   DataField      gfield;
109fb1bcc12SMatthew G. Knepley   void         (*fptr)(void);
110fb1bcc12SMatthew G. Knepley   PetscInt       bs, nlocal;
111fb1bcc12SMatthew G. Knepley   char           name[PETSC_MAX_PATH_LEN];
112fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
113d3a51819SDave May 
114fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
115fb1bcc12SMatthew G. Knepley   ierr = VecGetLocalSize(*vec, &nlocal);CHKERRQ(ierr);
116fb1bcc12SMatthew G. Knepley   ierr = VecGetBlockSize(*vec, &bs);CHKERRQ(ierr);
117fb1bcc12SMatthew 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 */
118fb1bcc12SMatthew G. Knepley   ierr = DataBucketGetDataFieldByName(swarm->db, fieldname, &gfield);CHKERRQ(ierr);
119fb1bcc12SMatthew G. Knepley   /* check vector is an inplace array */
120521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr);
121fb1bcc12SMatthew G. Knepley   ierr = PetscObjectQueryFunction((PetscObject) *vec, name, &fptr);CHKERRQ(ierr);
122fb1bcc12SMatthew G. Knepley   if (!fptr) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Vector being destroyed was not created from DMSwarm field(%s)", fieldname);
123fb1bcc12SMatthew G. Knepley   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
124fb1bcc12SMatthew G. Knepley   ierr = VecDestroy(vec);CHKERRQ(ierr);
125fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
126fb1bcc12SMatthew G. Knepley }
127fb1bcc12SMatthew G. Knepley 
128fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmCreateVectorFromField_Private(DM dm, const char fieldname[], MPI_Comm comm, Vec *vec)
129fb1bcc12SMatthew G. Knepley {
130fb1bcc12SMatthew G. Knepley   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
131fb1bcc12SMatthew G. Knepley   PetscDataType  type;
132fb1bcc12SMatthew G. Knepley   PetscScalar   *array;
133fb1bcc12SMatthew G. Knepley   PetscInt       bs, n;
134fb1bcc12SMatthew G. Knepley   char           name[PETSC_MAX_PATH_LEN];
135fb1bcc12SMatthew G. Knepley   PetscMPIInt    commsize;
136fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
137fb1bcc12SMatthew G. Knepley 
138fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
139fb1bcc12SMatthew G. Knepley   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
140fb1bcc12SMatthew G. Knepley   ierr = DataBucketGetSizes(swarm->db, &n, NULL, NULL);CHKERRQ(ierr);
141fb1bcc12SMatthew G. Knepley   ierr = DMSwarmGetField(dm, fieldname, &bs, &type, (void **) &array);CHKERRQ(ierr);
142fb1bcc12SMatthew G. Knepley   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Only valid for PETSC_REAL");
143fb1bcc12SMatthew G. Knepley 
144fb1bcc12SMatthew G. Knepley   ierr = MPI_Comm_size(comm, &commsize);CHKERRQ(ierr);
145fb1bcc12SMatthew G. Knepley   if (commsize == 1) {
146fb1bcc12SMatthew G. Knepley     ierr = VecCreateSeqWithArray(comm, bs, n*bs, array, vec);CHKERRQ(ierr);
147fb1bcc12SMatthew G. Knepley   } else {
148fb1bcc12SMatthew G. Knepley     ierr = VecCreateMPIWithArray(comm, bs, n*bs, PETSC_DETERMINE, array, vec);CHKERRQ(ierr);
149fb1bcc12SMatthew G. Knepley   }
150fb1bcc12SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarmSharedField_%s", fieldname);CHKERRQ(ierr);
151fb1bcc12SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) *vec, name);CHKERRQ(ierr);
152fb1bcc12SMatthew G. Knepley 
153fb1bcc12SMatthew G. Knepley   /* Set guard */
154fb1bcc12SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr);
155fb1bcc12SMatthew G. Knepley   ierr = PetscObjectComposeFunction((PetscObject) *vec, name, DMSwarmDestroyVectorFromField_Private);CHKERRQ(ierr);
156fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
157fb1bcc12SMatthew G. Knepley }
158fb1bcc12SMatthew G. Knepley 
159fb1bcc12SMatthew G. Knepley /*@C
160d3a51819SDave May   DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field
161d3a51819SDave May 
162d3a51819SDave May   Collective on DM
163d3a51819SDave May 
164d3a51819SDave May   Input parameters:
165d3a51819SDave May  . dm - a DMSwarm
166d3a51819SDave May  . fieldname - the textual name given to a registered field
167d3a51819SDave May 
168*8b8a3813SDave May  Output parameter:
169d3a51819SDave May  . vec - the vector
170d3a51819SDave May 
171d3a51819SDave May   Level: beginner
172d3a51819SDave May 
173*8b8a3813SDave May   Notes:
174*8b8a3813SDave May   The vector must be returned using a matching call to DMSwarmDestroyGlobalVectorFromField().
175*8b8a3813SDave May 
176*8b8a3813SDave May . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyGlobalVectorFromField()
177d3a51819SDave May @*/
178b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
179b5bcf523SDave May {
180fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PetscObjectComm((PetscObject) dm);
181b5bcf523SDave May   PetscErrorCode ierr;
182b5bcf523SDave May 
183fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
184fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
185b5bcf523SDave May   PetscFunctionReturn(0);
186b5bcf523SDave May }
187b5bcf523SDave May 
188d3a51819SDave May /*@C
189d3a51819SDave May   DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field
190d3a51819SDave May 
191d3a51819SDave May   Collective on DM
192d3a51819SDave May 
193d3a51819SDave May   Input parameters:
194d3a51819SDave May  . dm - a DMSwarm
195d3a51819SDave May  . fieldname - the textual name given to a registered field
196d3a51819SDave May 
197*8b8a3813SDave May   Output parameter:
198d3a51819SDave May  . vec - the vector
199d3a51819SDave May 
200d3a51819SDave May   Level: beginner
201d3a51819SDave May 
202*8b8a3813SDave May . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateGlobalVectorFromField()
203d3a51819SDave May @*/
204b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
205b5bcf523SDave May {
206b5bcf523SDave May   PetscErrorCode ierr;
207cc651181SDave May 
208fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
209fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
210b5bcf523SDave May   PetscFunctionReturn(0);
211b5bcf523SDave May }
212b5bcf523SDave May 
213fb1bcc12SMatthew G. Knepley /*@C
214fb1bcc12SMatthew G. Knepley   DMSwarmCreateLocalVectorFromField - Creates a Vec object sharing the array associated with a given field
215fb1bcc12SMatthew G. Knepley 
216fb1bcc12SMatthew G. Knepley   Collective on DM
217fb1bcc12SMatthew G. Knepley 
218fb1bcc12SMatthew G. Knepley   Input parameters:
219fb1bcc12SMatthew G. Knepley  . dm - a DMSwarm
220fb1bcc12SMatthew G. Knepley  . fieldname - the textual name given to a registered field
221fb1bcc12SMatthew G. Knepley 
222*8b8a3813SDave May  Output parameter:
223fb1bcc12SMatthew G. Knepley  . vec - the vector
224fb1bcc12SMatthew G. Knepley 
225fb1bcc12SMatthew G. Knepley   Level: beginner
226fb1bcc12SMatthew G. Knepley 
227*8b8a3813SDave May   Notes:
228*8b8a3813SDave May   The vector must be returned using a matching call to DMSwarmDestroyLocalVectorFromField().
229*8b8a3813SDave May 
230*8b8a3813SDave May . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyLocalVectorFromField()
231fb1bcc12SMatthew G. Knepley @*/
232fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmCreateLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
233bbe8250bSMatthew G. Knepley {
234fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PETSC_COMM_SELF;
235bbe8250bSMatthew G. Knepley   PetscErrorCode ierr;
236bbe8250bSMatthew G. Knepley 
237fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
238fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
239fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
240bbe8250bSMatthew G. Knepley }
241fb1bcc12SMatthew G. Knepley 
242fb1bcc12SMatthew G. Knepley /*@C
243fb1bcc12SMatthew G. Knepley   DMSwarmDestroyLocalVectorFromField - Destroys the Vec object which share the array associated with a given field
244fb1bcc12SMatthew G. Knepley 
245fb1bcc12SMatthew G. Knepley   Collective on DM
246fb1bcc12SMatthew G. Knepley 
247fb1bcc12SMatthew G. Knepley   Input parameters:
248fb1bcc12SMatthew G. Knepley  . dm - a DMSwarm
249fb1bcc12SMatthew G. Knepley  . fieldname - the textual name given to a registered field
250fb1bcc12SMatthew G. Knepley 
251*8b8a3813SDave May   Output parameter:
252fb1bcc12SMatthew G. Knepley  . vec - the vector
253fb1bcc12SMatthew G. Knepley 
254fb1bcc12SMatthew G. Knepley   Level: beginner
255fb1bcc12SMatthew G. Knepley 
256*8b8a3813SDave May . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateLocalVectorFromField()
257fb1bcc12SMatthew G. Knepley @*/
258fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmDestroyLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
259fb1bcc12SMatthew G. Knepley {
260fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
261fb1bcc12SMatthew G. Knepley 
262fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
263fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
264bbe8250bSMatthew G. Knepley   PetscFunctionReturn(0);
265bbe8250bSMatthew G. Knepley }
266bbe8250bSMatthew G. Knepley 
267b5bcf523SDave May /*
268b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec)
269b5bcf523SDave May {
270b5bcf523SDave May   PetscFunctionReturn(0);
271b5bcf523SDave May }
272b5bcf523SDave May 
273b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec)
274b5bcf523SDave May {
275b5bcf523SDave May   PetscFunctionReturn(0);
276b5bcf523SDave May }
277b5bcf523SDave May */
278b5bcf523SDave May 
279d3a51819SDave May /*@C
280d3a51819SDave May 
281d3a51819SDave May  DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm
282d3a51819SDave May 
283d3a51819SDave May  Collective on DM
284d3a51819SDave May 
285d3a51819SDave May  Input parameter:
286d3a51819SDave May  . dm - a DMSwarm
287d3a51819SDave May 
288d3a51819SDave May  Level: beginner
289d3a51819SDave May 
290d3a51819SDave May  Notes:
291*8b8a3813SDave May  After all fields have been registered, you must call DMSwarmFinalizeFieldRegister().
292d3a51819SDave May 
293d3a51819SDave May  . seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
294d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
295d3a51819SDave May @*/
2965f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm)
2975f50eb2eSDave May {
2985f50eb2eSDave May   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
2993454631fSDave May   PetscErrorCode ierr;
3003454631fSDave May 
301521f74f9SMatthew G. Knepley   PetscFunctionBegin;
302cc651181SDave May   if (!swarm->field_registration_initialized) {
3035f50eb2eSDave May     swarm->field_registration_initialized = PETSC_TRUE;
304f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */
305f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */
306cc651181SDave May   }
3075f50eb2eSDave May   PetscFunctionReturn(0);
3085f50eb2eSDave May }
3095f50eb2eSDave May 
310d3a51819SDave May /*@C
311d3a51819SDave May 
312d3a51819SDave May  DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm
313d3a51819SDave May 
314d3a51819SDave May  Collective on DM
315d3a51819SDave May 
316d3a51819SDave May  Input parameter:
317d3a51819SDave May  . dm - a DMSwarm
318d3a51819SDave May 
319d3a51819SDave May  Level: beginner
320d3a51819SDave May 
321d3a51819SDave May  Notes:
322*8b8a3813SDave May  After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined.
323d3a51819SDave May  on the DMSwarm
324d3a51819SDave May 
325d3a51819SDave May  . seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
326d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
327d3a51819SDave May @*/
3285f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm)
3295f50eb2eSDave May {
3305f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3316845f8f5SDave May   PetscErrorCode ierr;
3326845f8f5SDave May 
333521f74f9SMatthew G. Knepley   PetscFunctionBegin;
334f0cdbbbaSDave May   if (!swarm->field_registration_finalized) {
3356845f8f5SDave May     ierr = DataBucketFinalize(swarm->db);CHKERRQ(ierr);
336f0cdbbbaSDave May   }
337f0cdbbbaSDave May   swarm->field_registration_finalized = PETSC_TRUE;
3385f50eb2eSDave May   PetscFunctionReturn(0);
3395f50eb2eSDave May }
3405f50eb2eSDave May 
341d3a51819SDave May /*@C
342d3a51819SDave May 
343d3a51819SDave May  DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm
344d3a51819SDave May 
345d3a51819SDave May  Not collective
346d3a51819SDave May 
347d3a51819SDave May  Input parameters:
348d3a51819SDave May  . dm - a DMSwarm
349d3a51819SDave May  . nlocal - the length of each registered field
350d3a51819SDave May  . buffer - the length of the buffer used to efficient dynamic re-sizing
351d3a51819SDave May 
352d3a51819SDave May  Level: beginner
353d3a51819SDave May 
354d3a51819SDave May  . seealso: DMSwarmGetLocalSize()
355d3a51819SDave May 
356d3a51819SDave May @*/
3575f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer)
3585f50eb2eSDave May {
3595f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3606845f8f5SDave May   PetscErrorCode ierr;
3615f50eb2eSDave May 
362521f74f9SMatthew G. Knepley   PetscFunctionBegin;
3636845f8f5SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr);
3645f50eb2eSDave May   PetscFunctionReturn(0);
3655f50eb2eSDave May }
3665f50eb2eSDave May 
367d3a51819SDave May /*@C
368d3a51819SDave May 
369d3a51819SDave May  DMSwarmSetCellDM - Attachs a DM to a DMSwarm
370d3a51819SDave May 
371d3a51819SDave May  Collective on DM
372d3a51819SDave May 
373d3a51819SDave May  Input parameters:
374d3a51819SDave May  . dm - a DMSwarm
375d3a51819SDave May  . dmcell - the DM to attach to the DMSwarm
376d3a51819SDave May 
377d3a51819SDave May  Level: beginner
378d3a51819SDave May 
379d3a51819SDave May  Notes:
380d3a51819SDave May  The attached DM (dmcell) will be queried for point location and
381*8b8a3813SDave May  neighbor MPI-rank information if DMSwarmMigrate() is called.
382d3a51819SDave May 
383*8b8a3813SDave May .seealso: DMSwarmSetType(), DMSwarmGetCellDM(), DMSwarmMigrate()
384d3a51819SDave May @*/
385b16650c8SDave May PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell)
386b16650c8SDave May {
387b16650c8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
388521f74f9SMatthew G. Knepley 
389521f74f9SMatthew G. Knepley   PetscFunctionBegin;
390b16650c8SDave May   swarm->dmcell = dmcell;
391b16650c8SDave May   PetscFunctionReturn(0);
392b16650c8SDave May }
393b16650c8SDave May 
394d3a51819SDave May /*@C
395d3a51819SDave May 
396d3a51819SDave May  DMSwarmGetCellDM - Fetches the attached cell DM
397d3a51819SDave May 
398d3a51819SDave May  Collective on DM
399d3a51819SDave May 
400d3a51819SDave May  Input parameter:
401d3a51819SDave May  . dm - a DMSwarm
402d3a51819SDave May 
403d3a51819SDave May  Output parameter:
404d3a51819SDave May  . dmcell - the DM which was attached to the DMSwarm
405d3a51819SDave May 
406d3a51819SDave May  Level: beginner
407d3a51819SDave May 
408d3a51819SDave May .seealso: DMSwarmSetCellDM()
409d3a51819SDave May @*/
410fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell)
411fe39f135SDave May {
412fe39f135SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
413521f74f9SMatthew G. Knepley 
414521f74f9SMatthew G. Knepley   PetscFunctionBegin;
415fe39f135SDave May   *dmcell = swarm->dmcell;
416fe39f135SDave May   PetscFunctionReturn(0);
417fe39f135SDave May }
418fe39f135SDave May 
419d3a51819SDave May /*@C
420d3a51819SDave May 
421d3a51819SDave May  DMSwarmGetLocalSize - Retrives the local length of fields registered
422d3a51819SDave May 
423d3a51819SDave May  Not collective
424d3a51819SDave May 
425d3a51819SDave May  Input parameter:
426d3a51819SDave May  . dm - a DMSwarm
427d3a51819SDave May 
428d3a51819SDave May  Output parameter:
429d3a51819SDave May  . nlocal - the length of each registered field
430d3a51819SDave May 
431d3a51819SDave May  Level: beginner
432d3a51819SDave May 
433*8b8a3813SDave May .seealso: DMSwarmGetSize(), DMSwarmSetLocalSizes()
434d3a51819SDave May @*/
435dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal)
436dcf43ee8SDave May {
437dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
438dcf43ee8SDave May   PetscErrorCode ierr;
439dcf43ee8SDave May 
440521f74f9SMatthew G. Knepley   PetscFunctionBegin;
441521f74f9SMatthew G. Knepley   if (nlocal) {ierr = DataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);}
442dcf43ee8SDave May   PetscFunctionReturn(0);
443dcf43ee8SDave May }
444dcf43ee8SDave May 
445d3a51819SDave May /*@C
446d3a51819SDave May 
447d3a51819SDave May  DMSwarmGetSize - Retrives the total length of fields registered
448d3a51819SDave May 
449d3a51819SDave May  Collective on DM
450d3a51819SDave May 
451d3a51819SDave May  Input parameter:
452d3a51819SDave May  . dm - a DMSwarm
453d3a51819SDave May 
454d3a51819SDave May  Output parameter:
455d3a51819SDave May  . n - the total length of each registered field
456d3a51819SDave May 
457d3a51819SDave May  Level: beginner
458d3a51819SDave May 
459d3a51819SDave May  Note:
460d3a51819SDave May  This calls MPI_Allreduce upon each call (inefficient but safe)
461d3a51819SDave May 
462*8b8a3813SDave May .seealso: DMSwarmGetLocalSize(), DMSwarmSetLocalSizes()
463d3a51819SDave May @*/
464dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n)
465dcf43ee8SDave May {
466dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
467dcf43ee8SDave May   PetscErrorCode ierr;
468dcf43ee8SDave May   PetscInt nlocal,ng;
469dcf43ee8SDave May 
470521f74f9SMatthew G. Knepley   PetscFunctionBegin;
471dcf43ee8SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
472dcf43ee8SDave May   ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
473dcf43ee8SDave May   if (n) { *n = ng; }
474dcf43ee8SDave May   PetscFunctionReturn(0);
475dcf43ee8SDave May }
476dcf43ee8SDave May 
477d3a51819SDave May /*@C
478d3a51819SDave May 
479*8b8a3813SDave May  DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm with a native PETSc data type
480d3a51819SDave May 
481d3a51819SDave May  Collective on DM
482d3a51819SDave May 
483d3a51819SDave May  Input parameters:
484d3a51819SDave May  . dm - a DMSwarm
485d3a51819SDave May  . fieldname - the textual name to identify this field
486d3a51819SDave May  . blocksize - the number of each data type
487d3a51819SDave May  . type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG)
488d3a51819SDave May 
489d3a51819SDave May  Level: beginner
490d3a51819SDave May 
491d3a51819SDave May  Notes:
492*8b8a3813SDave May  The textual name for each registered field must be unique.
493d3a51819SDave May 
494d3a51819SDave May .seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
495d3a51819SDave May @*/
4965f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
497b62e03f8SDave May {
4982eac95f8SDave May   PetscErrorCode ierr;
499b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
500b62e03f8SDave May   size_t size;
501b62e03f8SDave May 
502521f74f9SMatthew G. Knepley   PetscFunctionBegin;
5035f50eb2eSDave May   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
5045f50eb2eSDave May   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
5055f50eb2eSDave May 
5065f50eb2eSDave May   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5075f50eb2eSDave May   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5085f50eb2eSDave May   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5095f50eb2eSDave May   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5105f50eb2eSDave May   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
511b62e03f8SDave May 
5122ddcf43eSMatthew G. Knepley   ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr);
513b62e03f8SDave May   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
51452c3ed93SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
51552c3ed93SDave May   {
51652c3ed93SDave May     DataField gfield;
51752c3ed93SDave May 
51852c3ed93SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
51952c3ed93SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
52052c3ed93SDave May   }
521b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
522b62e03f8SDave May   PetscFunctionReturn(0);
523b62e03f8SDave May }
524b62e03f8SDave May 
525d3a51819SDave May /*@C
526d3a51819SDave May 
527d3a51819SDave May  DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm
528d3a51819SDave May 
529d3a51819SDave May  Collective on DM
530d3a51819SDave May 
531d3a51819SDave May  Input parameters:
532d3a51819SDave May  . dm - a DMSwarm
533d3a51819SDave May  . fieldname - the textual name to identify this field
534d3a51819SDave May  . size - the size in bytes of the user struct of each data type
535d3a51819SDave May 
536d3a51819SDave May  Level: beginner
537d3a51819SDave May 
538d3a51819SDave May  Notes:
539*8b8a3813SDave May  The textual name for each registered field must be unique.
540d3a51819SDave May 
541d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField()
542d3a51819SDave May @*/
5435f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
544b62e03f8SDave May {
5452eac95f8SDave May   PetscErrorCode ierr;
546b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
547b62e03f8SDave May 
548521f74f9SMatthew G. Knepley   PetscFunctionBegin;
5492eac95f8SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
550b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
551b62e03f8SDave May   PetscFunctionReturn(0);
552b62e03f8SDave May }
553b62e03f8SDave May 
554d3a51819SDave May /*@C
555d3a51819SDave May 
556d3a51819SDave May  DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm
557d3a51819SDave May 
558d3a51819SDave May  Collective on DM
559d3a51819SDave May 
560d3a51819SDave May  Input parameters:
561d3a51819SDave May  . dm - a DMSwarm
562d3a51819SDave May  . fieldname - the textual name to identify this field
563d3a51819SDave May  . size - the size in bytes of the user data type
564d3a51819SDave May  . blocksize - the number of each data type
565d3a51819SDave May 
566d3a51819SDave May  Level: beginner
567d3a51819SDave May 
568d3a51819SDave May  Notes:
569*8b8a3813SDave May  The textual name for each registered field must be unique.
570d3a51819SDave May 
571d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
572d3a51819SDave May @*/
573320740a0SDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize)
574b62e03f8SDave May {
575b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
5766845f8f5SDave May   PetscErrorCode ierr;
577b62e03f8SDave May 
578521f74f9SMatthew G. Knepley   PetscFunctionBegin;
579320740a0SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
580320740a0SDave May   {
581320740a0SDave May     DataField gfield;
582320740a0SDave May 
583320740a0SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
584320740a0SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
585320740a0SDave May   }
586b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
587b62e03f8SDave May   PetscFunctionReturn(0);
588b62e03f8SDave May }
589b62e03f8SDave May 
590d3a51819SDave May /*@C
591d3a51819SDave May 
592d3a51819SDave May  DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field
593d3a51819SDave May 
594d3a51819SDave May  Not collective
595d3a51819SDave May 
596d3a51819SDave May  Input parameters:
597d3a51819SDave May  . dm - a DMSwarm
598d3a51819SDave May  . fieldname - the textual name to identify this field
599d3a51819SDave May 
600d3a51819SDave May  Output parameters:
601d3a51819SDave May  . blocksize - the number of each data type
602d3a51819SDave May  . type - the data type
603d3a51819SDave May  . data - pointer to raw array
604d3a51819SDave May 
605d3a51819SDave May  Level: beginner
606d3a51819SDave May 
607d3a51819SDave May  Notes:
608*8b8a3813SDave May  The array must be returned using a matching call to DMSwarmRestoreField().
609d3a51819SDave May 
610d3a51819SDave May .seealso: DMSwarmRestoreField()
611d3a51819SDave May @*/
6125f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
613b62e03f8SDave May {
614b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
615b62e03f8SDave May   DataField gfield;
6162eac95f8SDave May   PetscErrorCode ierr;
617b62e03f8SDave May 
618521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6193454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
6202eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6216845f8f5SDave May   ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr);
6226845f8f5SDave May   ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr);
6231b1ea282SDave May   if (blocksize) {*blocksize = gfield->bs; }
624b5bcf523SDave May   if (type) { *type = gfield->petsc_type; }
625b62e03f8SDave May   PetscFunctionReturn(0);
626b62e03f8SDave May }
627b62e03f8SDave May 
628d3a51819SDave May /*@C
629d3a51819SDave May 
630d3a51819SDave May  DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field
631d3a51819SDave May 
632d3a51819SDave May  Not collective
633d3a51819SDave May 
634d3a51819SDave May  Input parameters:
635d3a51819SDave May  . dm - a DMSwarm
636d3a51819SDave May  . fieldname - the textual name to identify this field
637d3a51819SDave May 
638d3a51819SDave May  Output parameters:
639d3a51819SDave May  . blocksize - the number of each data type
640d3a51819SDave May  . type - the data type
641d3a51819SDave May  . data - pointer to raw array
642d3a51819SDave May 
643d3a51819SDave May  Level: beginner
644d3a51819SDave May 
645d3a51819SDave May  Notes:
646*8b8a3813SDave May  The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField().
647d3a51819SDave May 
648d3a51819SDave May .seealso: DMSwarmGetField()
649d3a51819SDave May @*/
6505f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
651b62e03f8SDave May {
652b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
653b62e03f8SDave May   DataField gfield;
6542eac95f8SDave May   PetscErrorCode ierr;
655b62e03f8SDave May 
656521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6572eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6586845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
659b62e03f8SDave May   if (data) *data = NULL;
660b62e03f8SDave May   PetscFunctionReturn(0);
661b62e03f8SDave May }
662b62e03f8SDave May 
663d3a51819SDave May /*@C
664d3a51819SDave May 
665d3a51819SDave May  DMSwarmAddPoint - Add space for one new point in the DMSwarm
666d3a51819SDave May 
667d3a51819SDave May  Not collective
668d3a51819SDave May 
669d3a51819SDave May  Input parameter:
670d3a51819SDave May  . dm - a DMSwarm
671d3a51819SDave May 
672d3a51819SDave May  Level: beginner
673d3a51819SDave May 
674d3a51819SDave May  Notes:
675*8b8a3813SDave May  The new point will have all fields initialized to zero.
676d3a51819SDave May 
677d3a51819SDave May .seealso: DMSwarmAddNPoints()
678d3a51819SDave May @*/
679cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
680cb1d1399SDave May {
681cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
682cb1d1399SDave May   PetscErrorCode ierr;
683cb1d1399SDave May 
684521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6853454631fSDave May   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
686cb1d1399SDave May   ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr);
687cb1d1399SDave May   PetscFunctionReturn(0);
688cb1d1399SDave May }
689cb1d1399SDave May 
690d3a51819SDave May /*@C
691d3a51819SDave May 
692d3a51819SDave May  DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm
693d3a51819SDave May 
694d3a51819SDave May  Not collective
695d3a51819SDave May 
696d3a51819SDave May  Input parameters:
697d3a51819SDave May  . dm - a DMSwarm
698d3a51819SDave May  . npoints - the number of new points to add
699d3a51819SDave May 
700d3a51819SDave May  Level: beginner
701d3a51819SDave May 
702d3a51819SDave May  Notes:
703*8b8a3813SDave May  The new point will have all fields initialized to zero.
704d3a51819SDave May 
705d3a51819SDave May .seealso: DMSwarmAddPoint()
706d3a51819SDave May @*/
707cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
708cb1d1399SDave May {
709cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
710cb1d1399SDave May   PetscErrorCode ierr;
711cb1d1399SDave May   PetscInt nlocal;
712cb1d1399SDave May 
713521f74f9SMatthew G. Knepley   PetscFunctionBegin;
714cb1d1399SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
715cb1d1399SDave May   nlocal = nlocal + npoints;
716cb1d1399SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,-1);CHKERRQ(ierr);
717cb1d1399SDave May   PetscFunctionReturn(0);
718cb1d1399SDave May }
719cb1d1399SDave May 
720d3a51819SDave May /*@C
721d3a51819SDave May 
722d3a51819SDave May  DMSwarmRemovePoint - Remove the last point from 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 .seealso: DMSwarmRemovePointAtIndex()
732d3a51819SDave May @*/
733cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
734cb1d1399SDave May {
735cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
736cb1d1399SDave May   PetscErrorCode ierr;
737cb1d1399SDave May 
738521f74f9SMatthew G. Knepley   PetscFunctionBegin;
739cb1d1399SDave May   ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
740cb1d1399SDave May   PetscFunctionReturn(0);
741cb1d1399SDave May }
742cb1d1399SDave May 
743d3a51819SDave May /*@C
744d3a51819SDave May  DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm
745d3a51819SDave May 
746d3a51819SDave May  Not collective
747d3a51819SDave May 
748d3a51819SDave May  Input parameters:
749d3a51819SDave May  . dm - a DMSwarm
750d3a51819SDave May  . idx - index of point to remove
751d3a51819SDave May 
752d3a51819SDave May  Level: beginner
753d3a51819SDave May 
754d3a51819SDave May .seealso: DMSwarmRemovePoint()
755d3a51819SDave May @*/
756cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
757cb1d1399SDave May {
758cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
759cb1d1399SDave May   PetscErrorCode ierr;
760cb1d1399SDave May 
761521f74f9SMatthew G. Knepley   PetscFunctionBegin;
762cb1d1399SDave May   ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
763cb1d1399SDave May   PetscFunctionReturn(0);
764cb1d1399SDave May }
765b62e03f8SDave May 
766095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points)
7673454631fSDave May {
768dcf43ee8SDave May   PetscErrorCode ierr;
769521f74f9SMatthew G. Knepley 
770521f74f9SMatthew G. Knepley   PetscFunctionBegin;
771dcf43ee8SDave May   ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr);
7723454631fSDave May   PetscFunctionReturn(0);
7733454631fSDave May }
7743454631fSDave May 
775d3a51819SDave May /*@C
776d3a51819SDave May 
777d3a51819SDave May  DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks
778d3a51819SDave May 
779d3a51819SDave May  Collective on DM
780d3a51819SDave May 
781d3a51819SDave May  Input parameters:
782d3a51819SDave May  . dm - the DMSwarm
783d3a51819SDave May  . remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank
784d3a51819SDave May 
785d3a51819SDave May  Notes:
786*8b8a3813SDave May  The DM will be modified to accomodate received points.
787*8b8a3813SDave May  If remove_sent_points = PETSC_TRUE, any points that were sent will be removed from the DM.
788*8b8a3813SDave May  Different styles of migration are supported. See DMSwarmSetMigrateType().
789d3a51819SDave May 
790d3a51819SDave May  Level: advanced
791d3a51819SDave May 
792d3a51819SDave May .seealso: DMSwarmSetMigrateType()
793d3a51819SDave May @*/
794095059a4SDave May PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points)
7953454631fSDave May {
796f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
7973454631fSDave May   PetscErrorCode ierr;
798f0cdbbbaSDave May 
799521f74f9SMatthew G. Knepley   PetscFunctionBegin;
800f0cdbbbaSDave May   switch (swarm->migrate_type) {
801f0cdbbbaSDave May     case DMSWARM_MIGRATE_BASIC:
802095059a4SDave May       ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr);
803f0cdbbbaSDave May       break;
804f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLNSCATTER:
805f0cdbbbaSDave May       ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr);
806f0cdbbbaSDave May       break;
807f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLEXACT:
808f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented");
809521f74f9SMatthew G. Knepley       /*ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr);*/
810f0cdbbbaSDave May       break;
811f0cdbbbaSDave May     case DMSWARM_MIGRATE_USER:
812f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented");
813521f74f9SMatthew G. Knepley       /*ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr);*/
814f0cdbbbaSDave May       break;
815f0cdbbbaSDave May     default:
816f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown");
817f0cdbbbaSDave May       break;
818f0cdbbbaSDave May   }
8193454631fSDave May   PetscFunctionReturn(0);
8203454631fSDave May }
8213454631fSDave May 
822f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize);
823f0cdbbbaSDave May 
824d3a51819SDave May /*
825d3a51819SDave May  DMSwarmCollectViewCreate
826d3a51819SDave May 
827d3a51819SDave May  * Applies a collection method and gathers point neighbour points into dm
828d3a51819SDave May 
829d3a51819SDave May  Notes:
830*8b8a3813SDave May  Users should call DMSwarmCollectViewDestroy() after
831d3a51819SDave May  they have finished computations associated with the collected points
832d3a51819SDave May */
833d3a51819SDave May 
834d3a51819SDave May /*@C
835d3a51819SDave May 
836d3a51819SDave May  DMSwarmCollectViewCreate - Applies a collection method and gathers points
837d3a51819SDave May  in neighbour MPI-ranks into the DMSwarm
838d3a51819SDave May 
839d3a51819SDave May  Collective on DM
840d3a51819SDave May 
841d3a51819SDave May  Input parameter:
842d3a51819SDave May  . dm - the DMSwarm
843d3a51819SDave May 
844d3a51819SDave May  Notes:
845d3a51819SDave May  Users should call DMSwarmCollectViewDestroy() after
846d3a51819SDave May  they have finished computations associated with the collected points
847*8b8a3813SDave May  Different collect methods are supported. See DMSwarmSetCollectType().
848d3a51819SDave May 
849d3a51819SDave May  Level: advanced
850d3a51819SDave May 
851d3a51819SDave May .seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType()
852d3a51819SDave May @*/
853fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm)
8542712d1f2SDave May {
8552712d1f2SDave May   PetscErrorCode ierr;
8562712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8572712d1f2SDave May   PetscInt ng;
8582712d1f2SDave May 
859521f74f9SMatthew G. Knepley   PetscFunctionBegin;
860480eef7bSDave May   if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active");
861480eef7bSDave May   ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr);
862480eef7bSDave May   switch (swarm->collect_type) {
863f0cdbbbaSDave May 
864480eef7bSDave May     case DMSWARM_COLLECT_BASIC:
8652712d1f2SDave May       ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr);
866480eef7bSDave May       break;
867480eef7bSDave May     case DMSWARM_COLLECT_DMDABOUNDINGBOX:
868f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented");
869521f74f9SMatthew G. Knepley       /*ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr);*/
870480eef7bSDave May       break;
871480eef7bSDave May     case DMSWARM_COLLECT_GENERAL:
872f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented");
873521f74f9SMatthew G. Knepley       /*ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr);*/
874480eef7bSDave May       break;
875480eef7bSDave May     default:
876f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown");
877480eef7bSDave May       break;
878480eef7bSDave May   }
879480eef7bSDave May   swarm->collect_view_active = PETSC_TRUE;
880480eef7bSDave May   swarm->collect_view_reset_nlocal = ng;
8812712d1f2SDave May   PetscFunctionReturn(0);
8822712d1f2SDave May }
8832712d1f2SDave May 
884d3a51819SDave May /*@C
885d3a51819SDave May 
886d3a51819SDave May  DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate()
887d3a51819SDave May 
888d3a51819SDave May  Collective on DM
889d3a51819SDave May 
890d3a51819SDave May  Input parameters:
891d3a51819SDave May  . dm - the DMSwarm
892d3a51819SDave May 
893d3a51819SDave May  Notes:
894d3a51819SDave May  Users should call DMSwarmCollectViewCreate() before this function is called.
895d3a51819SDave May 
896d3a51819SDave May  Level: advanced
897d3a51819SDave May 
898d3a51819SDave May .seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType()
899d3a51819SDave May @*/
900fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm)
9012712d1f2SDave May {
9022712d1f2SDave May   PetscErrorCode ierr;
9032712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9042712d1f2SDave May 
905521f74f9SMatthew G. Knepley   PetscFunctionBegin;
906480eef7bSDave May   if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active");
907480eef7bSDave May   ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr);
908480eef7bSDave May   swarm->collect_view_active = PETSC_FALSE;
9092712d1f2SDave May   PetscFunctionReturn(0);
9102712d1f2SDave May }
9113454631fSDave May 
912f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm)
913f0cdbbbaSDave May {
914f0cdbbbaSDave May   PetscInt dim;
915f0cdbbbaSDave May   PetscErrorCode ierr;
916f0cdbbbaSDave May 
917521f74f9SMatthew G. Knepley   PetscFunctionBegin;
918f0cdbbbaSDave May   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
919f0cdbbbaSDave May   if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
920f0cdbbbaSDave May   if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
921f0cdbbbaSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr);
922e2d107dbSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_cellid,1,PETSC_INT);CHKERRQ(ierr);
923f0cdbbbaSDave May   PetscFunctionReturn(0);
924f0cdbbbaSDave May }
925f0cdbbbaSDave May 
926d3a51819SDave May /*@C
927d3a51819SDave May 
928d3a51819SDave May  DMSwarmSetType - Set particular flavor of DMSwarm
929d3a51819SDave May 
930d3a51819SDave May  Collective on DM
931d3a51819SDave May 
932d3a51819SDave May  Input parameters:
933d3a51819SDave May . dm - the DMSwarm
934d3a51819SDave May . stype - the DMSwarm type (e.g. DMSWARM_PIC)
935d3a51819SDave May 
936d3a51819SDave May  Level: advanced
937d3a51819SDave May 
938d3a51819SDave May .seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType()
939d3a51819SDave May @*/
940f0cdbbbaSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype)
941f0cdbbbaSDave May {
942f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
943f0cdbbbaSDave May   PetscErrorCode ierr;
944f0cdbbbaSDave May 
945521f74f9SMatthew G. Knepley   PetscFunctionBegin;
946f0cdbbbaSDave May   swarm->swarm_type = stype;
947f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
948f0cdbbbaSDave May     ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr);
949f0cdbbbaSDave May   }
950f0cdbbbaSDave May   PetscFunctionReturn(0);
951f0cdbbbaSDave May }
952f0cdbbbaSDave May 
9533454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm)
9543454631fSDave May {
9553454631fSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9563454631fSDave May   PetscErrorCode ierr;
9573454631fSDave May   PetscMPIInt rank;
9583454631fSDave May   PetscInt p,npoints,*rankval;
9593454631fSDave May 
960521f74f9SMatthew G. Knepley   PetscFunctionBegin;
9613454631fSDave May   if (swarm->issetup) PetscFunctionReturn(0);
9623454631fSDave May 
9633454631fSDave May   swarm->issetup = PETSC_TRUE;
9643454631fSDave May 
965f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
966f0cdbbbaSDave May     /* check dmcell exists */
967f0cdbbbaSDave May     if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM");
968f0cdbbbaSDave May 
969f0cdbbbaSDave May     if (swarm->dmcell->ops->locatepointssubdomain) {
970f0cdbbbaSDave May       /* check methods exists for exact ownership identificiation */
971521f74f9SMatthew G. Knepley       ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");CHKERRQ(ierr);
972f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT;
973f0cdbbbaSDave May     } else {
974f0cdbbbaSDave May       /* check methods exist for point location AND rank neighbor identification */
975f0cdbbbaSDave May       if (swarm->dmcell->ops->locatepoints) {
976521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->LocatePoints\n");CHKERRQ(ierr);
977f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined");
978f0cdbbbaSDave May 
979f0cdbbbaSDave May       if (swarm->dmcell->ops->getneighbors) {
980521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->GetNeigbors\n");CHKERRQ(ierr);
981f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined");
982f0cdbbbaSDave May 
983f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER;
984f0cdbbbaSDave May     }
985f0cdbbbaSDave May   }
986f0cdbbbaSDave May 
987f0cdbbbaSDave May   ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr);
988f0cdbbbaSDave May 
9893454631fSDave May   /* check some fields were registered */
9903454631fSDave May   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
9913454631fSDave May 
9923454631fSDave May   /* check local sizes were set */
9933454631fSDave May   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
9943454631fSDave May 
9953454631fSDave May   /* initialize values in pid and rank placeholders */
9963454631fSDave May   /* TODO: [pid - use MPI_Scan] */
9973454631fSDave May   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
9983454631fSDave May   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
999f0cdbbbaSDave May   ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10003454631fSDave May   for (p=0; p<npoints; p++) {
10013454631fSDave May     rankval[p] = (PetscInt)rank;
10023454631fSDave May   }
1003f0cdbbbaSDave May   ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10043454631fSDave May   PetscFunctionReturn(0);
10053454631fSDave May }
10063454631fSDave May 
100757795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm)
100857795646SDave May {
100957795646SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
101057795646SDave May   PetscErrorCode ierr;
101157795646SDave May 
101257795646SDave May   PetscFunctionBegin;
10136845f8f5SDave May   ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr);
101457795646SDave May   ierr = PetscFree(swarm);CHKERRQ(ierr);
101557795646SDave May   PetscFunctionReturn(0);
101657795646SDave May }
101757795646SDave May 
1018a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer)
1019a9ee3421SMatthew G. Knepley {
1020a9ee3421SMatthew G. Knepley   DM             cdm;
1021a9ee3421SMatthew G. Knepley   PetscDraw      draw;
1022a9ee3421SMatthew G. Knepley   PetscReal     *coords, oldPause;
1023a9ee3421SMatthew G. Knepley   PetscInt       Np, p, bs;
1024a9ee3421SMatthew G. Knepley   PetscErrorCode ierr;
1025a9ee3421SMatthew G. Knepley 
1026a9ee3421SMatthew G. Knepley   PetscFunctionBegin;
1027a9ee3421SMatthew G. Knepley   ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr);
1028a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr);
1029a9ee3421SMatthew G. Knepley   ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr);
1030a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr);
1031a9ee3421SMatthew G. Knepley   ierr = DMView(cdm, viewer);CHKERRQ(ierr);
1032a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr);
1033a9ee3421SMatthew G. Knepley 
1034a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr);
1035a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1036a9ee3421SMatthew G. Knepley   for (p = 0; p < Np; ++p) {
1037a9ee3421SMatthew G. Knepley     const PetscInt i = p*bs;
1038a9ee3421SMatthew G. Knepley 
1039a9ee3421SMatthew G. Knepley     ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], 0.01, 0.01, PETSC_DRAW_BLUE);CHKERRQ(ierr);
1040a9ee3421SMatthew G. Knepley   }
1041a9ee3421SMatthew G. Knepley   ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1042a9ee3421SMatthew G. Knepley   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
1043a9ee3421SMatthew G. Knepley   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
1044a9ee3421SMatthew G. Knepley   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1045a9ee3421SMatthew G. Knepley   PetscFunctionReturn(0);
1046a9ee3421SMatthew G. Knepley }
1047a9ee3421SMatthew G. Knepley 
10485f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
10495f50eb2eSDave May {
10505f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1051a9ee3421SMatthew G. Knepley   PetscBool      iascii,ibinary,ishdf5,isvtk,isdraw;
10525f50eb2eSDave May   PetscErrorCode ierr;
10535f50eb2eSDave May 
10545f50eb2eSDave May   PetscFunctionBegin;
10555f50eb2eSDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10565f50eb2eSDave May   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
10575f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
10585f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
10595f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
10605f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1061a9ee3421SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW,  &isdraw);CHKERRQ(ierr);
10625f50eb2eSDave May   if (iascii) {
10636845f8f5SDave May     ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
10645f50eb2eSDave May   } else if (ibinary) {
1065a9ee3421SMatthew G. Knepley     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support");
10665f50eb2eSDave May   } else if (ishdf5) {
10675f50eb2eSDave May #if defined(PETSC_HAVE_HDF5)
10685f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
10695f50eb2eSDave May #else
10705f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
10715f50eb2eSDave May #endif
10725f50eb2eSDave May   } else if (isvtk) {
10735f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
1074a9ee3421SMatthew G. Knepley   } else if (isdraw) {
1075a9ee3421SMatthew G. Knepley     ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr);
10765f50eb2eSDave May   }
10775f50eb2eSDave May   PetscFunctionReturn(0);
10785f50eb2eSDave May }
10795f50eb2eSDave May 
1080d3a51819SDave May /*MC
1081d3a51819SDave May 
1082d3a51819SDave May  DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type.
1083d3a51819SDave May  This implementation was designed for particle-in-cell type methods in which the underlying
1084d3a51819SDave May  data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type.
1085d3a51819SDave May 
1086d3a51819SDave May  User data can be represented by DMSwarm through a registring "fields".
1087d3a51819SDave May  To register a field, the user must provide:
1088d3a51819SDave May  (a) a unique name
1089d3a51819SDave May  (b) the data type (or size in bytes)
1090d3a51819SDave May  (c) the block size of the data
1091d3a51819SDave May 
1092d3a51819SDave May  For example, suppose the application requires a unique id, energy, momentum and density to be stored
1093d3a51819SDave May  on a set of of particles. Then the following application could be used
1094d3a51819SDave May 
1095d3a51819SDave May  DMSwarmInitializeFieldRegister(dm)
1096d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG);
1097d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL);
1098d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL);
1099d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT);
1100d3a51819SDave May  DMSwarmFinalizeFieldRegister(dm)
1101d3a51819SDave May 
1102d3a51819SDave May  The fields represented by DMSwarm are dynamic and can be re-sized at any time.
1103d3a51819SDave May  The only restriction imposed by DMSwarm is that all fields contain the same number of points
1104d3a51819SDave May 
1105d3a51819SDave May  To support particle methods, "migration" techniques are provided. These methods migrate data
1106d3a51819SDave May  between MPI-ranks.
1107d3a51819SDave May 
1108d3a51819SDave May  DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector().
1109d3a51819SDave May  As a DMSwarm may internally define and store values of different data types,
1110d3a51819SDave May  before calling DMCreate{Global/Local}Vector() the user must inform DMSwarm which
1111d3a51819SDave May  fields should be used to define a Vec object via
1112d3a51819SDave May    DMSwarmVectorDefineField()
1113d3a51819SDave May  The specified field can can changed be changed at any time - thereby permitting vectors
1114d3a51819SDave May  compatable with different fields to be created.
1115d3a51819SDave May 
1116d3a51819SDave May  A dual representation of fields in the DMSwarm and a Vec object are permitted via
1117d3a51819SDave May    DMSwarmCreateGlobalVectorFromField()
1118d3a51819SDave May  Here the data defining the field in the DMSwarm is shared with a Vec.
1119d3a51819SDave May  This is inherently unsafe if you alter the size of the field at any time between
1120d3a51819SDave May  calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField().
1121cc651181SDave May  If the local size of the DMSwarm does not match the localsize of the global vector
1122cc651181SDave May  when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown.
1123d3a51819SDave May 
1124d3a51819SDave May  Level: beginner
1125d3a51819SDave May 
1126d3a51819SDave May .seealso: DMType, DMCreate(), DMSetType()
1127d3a51819SDave May M*/
112857795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
112957795646SDave May {
113057795646SDave May   DM_Swarm      *swarm;
113157795646SDave May   PetscErrorCode ierr;
113257795646SDave May 
113357795646SDave May   PetscFunctionBegin;
113457795646SDave May   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
113557795646SDave May   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
1136f0cdbbbaSDave May   dm->data = swarm;
113757795646SDave May 
11386845f8f5SDave May   ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr);
1139f0cdbbbaSDave May   ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr);
1140f0cdbbbaSDave May 
1141b5bcf523SDave May   swarm->vec_field_set = PETSC_FALSE;
11423454631fSDave May   swarm->issetup = PETSC_FALSE;
1143480eef7bSDave May   swarm->swarm_type = DMSWARM_BASIC;
1144480eef7bSDave May   swarm->migrate_type = DMSWARM_MIGRATE_BASIC;
1145480eef7bSDave May   swarm->collect_type = DMSWARM_COLLECT_BASIC;
114640c453e9SDave May   swarm->migrate_error_on_missing_point = PETSC_FALSE;
1147b62e03f8SDave May 
1148f0cdbbbaSDave May   swarm->dmcell = NULL;
1149f0cdbbbaSDave May   swarm->collect_view_active = PETSC_FALSE;
1150f0cdbbbaSDave May   swarm->collect_view_reset_nlocal = -1;
115157795646SDave May 
1152f0cdbbbaSDave May   dm->dim  = 0;
11535f50eb2eSDave May   dm->ops->view                            = DMView_Swarm;
115457795646SDave May   dm->ops->load                            = NULL;
115557795646SDave May   dm->ops->setfromoptions                  = NULL;
115657795646SDave May   dm->ops->clone                           = NULL;
11573454631fSDave May   dm->ops->setup                           = DMSetup_Swarm;
115857795646SDave May   dm->ops->createdefaultsection            = NULL;
115957795646SDave May   dm->ops->createdefaultconstraints        = NULL;
1160b5bcf523SDave May   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
1161b5bcf523SDave May   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
116257795646SDave May   dm->ops->getlocaltoglobalmapping         = NULL;
116357795646SDave May   dm->ops->createfieldis                   = NULL;
116457795646SDave May   dm->ops->createcoordinatedm              = NULL;
116557795646SDave May   dm->ops->getcoloring                     = NULL;
116657795646SDave May   dm->ops->creatematrix                    = NULL;
116757795646SDave May   dm->ops->createinterpolation             = NULL;
116857795646SDave May   dm->ops->getaggregates                   = NULL;
116957795646SDave May   dm->ops->getinjection                    = NULL;
117057795646SDave May   dm->ops->refine                          = NULL;
117157795646SDave May   dm->ops->coarsen                         = NULL;
117257795646SDave May   dm->ops->refinehierarchy                 = NULL;
117357795646SDave May   dm->ops->coarsenhierarchy                = NULL;
117457795646SDave May   dm->ops->globaltolocalbegin              = NULL;
117557795646SDave May   dm->ops->globaltolocalend                = NULL;
117657795646SDave May   dm->ops->localtoglobalbegin              = NULL;
117757795646SDave May   dm->ops->localtoglobalend                = NULL;
117857795646SDave May   dm->ops->destroy                         = DMDestroy_Swarm;
117957795646SDave May   dm->ops->createsubdm                     = NULL;
118057795646SDave May   dm->ops->getdimpoints                    = NULL;
118157795646SDave May   dm->ops->locatepoints                    = NULL;
118257795646SDave May   PetscFunctionReturn(0);
118357795646SDave May }
1184