xref: /petsc/src/dm/impls/swarm/swarm.c (revision e2d107db826654ae5ceb41f42932c0068b201924)
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 };
9*e2d107dbSDave 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";
14*e2d107dbSDave May const char DMSwarmPICField_cellid[] = "DMSwarm_cellid";
15f0cdbbbaSDave May 
16d3a51819SDave May /*@C
17dcf43ee8SDave May 
18d3a51819SDave May   DMSwarmVectorDefineField - Sets the field from which to define a Vec object
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 
33d3a51819SDave May . seealso: DMSwarmRegisterPetscDatatypeField()
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 
168d3a51819SDave May  Output parameters:
169d3a51819SDave May  . vec - the vector
170d3a51819SDave May 
171d3a51819SDave May   Level: beginner
172d3a51819SDave May 
173d3a51819SDave May . seealso: DMSwarmRegisterPetscDatatypeField()
174d3a51819SDave May @*/
175b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
176b5bcf523SDave May {
177fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PetscObjectComm((PetscObject) dm);
178b5bcf523SDave May   PetscErrorCode ierr;
179b5bcf523SDave May 
180fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
181fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
182b5bcf523SDave May   PetscFunctionReturn(0);
183b5bcf523SDave May }
184b5bcf523SDave May 
185d3a51819SDave May /*@C
186d3a51819SDave May   DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field
187d3a51819SDave May 
188d3a51819SDave May   Collective on DM
189d3a51819SDave May 
190d3a51819SDave May   Input parameters:
191d3a51819SDave May  . dm - a DMSwarm
192d3a51819SDave May  . fieldname - the textual name given to a registered field
193d3a51819SDave May 
194d3a51819SDave May   Output parameters:
195d3a51819SDave May  . vec - the vector
196d3a51819SDave May 
197d3a51819SDave May   Level: beginner
198d3a51819SDave May 
199d3a51819SDave May . seealso: DMSwarmRegisterPetscDatatypeField()
200d3a51819SDave May @*/
201b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
202b5bcf523SDave May {
203b5bcf523SDave May   PetscErrorCode ierr;
204cc651181SDave May 
205fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
206fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
207b5bcf523SDave May   PetscFunctionReturn(0);
208b5bcf523SDave May }
209b5bcf523SDave May 
210fb1bcc12SMatthew G. Knepley /*@C
211fb1bcc12SMatthew G. Knepley   DMSwarmCreateLocalVectorFromField - Creates a Vec object sharing the array associated with a given field
212fb1bcc12SMatthew G. Knepley 
213fb1bcc12SMatthew G. Knepley   Collective on DM
214fb1bcc12SMatthew G. Knepley 
215fb1bcc12SMatthew G. Knepley   Input parameters:
216fb1bcc12SMatthew G. Knepley  . dm - a DMSwarm
217fb1bcc12SMatthew G. Knepley  . fieldname - the textual name given to a registered field
218fb1bcc12SMatthew G. Knepley 
219fb1bcc12SMatthew G. Knepley  Output parameters:
220fb1bcc12SMatthew G. Knepley  . vec - the vector
221fb1bcc12SMatthew G. Knepley 
222fb1bcc12SMatthew G. Knepley   Level: beginner
223fb1bcc12SMatthew G. Knepley 
224fb1bcc12SMatthew G. Knepley . seealso: DMSwarmRegisterPetscDatatypeField()
225fb1bcc12SMatthew G. Knepley @*/
226fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmCreateLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
227bbe8250bSMatthew G. Knepley {
228fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PETSC_COMM_SELF;
229bbe8250bSMatthew G. Knepley   PetscErrorCode ierr;
230bbe8250bSMatthew G. Knepley 
231fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
232fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
233fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
234bbe8250bSMatthew G. Knepley }
235fb1bcc12SMatthew G. Knepley 
236fb1bcc12SMatthew G. Knepley /*@C
237fb1bcc12SMatthew G. Knepley   DMSwarmDestroyLocalVectorFromField - Destroys the Vec object which share the array associated with a given field
238fb1bcc12SMatthew G. Knepley 
239fb1bcc12SMatthew G. Knepley   Collective on DM
240fb1bcc12SMatthew G. Knepley 
241fb1bcc12SMatthew G. Knepley   Input parameters:
242fb1bcc12SMatthew G. Knepley  . dm - a DMSwarm
243fb1bcc12SMatthew G. Knepley  . fieldname - the textual name given to a registered field
244fb1bcc12SMatthew G. Knepley 
245fb1bcc12SMatthew G. Knepley   Output parameters:
246fb1bcc12SMatthew G. Knepley  . vec - the vector
247fb1bcc12SMatthew G. Knepley 
248fb1bcc12SMatthew G. Knepley   Level: beginner
249fb1bcc12SMatthew G. Knepley 
250fb1bcc12SMatthew G. Knepley . seealso: DMSwarmRegisterPetscDatatypeField()
251fb1bcc12SMatthew G. Knepley @*/
252fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmDestroyLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
253fb1bcc12SMatthew G. Knepley {
254fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
255fb1bcc12SMatthew G. Knepley 
256fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
257fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
258bbe8250bSMatthew G. Knepley   PetscFunctionReturn(0);
259bbe8250bSMatthew G. Knepley }
260bbe8250bSMatthew G. Knepley 
261b5bcf523SDave May /*
262b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec)
263b5bcf523SDave May {
264b5bcf523SDave May   PetscFunctionReturn(0);
265b5bcf523SDave May }
266b5bcf523SDave May 
267b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec)
268b5bcf523SDave May {
269b5bcf523SDave May   PetscFunctionReturn(0);
270b5bcf523SDave May }
271b5bcf523SDave May */
272b5bcf523SDave May 
273d3a51819SDave May /*@C
274d3a51819SDave May 
275d3a51819SDave May  DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm
276d3a51819SDave May 
277d3a51819SDave May  Collective on DM
278d3a51819SDave May 
279d3a51819SDave May  Input parameter:
280d3a51819SDave May  . dm - a DMSwarm
281d3a51819SDave May 
282d3a51819SDave May  Level: beginner
283d3a51819SDave May 
284d3a51819SDave May  Notes:
285d3a51819SDave May  After all fields have been registered, users should call DMSwarmFinalizeFieldRegister()
286d3a51819SDave May 
287d3a51819SDave May  . seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
288d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
289d3a51819SDave May @*/
2905f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm)
2915f50eb2eSDave May {
2925f50eb2eSDave May   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
2933454631fSDave May   PetscErrorCode ierr;
2943454631fSDave May 
295521f74f9SMatthew G. Knepley   PetscFunctionBegin;
296cc651181SDave May   if (!swarm->field_registration_initialized) {
2975f50eb2eSDave May     swarm->field_registration_initialized = PETSC_TRUE;
298f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */
299f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */
300cc651181SDave May   }
3015f50eb2eSDave May   PetscFunctionReturn(0);
3025f50eb2eSDave May }
3035f50eb2eSDave May 
304d3a51819SDave May /*@C
305d3a51819SDave May 
306d3a51819SDave May  DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm
307d3a51819SDave May 
308d3a51819SDave May  Collective on DM
309d3a51819SDave May 
310d3a51819SDave May  Input parameter:
311d3a51819SDave May  . dm - a DMSwarm
312d3a51819SDave May 
313d3a51819SDave May  Level: beginner
314d3a51819SDave May 
315d3a51819SDave May  Notes:
316d3a51819SDave May  After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined
317d3a51819SDave May  on the DMSwarm
318d3a51819SDave May 
319d3a51819SDave May  . seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
320d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
321d3a51819SDave May @*/
3225f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm)
3235f50eb2eSDave May {
3245f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3256845f8f5SDave May   PetscErrorCode ierr;
3266845f8f5SDave May 
327521f74f9SMatthew G. Knepley   PetscFunctionBegin;
328f0cdbbbaSDave May   if (!swarm->field_registration_finalized) {
3296845f8f5SDave May     ierr = DataBucketFinalize(swarm->db);CHKERRQ(ierr);
330f0cdbbbaSDave May   }
331f0cdbbbaSDave May   swarm->field_registration_finalized = PETSC_TRUE;
3325f50eb2eSDave May   PetscFunctionReturn(0);
3335f50eb2eSDave May }
3345f50eb2eSDave May 
335d3a51819SDave May /*@C
336d3a51819SDave May 
337d3a51819SDave May  DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm
338d3a51819SDave May 
339d3a51819SDave May  Not collective
340d3a51819SDave May 
341d3a51819SDave May  Input parameters:
342d3a51819SDave May  . dm - a DMSwarm
343d3a51819SDave May  . nlocal - the length of each registered field
344d3a51819SDave May  . buffer - the length of the buffer used to efficient dynamic re-sizing
345d3a51819SDave May 
346d3a51819SDave May  Level: beginner
347d3a51819SDave May 
348d3a51819SDave May  . seealso: DMSwarmGetLocalSize()
349d3a51819SDave May 
350d3a51819SDave May @*/
3515f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer)
3525f50eb2eSDave May {
3535f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3546845f8f5SDave May   PetscErrorCode ierr;
3555f50eb2eSDave May 
356521f74f9SMatthew G. Knepley   PetscFunctionBegin;
3576845f8f5SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr);
3585f50eb2eSDave May   PetscFunctionReturn(0);
3595f50eb2eSDave May }
3605f50eb2eSDave May 
361d3a51819SDave May /*@C
362d3a51819SDave May 
363d3a51819SDave May  DMSwarmSetCellDM - Attachs a DM to a DMSwarm
364d3a51819SDave May 
365d3a51819SDave May  Collective on DM
366d3a51819SDave May 
367d3a51819SDave May  Input parameters:
368d3a51819SDave May  . dm - a DMSwarm
369d3a51819SDave May  . dmcell - the DM to attach to the DMSwarm
370d3a51819SDave May 
371d3a51819SDave May  Level: beginner
372d3a51819SDave May 
373d3a51819SDave May  Notes:
374d3a51819SDave May  The attached DM (dmcell) will be queried for pointlocation and
375d3a51819SDave May  neighbor MPI-rank information if DMSwarmMigrate() is called
376d3a51819SDave May 
377d3a51819SDave May .seealso: DMSwarmGetCellDM(), DMSwarmMigrate()
378d3a51819SDave May @*/
379b16650c8SDave May PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell)
380b16650c8SDave May {
381b16650c8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
382521f74f9SMatthew G. Knepley 
383521f74f9SMatthew G. Knepley   PetscFunctionBegin;
384b16650c8SDave May   swarm->dmcell = dmcell;
385b16650c8SDave May   PetscFunctionReturn(0);
386b16650c8SDave May }
387b16650c8SDave May 
388d3a51819SDave May /*@C
389d3a51819SDave May 
390d3a51819SDave May  DMSwarmGetCellDM - Fetches the attached cell DM
391d3a51819SDave May 
392d3a51819SDave May  Collective on DM
393d3a51819SDave May 
394d3a51819SDave May  Input parameter:
395d3a51819SDave May  . dm - a DMSwarm
396d3a51819SDave May 
397d3a51819SDave May  Output parameter:
398d3a51819SDave May  . dmcell - the DM which was attached to the DMSwarm
399d3a51819SDave May 
400d3a51819SDave May  Level: beginner
401d3a51819SDave May 
402d3a51819SDave May  Notes:
403d3a51819SDave May  The attached DM (dmcell) will be queried for pointlocation and
404d3a51819SDave May  neighbor MPI-rank information if DMSwarmMigrate() is called
405d3a51819SDave May 
406d3a51819SDave May .seealso: DMSwarmSetCellDM()
407d3a51819SDave May @*/
408fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell)
409fe39f135SDave May {
410fe39f135SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
411521f74f9SMatthew G. Knepley 
412521f74f9SMatthew G. Knepley   PetscFunctionBegin;
413fe39f135SDave May   *dmcell = swarm->dmcell;
414fe39f135SDave May   PetscFunctionReturn(0);
415fe39f135SDave May }
416fe39f135SDave May 
417d3a51819SDave May /*@C
418d3a51819SDave May 
419d3a51819SDave May  DMSwarmGetLocalSize - Retrives the local length of fields registered
420d3a51819SDave May 
421d3a51819SDave May  Not collective
422d3a51819SDave May 
423d3a51819SDave May  Input parameter:
424d3a51819SDave May  . dm - a DMSwarm
425d3a51819SDave May 
426d3a51819SDave May  Output parameter:
427d3a51819SDave May  . nlocal - the length of each registered field
428d3a51819SDave May 
429d3a51819SDave May  Level: beginner
430d3a51819SDave May 
431d3a51819SDave May .seealso: DMSwarmSetLocalSizes()
432d3a51819SDave May @*/
433dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal)
434dcf43ee8SDave May {
435dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
436dcf43ee8SDave May   PetscErrorCode ierr;
437dcf43ee8SDave May 
438521f74f9SMatthew G. Knepley   PetscFunctionBegin;
439521f74f9SMatthew G. Knepley   if (nlocal) {ierr = DataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);}
440dcf43ee8SDave May   PetscFunctionReturn(0);
441dcf43ee8SDave May }
442dcf43ee8SDave May 
443d3a51819SDave May /*@C
444d3a51819SDave May 
445d3a51819SDave May  DMSwarmGetSize - Retrives the total length of fields registered
446d3a51819SDave May 
447d3a51819SDave May  Collective on DM
448d3a51819SDave May 
449d3a51819SDave May  Input parameter:
450d3a51819SDave May  . dm - a DMSwarm
451d3a51819SDave May 
452d3a51819SDave May  Output parameter:
453d3a51819SDave May  . n - the total length of each registered field
454d3a51819SDave May 
455d3a51819SDave May  Level: beginner
456d3a51819SDave May 
457d3a51819SDave May  Note:
458d3a51819SDave May  This calls MPI_Allreduce upon each call (inefficient but safe)
459d3a51819SDave May 
460d3a51819SDave May .seealso: DMSwarmGetLocalSize()
461d3a51819SDave May @*/
462dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n)
463dcf43ee8SDave May {
464dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
465dcf43ee8SDave May   PetscErrorCode ierr;
466dcf43ee8SDave May   PetscInt nlocal,ng;
467dcf43ee8SDave May 
468521f74f9SMatthew G. Knepley   PetscFunctionBegin;
469dcf43ee8SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
470dcf43ee8SDave May   ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
471dcf43ee8SDave May   if (n) { *n = ng; }
472dcf43ee8SDave May   PetscFunctionReturn(0);
473dcf43ee8SDave May }
474dcf43ee8SDave May 
475d3a51819SDave May /*@C
476d3a51819SDave May 
477d3a51819SDave May  DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm
478d3a51819SDave May 
479d3a51819SDave May  Collective on DM
480d3a51819SDave May 
481d3a51819SDave May  Input parameters:
482d3a51819SDave May  . dm - a DMSwarm
483d3a51819SDave May  . fieldname - the textual name to identify this field
484d3a51819SDave May  . blocksize - the number of each data type
485d3a51819SDave May  . type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG)
486d3a51819SDave May 
487d3a51819SDave May  Level: beginner
488d3a51819SDave May 
489d3a51819SDave May  Notes:
490d3a51819SDave May  The textual name for each registered field must be unique
491d3a51819SDave May 
492d3a51819SDave May .seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
493d3a51819SDave May @*/
4945f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
495b62e03f8SDave May {
4962eac95f8SDave May   PetscErrorCode ierr;
497b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
498b62e03f8SDave May   size_t size;
499b62e03f8SDave May 
500521f74f9SMatthew G. Knepley   PetscFunctionBegin;
5015f50eb2eSDave May   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
5025f50eb2eSDave May   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
5035f50eb2eSDave May 
5045f50eb2eSDave May   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5055f50eb2eSDave May   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5065f50eb2eSDave May   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5075f50eb2eSDave May   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5085f50eb2eSDave May   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
509b62e03f8SDave May 
5102ddcf43eSMatthew G. Knepley   ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr);
511b62e03f8SDave May   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
51252c3ed93SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
51352c3ed93SDave May   {
51452c3ed93SDave May     DataField gfield;
51552c3ed93SDave May 
51652c3ed93SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
51752c3ed93SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
51852c3ed93SDave May   }
519b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
520b62e03f8SDave May   PetscFunctionReturn(0);
521b62e03f8SDave May }
522b62e03f8SDave May 
523d3a51819SDave May /*@C
524d3a51819SDave May 
525d3a51819SDave May  DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm
526d3a51819SDave May 
527d3a51819SDave May  Collective on DM
528d3a51819SDave May 
529d3a51819SDave May  Input parameters:
530d3a51819SDave May  . dm - a DMSwarm
531d3a51819SDave May  . fieldname - the textual name to identify this field
532d3a51819SDave May  . size - the size in bytes of the user struct of each data type
533d3a51819SDave May 
534d3a51819SDave May  Level: beginner
535d3a51819SDave May 
536d3a51819SDave May  Notes:
537d3a51819SDave May  The textual name for each registered field must be unique
538d3a51819SDave May 
539d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField()
540d3a51819SDave May @*/
5415f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
542b62e03f8SDave May {
5432eac95f8SDave May   PetscErrorCode ierr;
544b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
545b62e03f8SDave May 
546521f74f9SMatthew G. Knepley   PetscFunctionBegin;
5472eac95f8SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
548b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
549b62e03f8SDave May   PetscFunctionReturn(0);
550b62e03f8SDave May }
551b62e03f8SDave May 
552d3a51819SDave May /*@C
553d3a51819SDave May 
554d3a51819SDave May  DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm
555d3a51819SDave May 
556d3a51819SDave May  Collective on DM
557d3a51819SDave May 
558d3a51819SDave May  Input parameters:
559d3a51819SDave May  . dm - a DMSwarm
560d3a51819SDave May  . fieldname - the textual name to identify this field
561d3a51819SDave May  . size - the size in bytes of the user data type
562d3a51819SDave May  . blocksize - the number of each data type
563d3a51819SDave May 
564d3a51819SDave May  Level: beginner
565d3a51819SDave May 
566d3a51819SDave May  Notes:
567d3a51819SDave May  The textual name for each registered field must be unique
568d3a51819SDave May 
569d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
570d3a51819SDave May @*/
571320740a0SDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize)
572b62e03f8SDave May {
573b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
5746845f8f5SDave May   PetscErrorCode ierr;
575b62e03f8SDave May 
576521f74f9SMatthew G. Knepley   PetscFunctionBegin;
577320740a0SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
578320740a0SDave May   {
579320740a0SDave May     DataField gfield;
580320740a0SDave May 
581320740a0SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
582320740a0SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
583320740a0SDave May   }
584b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
585b62e03f8SDave May   PetscFunctionReturn(0);
586b62e03f8SDave May }
587b62e03f8SDave May 
588d3a51819SDave May /*@C
589d3a51819SDave May 
590d3a51819SDave May  DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field
591d3a51819SDave May 
592d3a51819SDave May  Not collective
593d3a51819SDave May 
594d3a51819SDave May  Input parameters:
595d3a51819SDave May  . dm - a DMSwarm
596d3a51819SDave May  . fieldname - the textual name to identify this field
597d3a51819SDave May 
598d3a51819SDave May  Output parameters:
599d3a51819SDave May  . blocksize - the number of each data type
600d3a51819SDave May  . type - the data type
601d3a51819SDave May  . data - pointer to raw array
602d3a51819SDave May 
603d3a51819SDave May  Level: beginner
604d3a51819SDave May 
605d3a51819SDave May  Notes:
606d3a51819SDave May  The user must call DMSwarmRestoreField()
607d3a51819SDave May 
608d3a51819SDave May .seealso: DMSwarmRestoreField()
609d3a51819SDave May @*/
6105f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
611b62e03f8SDave May {
612b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
613b62e03f8SDave May   DataField gfield;
6142eac95f8SDave May   PetscErrorCode ierr;
615b62e03f8SDave May 
616521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6173454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
6182eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6196845f8f5SDave May   ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr);
6206845f8f5SDave May   ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr);
6211b1ea282SDave May   if (blocksize) {*blocksize = gfield->bs; }
622b5bcf523SDave May   if (type) { *type = gfield->petsc_type; }
623b62e03f8SDave May   PetscFunctionReturn(0);
624b62e03f8SDave May }
625b62e03f8SDave May 
626d3a51819SDave May /*@C
627d3a51819SDave May 
628d3a51819SDave May  DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field
629d3a51819SDave May 
630d3a51819SDave May  Not collective
631d3a51819SDave May 
632d3a51819SDave May  Input parameters:
633d3a51819SDave May  . dm - a DMSwarm
634d3a51819SDave May  . fieldname - the textual name to identify this field
635d3a51819SDave May 
636d3a51819SDave May  Output parameters:
637d3a51819SDave May  . blocksize - the number of each data type
638d3a51819SDave May  . type - the data type
639d3a51819SDave May  . data - pointer to raw array
640d3a51819SDave May 
641d3a51819SDave May  Level: beginner
642d3a51819SDave May 
643d3a51819SDave May  Notes:
644d3a51819SDave May  The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField()
645d3a51819SDave May 
646d3a51819SDave May .seealso: DMSwarmGetField()
647d3a51819SDave May @*/
6485f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(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 
654521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6552eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6566845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
657b62e03f8SDave May   if (data) *data = NULL;
658b62e03f8SDave May   PetscFunctionReturn(0);
659b62e03f8SDave May }
660b62e03f8SDave May 
661d3a51819SDave May /*@C
662d3a51819SDave May 
663d3a51819SDave May  DMSwarmAddPoint - Add space for one new point in the DMSwarm
664d3a51819SDave May 
665d3a51819SDave May  Not collective
666d3a51819SDave May 
667d3a51819SDave May  Input parameter:
668d3a51819SDave May  . dm - a DMSwarm
669d3a51819SDave May 
670d3a51819SDave May  Level: beginner
671d3a51819SDave May 
672d3a51819SDave May  Notes:
673d3a51819SDave May  The new point will have all fields initialized to zero
674d3a51819SDave May 
675d3a51819SDave May .seealso: DMSwarmAddNPoints()
676d3a51819SDave May @*/
677cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
678cb1d1399SDave May {
679cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
680cb1d1399SDave May   PetscErrorCode ierr;
681cb1d1399SDave May 
682521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6833454631fSDave May   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
684cb1d1399SDave May   ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr);
685cb1d1399SDave May   PetscFunctionReturn(0);
686cb1d1399SDave May }
687cb1d1399SDave May 
688d3a51819SDave May /*@C
689d3a51819SDave May 
690d3a51819SDave May  DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm
691d3a51819SDave May 
692d3a51819SDave May  Not collective
693d3a51819SDave May 
694d3a51819SDave May  Input parameters:
695d3a51819SDave May  . dm - a DMSwarm
696d3a51819SDave May  . npoints - the number of new points to add
697d3a51819SDave May 
698d3a51819SDave May  Level: beginner
699d3a51819SDave May 
700d3a51819SDave May  Notes:
701d3a51819SDave May  The new point will have all fields initialized to zero
702d3a51819SDave May 
703d3a51819SDave May .seealso: DMSwarmAddPoint()
704d3a51819SDave May @*/
705cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
706cb1d1399SDave May {
707cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
708cb1d1399SDave May   PetscErrorCode ierr;
709cb1d1399SDave May   PetscInt nlocal;
710cb1d1399SDave May 
711521f74f9SMatthew G. Knepley   PetscFunctionBegin;
712cb1d1399SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
713cb1d1399SDave May   nlocal = nlocal + npoints;
714cb1d1399SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,-1);CHKERRQ(ierr);
715cb1d1399SDave May   PetscFunctionReturn(0);
716cb1d1399SDave May }
717cb1d1399SDave May 
718d3a51819SDave May /*@C
719d3a51819SDave May 
720d3a51819SDave May  DMSwarmRemovePoint - Remove the last point from the DMSwarm
721d3a51819SDave May 
722d3a51819SDave May  Not collective
723d3a51819SDave May 
724d3a51819SDave May  Input parameter:
725d3a51819SDave May  . dm - a DMSwarm
726d3a51819SDave May 
727d3a51819SDave May  Level: beginner
728d3a51819SDave May 
729d3a51819SDave May .seealso: DMSwarmRemovePointAtIndex()
730d3a51819SDave May @*/
731cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
732cb1d1399SDave May {
733cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
734cb1d1399SDave May   PetscErrorCode ierr;
735cb1d1399SDave May 
736521f74f9SMatthew G. Knepley   PetscFunctionBegin;
737cb1d1399SDave May   ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
738cb1d1399SDave May   PetscFunctionReturn(0);
739cb1d1399SDave May }
740cb1d1399SDave May 
741d3a51819SDave May /*@C
742d3a51819SDave May  DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm
743d3a51819SDave May 
744d3a51819SDave May  Not collective
745d3a51819SDave May 
746d3a51819SDave May  Input parameters:
747d3a51819SDave May  . dm - a DMSwarm
748d3a51819SDave May  . idx - index of point to remove
749d3a51819SDave May 
750d3a51819SDave May  Level: beginner
751d3a51819SDave May 
752d3a51819SDave May .seealso: DMSwarmRemovePoint()
753d3a51819SDave May @*/
754cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
755cb1d1399SDave May {
756cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
757cb1d1399SDave May   PetscErrorCode ierr;
758cb1d1399SDave May 
759521f74f9SMatthew G. Knepley   PetscFunctionBegin;
760cb1d1399SDave May   ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
761cb1d1399SDave May   PetscFunctionReturn(0);
762cb1d1399SDave May }
763b62e03f8SDave May 
764095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points)
7653454631fSDave May {
766dcf43ee8SDave May   PetscErrorCode ierr;
767521f74f9SMatthew G. Knepley 
768521f74f9SMatthew G. Knepley   PetscFunctionBegin;
769dcf43ee8SDave May   ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr);
7703454631fSDave May   PetscFunctionReturn(0);
7713454631fSDave May }
7723454631fSDave May 
773d3a51819SDave May /*@C
774d3a51819SDave May 
775d3a51819SDave May  DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks
776d3a51819SDave May 
777d3a51819SDave May  Collective on DM
778d3a51819SDave May 
779d3a51819SDave May  Input parameters:
780d3a51819SDave May  . dm - the DMSwarm
781d3a51819SDave May  . remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank
782d3a51819SDave May 
783d3a51819SDave May  Notes:
784d3a51819SDave May  The DM wil be modified to accomodate received points.
785d3a51819SDave May  If remove_sent_points = PETSC_TRUE, send points will be removed from the DM
786d3a51819SDave May  Different styles of migration are supported. See DMSwarmSetMigrateType()
787d3a51819SDave May 
788d3a51819SDave May  Level: advanced
789d3a51819SDave May 
790d3a51819SDave May .seealso: DMSwarmSetMigrateType()
791d3a51819SDave May @*/
792095059a4SDave May PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points)
7933454631fSDave May {
794f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
7953454631fSDave May   PetscErrorCode ierr;
796f0cdbbbaSDave May 
797521f74f9SMatthew G. Knepley   PetscFunctionBegin;
798f0cdbbbaSDave May   switch (swarm->migrate_type) {
799f0cdbbbaSDave May     case DMSWARM_MIGRATE_BASIC:
800095059a4SDave May       ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr);
801f0cdbbbaSDave May       break;
802f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLNSCATTER:
803f0cdbbbaSDave May       ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr);
804f0cdbbbaSDave May       break;
805f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLEXACT:
806f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented");
807521f74f9SMatthew G. Knepley       /*ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr);*/
808f0cdbbbaSDave May       break;
809f0cdbbbaSDave May     case DMSWARM_MIGRATE_USER:
810f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented");
811521f74f9SMatthew G. Knepley       /*ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr);*/
812f0cdbbbaSDave May       break;
813f0cdbbbaSDave May     default:
814f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown");
815f0cdbbbaSDave May       break;
816f0cdbbbaSDave May   }
8173454631fSDave May   PetscFunctionReturn(0);
8183454631fSDave May }
8193454631fSDave May 
820f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize);
821f0cdbbbaSDave May 
822d3a51819SDave May /*
823d3a51819SDave May  DMSwarmCollectViewCreate
824d3a51819SDave May 
825d3a51819SDave May  * Applies a collection method and gathers point neighbour points into dm
826d3a51819SDave May 
827d3a51819SDave May  Notes:
828d3a51819SDave May  - Users should call DMSwarmCollectViewDestroy() after
829d3a51819SDave May  they have finished computations associated with the collected points
830d3a51819SDave May */
831d3a51819SDave May 
832d3a51819SDave May /*@C
833d3a51819SDave May 
834d3a51819SDave May  DMSwarmCollectViewCreate - Applies a collection method and gathers points
835d3a51819SDave May  in neighbour MPI-ranks into the DMSwarm
836d3a51819SDave May 
837d3a51819SDave May  Collective on DM
838d3a51819SDave May 
839d3a51819SDave May  Input parameter:
840d3a51819SDave May  . dm - the DMSwarm
841d3a51819SDave May 
842d3a51819SDave May  Notes:
843d3a51819SDave May  Users should call DMSwarmCollectViewDestroy() after
844d3a51819SDave May  they have finished computations associated with the collected points
845d3a51819SDave May  Different collect methods are supported. See DMSwarmSetCollectType()
846d3a51819SDave May 
847d3a51819SDave May  Level: advanced
848d3a51819SDave May 
849d3a51819SDave May .seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType()
850d3a51819SDave May @*/
851fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm)
8522712d1f2SDave May {
8532712d1f2SDave May   PetscErrorCode ierr;
8542712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8552712d1f2SDave May   PetscInt ng;
8562712d1f2SDave May 
857521f74f9SMatthew G. Knepley   PetscFunctionBegin;
858480eef7bSDave May   if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active");
859480eef7bSDave May   ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr);
860480eef7bSDave May   switch (swarm->collect_type) {
861f0cdbbbaSDave May 
862480eef7bSDave May     case DMSWARM_COLLECT_BASIC:
8632712d1f2SDave May       ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr);
864480eef7bSDave May       break;
865480eef7bSDave May     case DMSWARM_COLLECT_DMDABOUNDINGBOX:
866f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented");
867521f74f9SMatthew G. Knepley       /*ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr);*/
868480eef7bSDave May       break;
869480eef7bSDave May     case DMSWARM_COLLECT_GENERAL:
870f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented");
871521f74f9SMatthew G. Knepley       /*ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr);*/
872480eef7bSDave May       break;
873480eef7bSDave May     default:
874f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown");
875480eef7bSDave May       break;
876480eef7bSDave May   }
877480eef7bSDave May   swarm->collect_view_active = PETSC_TRUE;
878480eef7bSDave May   swarm->collect_view_reset_nlocal = ng;
8792712d1f2SDave May   PetscFunctionReturn(0);
8802712d1f2SDave May }
8812712d1f2SDave May 
882d3a51819SDave May /*@C
883d3a51819SDave May 
884d3a51819SDave May  DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate()
885d3a51819SDave May 
886d3a51819SDave May  Collective on DM
887d3a51819SDave May 
888d3a51819SDave May  Input parameters:
889d3a51819SDave May  . dm - the DMSwarm
890d3a51819SDave May 
891d3a51819SDave May  Notes:
892d3a51819SDave May  Users should call DMSwarmCollectViewCreate() before this function is called.
893d3a51819SDave May 
894d3a51819SDave May  Level: advanced
895d3a51819SDave May 
896d3a51819SDave May .seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType()
897d3a51819SDave May @*/
898fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm)
8992712d1f2SDave May {
9002712d1f2SDave May   PetscErrorCode ierr;
9012712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9022712d1f2SDave May 
903521f74f9SMatthew G. Knepley   PetscFunctionBegin;
904480eef7bSDave May   if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active");
905480eef7bSDave May   ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr);
906480eef7bSDave May   swarm->collect_view_active = PETSC_FALSE;
9072712d1f2SDave May   PetscFunctionReturn(0);
9082712d1f2SDave May }
9093454631fSDave May 
910f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm)
911f0cdbbbaSDave May {
912f0cdbbbaSDave May   PetscInt dim;
913f0cdbbbaSDave May   PetscErrorCode ierr;
914f0cdbbbaSDave May 
915521f74f9SMatthew G. Knepley   PetscFunctionBegin;
916f0cdbbbaSDave May   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
917f0cdbbbaSDave May   if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
918f0cdbbbaSDave May   if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
919f0cdbbbaSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr);
920*e2d107dbSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_cellid,1,PETSC_INT);CHKERRQ(ierr);
921f0cdbbbaSDave May   PetscFunctionReturn(0);
922f0cdbbbaSDave May }
923f0cdbbbaSDave May 
924d3a51819SDave May /*@C
925d3a51819SDave May 
926d3a51819SDave May  DMSwarmSetType - Set particular flavor of DMSwarm
927d3a51819SDave May 
928d3a51819SDave May  Collective on DM
929d3a51819SDave May 
930d3a51819SDave May  Input parameters:
931d3a51819SDave May . dm - the DMSwarm
932d3a51819SDave May . stype - the DMSwarm type (e.g. DMSWARM_PIC)
933d3a51819SDave May 
934d3a51819SDave May  Level: advanced
935d3a51819SDave May 
936d3a51819SDave May .seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType()
937d3a51819SDave May @*/
938f0cdbbbaSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype)
939f0cdbbbaSDave May {
940f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
941f0cdbbbaSDave May   PetscErrorCode ierr;
942f0cdbbbaSDave May 
943521f74f9SMatthew G. Knepley   PetscFunctionBegin;
944f0cdbbbaSDave May   swarm->swarm_type = stype;
945f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
946f0cdbbbaSDave May     ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr);
947f0cdbbbaSDave May   }
948f0cdbbbaSDave May   PetscFunctionReturn(0);
949f0cdbbbaSDave May }
950f0cdbbbaSDave May 
9513454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm)
9523454631fSDave May {
9533454631fSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9543454631fSDave May   PetscErrorCode ierr;
9553454631fSDave May   PetscMPIInt rank;
9563454631fSDave May   PetscInt p,npoints,*rankval;
9573454631fSDave May 
958521f74f9SMatthew G. Knepley   PetscFunctionBegin;
9593454631fSDave May   if (swarm->issetup) PetscFunctionReturn(0);
9603454631fSDave May 
9613454631fSDave May   swarm->issetup = PETSC_TRUE;
9623454631fSDave May 
963f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
964f0cdbbbaSDave May     /* check dmcell exists */
965f0cdbbbaSDave May     if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM");
966f0cdbbbaSDave May 
967f0cdbbbaSDave May     if (swarm->dmcell->ops->locatepointssubdomain) {
968f0cdbbbaSDave May       /* check methods exists for exact ownership identificiation */
969521f74f9SMatthew G. Knepley       ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");CHKERRQ(ierr);
970f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT;
971f0cdbbbaSDave May     } else {
972f0cdbbbaSDave May       /* check methods exist for point location AND rank neighbor identification */
973f0cdbbbaSDave May       if (swarm->dmcell->ops->locatepoints) {
974521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->LocatePoints\n");CHKERRQ(ierr);
975f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined");
976f0cdbbbaSDave May 
977f0cdbbbaSDave May       if (swarm->dmcell->ops->getneighbors) {
978521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->GetNeigbors\n");CHKERRQ(ierr);
979f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined");
980f0cdbbbaSDave May 
981f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER;
982f0cdbbbaSDave May     }
983f0cdbbbaSDave May   }
984f0cdbbbaSDave May 
985f0cdbbbaSDave May   ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr);
986f0cdbbbaSDave May 
9873454631fSDave May   /* check some fields were registered */
9883454631fSDave May   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
9893454631fSDave May 
9903454631fSDave May   /* check local sizes were set */
9913454631fSDave May   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
9923454631fSDave May 
9933454631fSDave May   /* initialize values in pid and rank placeholders */
9943454631fSDave May   /* TODO: [pid - use MPI_Scan] */
9953454631fSDave May   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
9963454631fSDave May   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
997f0cdbbbaSDave May   ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
9983454631fSDave May   for (p=0; p<npoints; p++) {
9993454631fSDave May     rankval[p] = (PetscInt)rank;
10003454631fSDave May   }
1001f0cdbbbaSDave May   ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10023454631fSDave May   PetscFunctionReturn(0);
10033454631fSDave May }
10043454631fSDave May 
100557795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm)
100657795646SDave May {
100757795646SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
100857795646SDave May   PetscErrorCode ierr;
100957795646SDave May 
101057795646SDave May   PetscFunctionBegin;
10116845f8f5SDave May   ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr);
101257795646SDave May   ierr = PetscFree(swarm);CHKERRQ(ierr);
101357795646SDave May   PetscFunctionReturn(0);
101457795646SDave May }
101557795646SDave May 
1016a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer)
1017a9ee3421SMatthew G. Knepley {
1018a9ee3421SMatthew G. Knepley   DM             cdm;
1019a9ee3421SMatthew G. Knepley   PetscDraw      draw;
1020a9ee3421SMatthew G. Knepley   PetscReal     *coords, oldPause;
1021a9ee3421SMatthew G. Knepley   PetscInt       Np, p, bs;
1022a9ee3421SMatthew G. Knepley   PetscErrorCode ierr;
1023a9ee3421SMatthew G. Knepley 
1024a9ee3421SMatthew G. Knepley   PetscFunctionBegin;
1025a9ee3421SMatthew G. Knepley   ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr);
1026a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr);
1027a9ee3421SMatthew G. Knepley   ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr);
1028a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr);
1029a9ee3421SMatthew G. Knepley   ierr = DMView(cdm, viewer);CHKERRQ(ierr);
1030a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr);
1031a9ee3421SMatthew G. Knepley 
1032a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr);
1033a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1034a9ee3421SMatthew G. Knepley   for (p = 0; p < Np; ++p) {
1035a9ee3421SMatthew G. Knepley     const PetscInt i = p*bs;
1036a9ee3421SMatthew G. Knepley 
1037a9ee3421SMatthew G. Knepley     ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], 0.01, 0.01, PETSC_DRAW_BLUE);CHKERRQ(ierr);
1038a9ee3421SMatthew G. Knepley   }
1039a9ee3421SMatthew G. Knepley   ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1040a9ee3421SMatthew G. Knepley   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
1041a9ee3421SMatthew G. Knepley   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
1042a9ee3421SMatthew G. Knepley   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1043a9ee3421SMatthew G. Knepley   PetscFunctionReturn(0);
1044a9ee3421SMatthew G. Knepley }
1045a9ee3421SMatthew G. Knepley 
10465f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
10475f50eb2eSDave May {
10485f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1049a9ee3421SMatthew G. Knepley   PetscBool      iascii,ibinary,ishdf5,isvtk,isdraw;
10505f50eb2eSDave May   PetscErrorCode ierr;
10515f50eb2eSDave May 
10525f50eb2eSDave May   PetscFunctionBegin;
10535f50eb2eSDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10545f50eb2eSDave May   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
10555f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
10565f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
10575f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
10585f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1059a9ee3421SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW,  &isdraw);CHKERRQ(ierr);
10605f50eb2eSDave May   if (iascii) {
10616845f8f5SDave May     ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
10625f50eb2eSDave May   } else if (ibinary) {
1063a9ee3421SMatthew G. Knepley     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support");
10645f50eb2eSDave May   } else if (ishdf5) {
10655f50eb2eSDave May #if defined(PETSC_HAVE_HDF5)
10665f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
10675f50eb2eSDave May #else
10685f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
10695f50eb2eSDave May #endif
10705f50eb2eSDave May   } else if (isvtk) {
10715f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
1072a9ee3421SMatthew G. Knepley   } else if (isdraw) {
1073a9ee3421SMatthew G. Knepley     ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr);
10745f50eb2eSDave May   }
10755f50eb2eSDave May   PetscFunctionReturn(0);
10765f50eb2eSDave May }
10775f50eb2eSDave May 
1078d3a51819SDave May /*MC
1079d3a51819SDave May 
1080d3a51819SDave May  DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type.
1081d3a51819SDave May  This implementation was designed for particle-in-cell type methods in which the underlying
1082d3a51819SDave May  data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type.
1083d3a51819SDave May 
1084d3a51819SDave May  User data can be represented by DMSwarm through a registring "fields".
1085d3a51819SDave May  To register a field, the user must provide:
1086d3a51819SDave May  (a) a unique name
1087d3a51819SDave May  (b) the data type (or size in bytes)
1088d3a51819SDave May  (c) the block size of the data
1089d3a51819SDave May 
1090d3a51819SDave May  For example, suppose the application requires a unique id, energy, momentum and density to be stored
1091d3a51819SDave May  on a set of of particles. Then the following application could be used
1092d3a51819SDave May 
1093d3a51819SDave May  DMSwarmInitializeFieldRegister(dm)
1094d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG);
1095d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL);
1096d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL);
1097d3a51819SDave May  DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT);
1098d3a51819SDave May  DMSwarmFinalizeFieldRegister(dm)
1099d3a51819SDave May 
1100d3a51819SDave May  The fields represented by DMSwarm are dynamic and can be re-sized at any time.
1101d3a51819SDave May  The only restriction imposed by DMSwarm is that all fields contain the same number of points
1102d3a51819SDave May 
1103d3a51819SDave May  To support particle methods, "migration" techniques are provided. These methods migrate data
1104d3a51819SDave May  between MPI-ranks.
1105d3a51819SDave May 
1106d3a51819SDave May  DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector().
1107d3a51819SDave May  As a DMSwarm may internally define and store values of different data types,
1108d3a51819SDave May  before calling DMCreate{Global/Local}Vector() the user must inform DMSwarm which
1109d3a51819SDave May  fields should be used to define a Vec object via
1110d3a51819SDave May    DMSwarmVectorDefineField()
1111d3a51819SDave May  The specified field can can changed be changed at any time - thereby permitting vectors
1112d3a51819SDave May  compatable with different fields to be created.
1113d3a51819SDave May 
1114d3a51819SDave May  A dual representation of fields in the DMSwarm and a Vec object are permitted via
1115d3a51819SDave May    DMSwarmCreateGlobalVectorFromField()
1116d3a51819SDave May  Here the data defining the field in the DMSwarm is shared with a Vec.
1117d3a51819SDave May  This is inherently unsafe if you alter the size of the field at any time between
1118d3a51819SDave May  calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField().
1119cc651181SDave May  If the local size of the DMSwarm does not match the localsize of the global vector
1120cc651181SDave May  when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown.
1121d3a51819SDave May 
1122d3a51819SDave May  Level: beginner
1123d3a51819SDave May 
1124d3a51819SDave May .seealso: DMType, DMCreate(), DMSetType()
1125d3a51819SDave May M*/
112657795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
112757795646SDave May {
112857795646SDave May   DM_Swarm      *swarm;
112957795646SDave May   PetscErrorCode ierr;
113057795646SDave May 
113157795646SDave May   PetscFunctionBegin;
113257795646SDave May   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
113357795646SDave May   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
1134f0cdbbbaSDave May   dm->data = swarm;
113557795646SDave May 
11366845f8f5SDave May   ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr);
1137f0cdbbbaSDave May   ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr);
1138f0cdbbbaSDave May 
1139b5bcf523SDave May   swarm->vec_field_set = PETSC_FALSE;
11403454631fSDave May   swarm->issetup = PETSC_FALSE;
1141480eef7bSDave May   swarm->swarm_type = DMSWARM_BASIC;
1142480eef7bSDave May   swarm->migrate_type = DMSWARM_MIGRATE_BASIC;
1143480eef7bSDave May   swarm->collect_type = DMSWARM_COLLECT_BASIC;
114440c453e9SDave May   swarm->migrate_error_on_missing_point = PETSC_FALSE;
1145b62e03f8SDave May 
1146f0cdbbbaSDave May   swarm->dmcell = NULL;
1147f0cdbbbaSDave May   swarm->collect_view_active = PETSC_FALSE;
1148f0cdbbbaSDave May   swarm->collect_view_reset_nlocal = -1;
114957795646SDave May 
1150f0cdbbbaSDave May   dm->dim  = 0;
11515f50eb2eSDave May   dm->ops->view                            = DMView_Swarm;
115257795646SDave May   dm->ops->load                            = NULL;
115357795646SDave May   dm->ops->setfromoptions                  = NULL;
115457795646SDave May   dm->ops->clone                           = NULL;
11553454631fSDave May   dm->ops->setup                           = DMSetup_Swarm;
115657795646SDave May   dm->ops->createdefaultsection            = NULL;
115757795646SDave May   dm->ops->createdefaultconstraints        = NULL;
1158b5bcf523SDave May   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
1159b5bcf523SDave May   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
116057795646SDave May   dm->ops->getlocaltoglobalmapping         = NULL;
116157795646SDave May   dm->ops->createfieldis                   = NULL;
116257795646SDave May   dm->ops->createcoordinatedm              = NULL;
116357795646SDave May   dm->ops->getcoloring                     = NULL;
116457795646SDave May   dm->ops->creatematrix                    = NULL;
116557795646SDave May   dm->ops->createinterpolation             = NULL;
116657795646SDave May   dm->ops->getaggregates                   = NULL;
116757795646SDave May   dm->ops->getinjection                    = NULL;
116857795646SDave May   dm->ops->refine                          = NULL;
116957795646SDave May   dm->ops->coarsen                         = NULL;
117057795646SDave May   dm->ops->refinehierarchy                 = NULL;
117157795646SDave May   dm->ops->coarsenhierarchy                = NULL;
117257795646SDave May   dm->ops->globaltolocalbegin              = NULL;
117357795646SDave May   dm->ops->globaltolocalend                = NULL;
117457795646SDave May   dm->ops->localtoglobalbegin              = NULL;
117557795646SDave May   dm->ops->localtoglobalend                = NULL;
117657795646SDave May   dm->ops->destroy                         = DMDestroy_Swarm;
117757795646SDave May   dm->ops->createsubdm                     = NULL;
117857795646SDave May   dm->ops->getdimpoints                    = NULL;
117957795646SDave May   dm->ops->locatepoints                    = NULL;
118057795646SDave May   PetscFunctionReturn(0);
118157795646SDave May }
1182