xref: /petsc/src/dm/impls/swarm/swarm.c (revision dc5f5ce9c59c5163bf2263800eaf93c7e75f06cf)
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
1762741f57SDave May    DMSwarmVectorDefineField - Sets the field from which to define a Vec object
1862741f57SDave May                              when DMCreateLocalVector(), or DMCreateGlobalVector() is called
1957795646SDave May 
20d3a51819SDave May    Collective on DM
2157795646SDave May 
22d3a51819SDave May    Input parameters:
2362741f57SDave May +  dm - a DMSwarm
2462741f57SDave May -  fieldname - the textual name given to a registered field
2557795646SDave May 
26d3a51819SDave May    Level: beginner
2757795646SDave May 
28d3a51819SDave May    Notes:
2962741f57SDave 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 
338b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMCreateGlobalVector(), DMCreateLocalVector()
34d3a51819SDave May @*/
35b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmVectorDefineField(DM dm,const char fieldname[])
36b5bcf523SDave May {
37b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
38b5bcf523SDave May   PetscErrorCode ierr;
39b5bcf523SDave May   PetscInt bs,n;
40b5bcf523SDave May   PetscScalar *array;
41b5bcf523SDave May   PetscDataType type;
42b5bcf523SDave May 
43a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
443454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
456845f8f5SDave May   ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr);
46b5bcf523SDave May   ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
47b5bcf523SDave May 
48b5bcf523SDave May   /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */
49b5bcf523SDave May   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL");
50521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(swarm->vec_field_name,PETSC_MAX_PATH_LEN-1,"%s",fieldname);CHKERRQ(ierr);
51b5bcf523SDave May   swarm->vec_field_set = PETSC_TRUE;
521b1ea282SDave May   swarm->vec_field_bs = bs;
53b5bcf523SDave May   swarm->vec_field_nlocal = n;
54dcf43ee8SDave May   ierr = DMSwarmRestoreField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
55b5bcf523SDave May   PetscFunctionReturn(0);
56b5bcf523SDave May }
57b5bcf523SDave May 
58cc651181SDave May /* requires DMSwarmDefineFieldVector has been called */
59b5bcf523SDave May PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec)
60b5bcf523SDave May {
61b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
62b5bcf523SDave May   PetscErrorCode ierr;
63b5bcf523SDave May   Vec x;
64b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
65b5bcf523SDave May 
66a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
673454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
68b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
69cc651181SDave 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 */
70cc651181SDave May 
71521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr);
72b5bcf523SDave May   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr);
73b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
741b1ea282SDave May   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr);
75b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
76b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
77b5bcf523SDave May   *vec = x;
78b5bcf523SDave May   PetscFunctionReturn(0);
79b5bcf523SDave May }
80b5bcf523SDave May 
81b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */
82b5bcf523SDave May PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec)
83b5bcf523SDave May {
84b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
85b5bcf523SDave May   PetscErrorCode ierr;
86b5bcf523SDave May   Vec x;
87b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
88b5bcf523SDave May 
89a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
903454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
91b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
92cc651181SDave 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 */
93cc651181SDave May 
94521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr);
95b5bcf523SDave May   ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr);
96b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
97071900c8SMatthew G. Knepley   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr);
98b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
99b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
100b5bcf523SDave May   *vec = x;
101b5bcf523SDave May   PetscFunctionReturn(0);
102b5bcf523SDave May }
103b5bcf523SDave May 
104fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmDestroyVectorFromField_Private(DM dm, const char fieldname[], Vec *vec)
105fb1bcc12SMatthew G. Knepley {
106fb1bcc12SMatthew G. Knepley   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
107fb1bcc12SMatthew G. Knepley   DataField      gfield;
108fb1bcc12SMatthew G. Knepley   void         (*fptr)(void);
109fb1bcc12SMatthew G. Knepley   PetscInt       bs, nlocal;
110fb1bcc12SMatthew G. Knepley   char           name[PETSC_MAX_PATH_LEN];
111fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
112d3a51819SDave May 
113fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
114fb1bcc12SMatthew G. Knepley   ierr = VecGetLocalSize(*vec, &nlocal);CHKERRQ(ierr);
115fb1bcc12SMatthew G. Knepley   ierr = VecGetBlockSize(*vec, &bs);CHKERRQ(ierr);
116fb1bcc12SMatthew 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 */
117fb1bcc12SMatthew G. Knepley   ierr = DataBucketGetDataFieldByName(swarm->db, fieldname, &gfield);CHKERRQ(ierr);
118fb1bcc12SMatthew G. Knepley   /* check vector is an inplace array */
119521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr);
120fb1bcc12SMatthew G. Knepley   ierr = PetscObjectQueryFunction((PetscObject) *vec, name, &fptr);CHKERRQ(ierr);
121fb1bcc12SMatthew G. Knepley   if (!fptr) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Vector being destroyed was not created from DMSwarm field(%s)", fieldname);
122fb1bcc12SMatthew G. Knepley   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
123fb1bcc12SMatthew G. Knepley   ierr = VecDestroy(vec);CHKERRQ(ierr);
124fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
125fb1bcc12SMatthew G. Knepley }
126fb1bcc12SMatthew G. Knepley 
127fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmCreateVectorFromField_Private(DM dm, const char fieldname[], MPI_Comm comm, Vec *vec)
128fb1bcc12SMatthew G. Knepley {
129fb1bcc12SMatthew G. Knepley   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
130fb1bcc12SMatthew G. Knepley   PetscDataType  type;
131fb1bcc12SMatthew G. Knepley   PetscScalar   *array;
132fb1bcc12SMatthew G. Knepley   PetscInt       bs, n;
133fb1bcc12SMatthew G. Knepley   char           name[PETSC_MAX_PATH_LEN];
134fb1bcc12SMatthew G. Knepley   PetscMPIInt    commsize;
135fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
136fb1bcc12SMatthew G. Knepley 
137fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
138fb1bcc12SMatthew G. Knepley   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
139fb1bcc12SMatthew G. Knepley   ierr = DataBucketGetSizes(swarm->db, &n, NULL, NULL);CHKERRQ(ierr);
140fb1bcc12SMatthew G. Knepley   ierr = DMSwarmGetField(dm, fieldname, &bs, &type, (void **) &array);CHKERRQ(ierr);
141fb1bcc12SMatthew G. Knepley   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Only valid for PETSC_REAL");
142fb1bcc12SMatthew G. Knepley 
143fb1bcc12SMatthew G. Knepley   ierr = MPI_Comm_size(comm, &commsize);CHKERRQ(ierr);
144fb1bcc12SMatthew G. Knepley   if (commsize == 1) {
145fb1bcc12SMatthew G. Knepley     ierr = VecCreateSeqWithArray(comm, bs, n*bs, array, vec);CHKERRQ(ierr);
146fb1bcc12SMatthew G. Knepley   } else {
147fb1bcc12SMatthew G. Knepley     ierr = VecCreateMPIWithArray(comm, bs, n*bs, PETSC_DETERMINE, array, vec);CHKERRQ(ierr);
148fb1bcc12SMatthew G. Knepley   }
149fb1bcc12SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarmSharedField_%s", fieldname);CHKERRQ(ierr);
150fb1bcc12SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) *vec, name);CHKERRQ(ierr);
151fb1bcc12SMatthew G. Knepley 
152fb1bcc12SMatthew G. Knepley   /* Set guard */
153fb1bcc12SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr);
154fb1bcc12SMatthew G. Knepley   ierr = PetscObjectComposeFunction((PetscObject) *vec, name, DMSwarmDestroyVectorFromField_Private);CHKERRQ(ierr);
155fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
156fb1bcc12SMatthew G. Knepley }
157fb1bcc12SMatthew G. Knepley 
158fb1bcc12SMatthew G. Knepley /*@C
159d3a51819SDave May    DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field
160d3a51819SDave May 
161d3a51819SDave May    Collective on DM
162d3a51819SDave May 
163d3a51819SDave May    Input parameters:
16462741f57SDave May +  dm - a DMSwarm
16562741f57SDave May -  fieldname - the textual name given to a registered field
166d3a51819SDave May 
1678b8a3813SDave May    Output parameter:
168d3a51819SDave May .  vec - the vector
169d3a51819SDave May 
170d3a51819SDave May    Level: beginner
171d3a51819SDave May 
1728b8a3813SDave May    Notes:
1738b8a3813SDave May    The vector must be returned using a matching call to DMSwarmDestroyGlobalVectorFromField().
1748b8a3813SDave May 
1758b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyGlobalVectorFromField()
176d3a51819SDave May @*/
177b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
178b5bcf523SDave May {
179fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PetscObjectComm((PetscObject) dm);
180b5bcf523SDave May   PetscErrorCode ierr;
181b5bcf523SDave May 
182fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
183fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
184b5bcf523SDave May   PetscFunctionReturn(0);
185b5bcf523SDave May }
186b5bcf523SDave May 
187d3a51819SDave May /*@C
188d3a51819SDave May    DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field
189d3a51819SDave May 
190d3a51819SDave May    Collective on DM
191d3a51819SDave May 
192d3a51819SDave May    Input parameters:
19362741f57SDave May +  dm - a DMSwarm
19462741f57SDave May -  fieldname - the textual name given to a registered field
195d3a51819SDave May 
1968b8a3813SDave May    Output parameter:
197d3a51819SDave May .  vec - the vector
198d3a51819SDave May 
199d3a51819SDave May    Level: beginner
200d3a51819SDave May 
2018b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateGlobalVectorFromField()
202d3a51819SDave May @*/
203b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
204b5bcf523SDave May {
205b5bcf523SDave May   PetscErrorCode ierr;
206cc651181SDave May 
207fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
208fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
209b5bcf523SDave May   PetscFunctionReturn(0);
210b5bcf523SDave May }
211b5bcf523SDave May 
212fb1bcc12SMatthew G. Knepley /*@C
213fb1bcc12SMatthew G. Knepley    DMSwarmCreateLocalVectorFromField - Creates a Vec object sharing the array associated with a given field
214fb1bcc12SMatthew G. Knepley 
215fb1bcc12SMatthew G. Knepley    Collective on DM
216fb1bcc12SMatthew G. Knepley 
217fb1bcc12SMatthew G. Knepley    Input parameters:
21862741f57SDave May +  dm - a DMSwarm
21962741f57SDave May -  fieldname - the textual name given to a registered field
220fb1bcc12SMatthew G. Knepley 
2218b8a3813SDave May    Output parameter:
222fb1bcc12SMatthew G. Knepley .  vec - the vector
223fb1bcc12SMatthew G. Knepley 
224fb1bcc12SMatthew G. Knepley    Level: beginner
225fb1bcc12SMatthew G. Knepley 
2268b8a3813SDave May    Notes:
2278b8a3813SDave May    The vector must be returned using a matching call to DMSwarmDestroyLocalVectorFromField().
2288b8a3813SDave May 
2298b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyLocalVectorFromField()
230fb1bcc12SMatthew G. Knepley @*/
231fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmCreateLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
232bbe8250bSMatthew G. Knepley {
233fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PETSC_COMM_SELF;
234bbe8250bSMatthew G. Knepley   PetscErrorCode ierr;
235bbe8250bSMatthew G. Knepley 
236fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
237fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
238fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
239bbe8250bSMatthew G. Knepley }
240fb1bcc12SMatthew G. Knepley 
241fb1bcc12SMatthew G. Knepley /*@C
242fb1bcc12SMatthew G. Knepley    DMSwarmDestroyLocalVectorFromField - Destroys the Vec object which share the array associated with a given field
243fb1bcc12SMatthew G. Knepley 
244fb1bcc12SMatthew G. Knepley    Collective on DM
245fb1bcc12SMatthew G. Knepley 
246fb1bcc12SMatthew G. Knepley    Input parameters:
24762741f57SDave May +  dm - a DMSwarm
24862741f57SDave May -  fieldname - the textual name given to a registered field
249fb1bcc12SMatthew G. Knepley 
2508b8a3813SDave May    Output parameter:
251fb1bcc12SMatthew G. Knepley .  vec - the vector
252fb1bcc12SMatthew G. Knepley 
253fb1bcc12SMatthew G. Knepley    Level: beginner
254fb1bcc12SMatthew G. Knepley 
2558b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateLocalVectorFromField()
256fb1bcc12SMatthew G. Knepley @*/
257fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmDestroyLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
258fb1bcc12SMatthew G. Knepley {
259fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
260fb1bcc12SMatthew G. Knepley 
261fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
262fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
263bbe8250bSMatthew G. Knepley   PetscFunctionReturn(0);
264bbe8250bSMatthew G. Knepley }
265bbe8250bSMatthew G. Knepley 
266b5bcf523SDave May /*
267b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec)
268b5bcf523SDave May {
269b5bcf523SDave May   PetscFunctionReturn(0);
270b5bcf523SDave May }
271b5bcf523SDave May 
272b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec)
273b5bcf523SDave May {
274b5bcf523SDave May   PetscFunctionReturn(0);
275b5bcf523SDave May }
276b5bcf523SDave May */
277b5bcf523SDave May 
278d3a51819SDave May /*@C
279d3a51819SDave May    DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm
280d3a51819SDave May 
281d3a51819SDave May    Collective on DM
282d3a51819SDave May 
283d3a51819SDave May    Input parameter:
284d3a51819SDave May .  dm - a DMSwarm
285d3a51819SDave May 
286d3a51819SDave May    Level: beginner
287d3a51819SDave May 
288d3a51819SDave May    Notes:
2898b8a3813SDave May    After all fields have been registered, you must call DMSwarmFinalizeFieldRegister().
290d3a51819SDave May 
291d3a51819SDave May .seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
292d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
293d3a51819SDave May @*/
2945f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm)
2955f50eb2eSDave May {
2965f50eb2eSDave May   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
2973454631fSDave May   PetscErrorCode ierr;
2983454631fSDave May 
299521f74f9SMatthew G. Knepley   PetscFunctionBegin;
300cc651181SDave May   if (!swarm->field_registration_initialized) {
3015f50eb2eSDave May     swarm->field_registration_initialized = PETSC_TRUE;
302f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */
303f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */
304cc651181SDave May   }
3055f50eb2eSDave May   PetscFunctionReturn(0);
3065f50eb2eSDave May }
3075f50eb2eSDave May 
308d3a51819SDave May /*@C
309d3a51819SDave May    DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm
310d3a51819SDave May 
311d3a51819SDave May    Collective on DM
312d3a51819SDave May 
313d3a51819SDave May    Input parameter:
314d3a51819SDave May .  dm - a DMSwarm
315d3a51819SDave May 
316d3a51819SDave May    Level: beginner
317d3a51819SDave May 
318d3a51819SDave May    Notes:
31962741f57SDave May    After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined on the DMSwarm.
320d3a51819SDave May 
321d3a51819SDave May .seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
322d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
323d3a51819SDave May @*/
3245f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm)
3255f50eb2eSDave May {
3265f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3276845f8f5SDave May   PetscErrorCode ierr;
3286845f8f5SDave May 
329521f74f9SMatthew G. Knepley   PetscFunctionBegin;
330f0cdbbbaSDave May   if (!swarm->field_registration_finalized) {
3316845f8f5SDave May     ierr = DataBucketFinalize(swarm->db);CHKERRQ(ierr);
332f0cdbbbaSDave May   }
333f0cdbbbaSDave May   swarm->field_registration_finalized = PETSC_TRUE;
3345f50eb2eSDave May   PetscFunctionReturn(0);
3355f50eb2eSDave May }
3365f50eb2eSDave May 
337d3a51819SDave May /*@C
338d3a51819SDave May    DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm
339d3a51819SDave May 
340d3a51819SDave May    Not collective
341d3a51819SDave May 
342d3a51819SDave May    Input parameters:
34362741f57SDave May +  dm - a DMSwarm
344d3a51819SDave May .  nlocal - the length of each registered field
34562741f57SDave May -  buffer - the length of the buffer used to efficient dynamic re-sizing
346d3a51819SDave May 
347d3a51819SDave May    Level: beginner
348d3a51819SDave May 
349d3a51819SDave May .seealso: DMSwarmGetLocalSize()
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    DMSwarmSetCellDM - Attachs a DM to a DMSwarm
363d3a51819SDave May 
364d3a51819SDave May    Collective on DM
365d3a51819SDave May 
366d3a51819SDave May    Input parameters:
36762741f57SDave May +  dm - a DMSwarm
36862741f57SDave May -  dmcell - the DM to attach to the DMSwarm
369d3a51819SDave May 
370d3a51819SDave May    Level: beginner
371d3a51819SDave May 
372d3a51819SDave May    Notes:
373d3a51819SDave May    The attached DM (dmcell) will be queried for point location and
3748b8a3813SDave May    neighbor MPI-rank information if DMSwarmMigrate() is called.
375d3a51819SDave May 
3768b8a3813SDave May .seealso: DMSwarmSetType(), DMSwarmGetCellDM(), DMSwarmMigrate()
377d3a51819SDave May @*/
378b16650c8SDave May PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell)
379b16650c8SDave May {
380b16650c8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
381521f74f9SMatthew G. Knepley 
382521f74f9SMatthew G. Knepley   PetscFunctionBegin;
383b16650c8SDave May   swarm->dmcell = dmcell;
384b16650c8SDave May   PetscFunctionReturn(0);
385b16650c8SDave May }
386b16650c8SDave May 
387d3a51819SDave May /*@C
388d3a51819SDave May    DMSwarmGetCellDM - Fetches the attached cell DM
389d3a51819SDave May 
390d3a51819SDave May    Collective on DM
391d3a51819SDave May 
392d3a51819SDave May    Input parameter:
393d3a51819SDave May .  dm - a DMSwarm
394d3a51819SDave May 
395d3a51819SDave May    Output parameter:
396d3a51819SDave May .  dmcell - the DM which was attached to the DMSwarm
397d3a51819SDave May 
398d3a51819SDave May    Level: beginner
399d3a51819SDave May 
400d3a51819SDave May .seealso: DMSwarmSetCellDM()
401d3a51819SDave May @*/
402fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell)
403fe39f135SDave May {
404fe39f135SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
405521f74f9SMatthew G. Knepley 
406521f74f9SMatthew G. Knepley   PetscFunctionBegin;
407fe39f135SDave May   *dmcell = swarm->dmcell;
408fe39f135SDave May   PetscFunctionReturn(0);
409fe39f135SDave May }
410fe39f135SDave May 
411d3a51819SDave May /*@C
412d3a51819SDave May    DMSwarmGetLocalSize - Retrives the local length of fields registered
413d3a51819SDave May 
414d3a51819SDave May    Not collective
415d3a51819SDave May 
416d3a51819SDave May    Input parameter:
417d3a51819SDave May .  dm - a DMSwarm
418d3a51819SDave May 
419d3a51819SDave May    Output parameter:
420d3a51819SDave May .  nlocal - the length of each registered field
421d3a51819SDave May 
422d3a51819SDave May    Level: beginner
423d3a51819SDave May 
4248b8a3813SDave May .seealso: DMSwarmGetSize(), DMSwarmSetLocalSizes()
425d3a51819SDave May @*/
426dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal)
427dcf43ee8SDave May {
428dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
429dcf43ee8SDave May   PetscErrorCode ierr;
430dcf43ee8SDave May 
431521f74f9SMatthew G. Knepley   PetscFunctionBegin;
432521f74f9SMatthew G. Knepley   if (nlocal) {ierr = DataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);}
433dcf43ee8SDave May   PetscFunctionReturn(0);
434dcf43ee8SDave May }
435dcf43ee8SDave May 
436d3a51819SDave May /*@C
437d3a51819SDave May    DMSwarmGetSize - Retrives the total length of fields registered
438d3a51819SDave May 
439d3a51819SDave May    Collective on DM
440d3a51819SDave May 
441d3a51819SDave May    Input parameter:
442d3a51819SDave May .  dm - a DMSwarm
443d3a51819SDave May 
444d3a51819SDave May    Output parameter:
445d3a51819SDave May .  n - the total length of each registered field
446d3a51819SDave May 
447d3a51819SDave May    Level: beginner
448d3a51819SDave May 
449d3a51819SDave May    Note:
450d3a51819SDave May    This calls MPI_Allreduce upon each call (inefficient but safe)
451d3a51819SDave May 
4528b8a3813SDave May .seealso: DMSwarmGetLocalSize(), DMSwarmSetLocalSizes()
453d3a51819SDave May @*/
454dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n)
455dcf43ee8SDave May {
456dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
457dcf43ee8SDave May   PetscErrorCode ierr;
458dcf43ee8SDave May   PetscInt nlocal,ng;
459dcf43ee8SDave May 
460521f74f9SMatthew G. Knepley   PetscFunctionBegin;
461dcf43ee8SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
462dcf43ee8SDave May   ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
463dcf43ee8SDave May   if (n) { *n = ng; }
464dcf43ee8SDave May   PetscFunctionReturn(0);
465dcf43ee8SDave May }
466dcf43ee8SDave May 
467d3a51819SDave May /*@C
4688b8a3813SDave May    DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm with a native PETSc data type
469d3a51819SDave May 
470d3a51819SDave May    Collective on DM
471d3a51819SDave May 
472d3a51819SDave May    Input parameters:
47362741f57SDave May +  dm - a DMSwarm
474d3a51819SDave May .  fieldname - the textual name to identify this field
475d3a51819SDave May .  blocksize - the number of each data type
47662741f57SDave May -  type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG)
477d3a51819SDave May 
478d3a51819SDave May    Level: beginner
479d3a51819SDave May 
480d3a51819SDave May    Notes:
4818b8a3813SDave May    The textual name for each registered field must be unique.
482d3a51819SDave May 
483d3a51819SDave May .seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
484d3a51819SDave May @*/
4855f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
486b62e03f8SDave May {
4872eac95f8SDave May   PetscErrorCode ierr;
488b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
489b62e03f8SDave May   size_t size;
490b62e03f8SDave May 
491521f74f9SMatthew G. Knepley   PetscFunctionBegin;
4925f50eb2eSDave May   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
4935f50eb2eSDave May   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
4945f50eb2eSDave May 
4955f50eb2eSDave May   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
4965f50eb2eSDave May   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
4975f50eb2eSDave May   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
4985f50eb2eSDave May   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
4995f50eb2eSDave May   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
500b62e03f8SDave May 
5012ddcf43eSMatthew G. Knepley   ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr);
502b62e03f8SDave May   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
50352c3ed93SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
50452c3ed93SDave May   {
50552c3ed93SDave May     DataField gfield;
50652c3ed93SDave May 
50752c3ed93SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
50852c3ed93SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
50952c3ed93SDave May   }
510b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
511b62e03f8SDave May   PetscFunctionReturn(0);
512b62e03f8SDave May }
513b62e03f8SDave May 
514d3a51819SDave May /*@C
515d3a51819SDave May    DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm
516d3a51819SDave May 
517d3a51819SDave May    Collective on DM
518d3a51819SDave May 
519d3a51819SDave May    Input parameters:
52062741f57SDave May +  dm - a DMSwarm
521d3a51819SDave May .  fieldname - the textual name to identify this field
52262741f57SDave May -  size - the size in bytes of the user struct of each data type
523d3a51819SDave May 
524d3a51819SDave May    Level: beginner
525d3a51819SDave May 
526d3a51819SDave May    Notes:
5278b8a3813SDave May    The textual name for each registered field must be unique.
528d3a51819SDave May 
529d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField()
530d3a51819SDave May @*/
5315f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
532b62e03f8SDave May {
5332eac95f8SDave May   PetscErrorCode ierr;
534b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
535b62e03f8SDave May 
536521f74f9SMatthew G. Knepley   PetscFunctionBegin;
5372eac95f8SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
538b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
539b62e03f8SDave May   PetscFunctionReturn(0);
540b62e03f8SDave May }
541b62e03f8SDave May 
542d3a51819SDave May /*@C
543d3a51819SDave May    DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm
544d3a51819SDave May 
545d3a51819SDave May    Collective on DM
546d3a51819SDave May 
547d3a51819SDave May    Input parameters:
54862741f57SDave May +  dm - a DMSwarm
549d3a51819SDave May .  fieldname - the textual name to identify this field
550d3a51819SDave May .  size - the size in bytes of the user data type
55162741f57SDave May -  blocksize - the number of each data type
552d3a51819SDave May 
553d3a51819SDave May    Level: beginner
554d3a51819SDave May 
555d3a51819SDave May    Notes:
5568b8a3813SDave May    The textual name for each registered field must be unique.
557d3a51819SDave May 
558d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
559d3a51819SDave May @*/
560320740a0SDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize)
561b62e03f8SDave May {
562b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
5636845f8f5SDave May   PetscErrorCode ierr;
564b62e03f8SDave May 
565521f74f9SMatthew G. Knepley   PetscFunctionBegin;
566320740a0SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
567320740a0SDave May   {
568320740a0SDave May     DataField gfield;
569320740a0SDave May 
570320740a0SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
571320740a0SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
572320740a0SDave May   }
573b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
574b62e03f8SDave May   PetscFunctionReturn(0);
575b62e03f8SDave May }
576b62e03f8SDave May 
577d3a51819SDave May /*@C
578d3a51819SDave May    DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field
579d3a51819SDave May 
580d3a51819SDave May    Not collective
581d3a51819SDave May 
582d3a51819SDave May    Input parameters:
58362741f57SDave May +  dm - a DMSwarm
58462741f57SDave May -  fieldname - the textual name to identify this field
585d3a51819SDave May 
586d3a51819SDave May    Output parameters:
58762741f57SDave May +  blocksize - the number of each data type
588d3a51819SDave May .  type - the data type
58962741f57SDave May -  data - pointer to raw array
590d3a51819SDave May 
591d3a51819SDave May    Level: beginner
592d3a51819SDave May 
593d3a51819SDave May    Notes:
5948b8a3813SDave May    The array must be returned using a matching call to DMSwarmRestoreField().
595d3a51819SDave May 
596d3a51819SDave May .seealso: DMSwarmRestoreField()
597d3a51819SDave May @*/
5985f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
599b62e03f8SDave May {
600b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
601b62e03f8SDave May   DataField gfield;
6022eac95f8SDave May   PetscErrorCode ierr;
603b62e03f8SDave May 
604521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6053454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
6062eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6076845f8f5SDave May   ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr);
6086845f8f5SDave May   ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr);
6091b1ea282SDave May   if (blocksize) {*blocksize = gfield->bs; }
610b5bcf523SDave May   if (type) { *type = gfield->petsc_type; }
611b62e03f8SDave May   PetscFunctionReturn(0);
612b62e03f8SDave May }
613b62e03f8SDave May 
614d3a51819SDave May /*@C
615d3a51819SDave May    DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field
616d3a51819SDave May 
617d3a51819SDave May    Not collective
618d3a51819SDave May 
619d3a51819SDave May    Input parameters:
62062741f57SDave May +  dm - a DMSwarm
62162741f57SDave May -  fieldname - the textual name to identify this field
622d3a51819SDave May 
623d3a51819SDave May    Output parameters:
62462741f57SDave May +  blocksize - the number of each data type
625d3a51819SDave May .  type - the data type
62662741f57SDave May -  data - pointer to raw array
627d3a51819SDave May 
628d3a51819SDave May    Level: beginner
629d3a51819SDave May 
630d3a51819SDave May    Notes:
6318b8a3813SDave May    The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField().
632d3a51819SDave May 
633d3a51819SDave May .seealso: DMSwarmGetField()
634d3a51819SDave May @*/
6355f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
636b62e03f8SDave May {
637b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
638b62e03f8SDave May   DataField gfield;
6392eac95f8SDave May   PetscErrorCode ierr;
640b62e03f8SDave May 
641521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6422eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6436845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
644b62e03f8SDave May   if (data) *data = NULL;
645b62e03f8SDave May   PetscFunctionReturn(0);
646b62e03f8SDave May }
647b62e03f8SDave May 
648d3a51819SDave May /*@C
649d3a51819SDave May    DMSwarmAddPoint - Add space for one new point in the DMSwarm
650d3a51819SDave May 
651d3a51819SDave May    Not collective
652d3a51819SDave May 
653d3a51819SDave May    Input parameter:
654d3a51819SDave May .  dm - a DMSwarm
655d3a51819SDave May 
656d3a51819SDave May    Level: beginner
657d3a51819SDave May 
658d3a51819SDave May    Notes:
6598b8a3813SDave May    The new point will have all fields initialized to zero.
660d3a51819SDave May 
661d3a51819SDave May .seealso: DMSwarmAddNPoints()
662d3a51819SDave May @*/
663cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
664cb1d1399SDave May {
665cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
666cb1d1399SDave May   PetscErrorCode ierr;
667cb1d1399SDave May 
668521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6693454631fSDave May   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
670cb1d1399SDave May   ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr);
671cb1d1399SDave May   PetscFunctionReturn(0);
672cb1d1399SDave May }
673cb1d1399SDave May 
674d3a51819SDave May /*@C
675d3a51819SDave May    DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm
676d3a51819SDave May 
677d3a51819SDave May    Not collective
678d3a51819SDave May 
679d3a51819SDave May    Input parameters:
68062741f57SDave May +  dm - a DMSwarm
68162741f57SDave May -  npoints - the number of new points to add
682d3a51819SDave May 
683d3a51819SDave May    Level: beginner
684d3a51819SDave May 
685d3a51819SDave May    Notes:
6868b8a3813SDave May    The new point will have all fields initialized to zero.
687d3a51819SDave May 
688d3a51819SDave May .seealso: DMSwarmAddPoint()
689d3a51819SDave May @*/
690cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
691cb1d1399SDave May {
692cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
693cb1d1399SDave May   PetscErrorCode ierr;
694cb1d1399SDave May   PetscInt nlocal;
695cb1d1399SDave May 
696521f74f9SMatthew G. Knepley   PetscFunctionBegin;
697cb1d1399SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
698cb1d1399SDave May   nlocal = nlocal + npoints;
699cb1d1399SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,-1);CHKERRQ(ierr);
700cb1d1399SDave May   PetscFunctionReturn(0);
701cb1d1399SDave May }
702cb1d1399SDave May 
703d3a51819SDave May /*@C
704d3a51819SDave May    DMSwarmRemovePoint - Remove the last point from the DMSwarm
705d3a51819SDave May 
706d3a51819SDave May    Not collective
707d3a51819SDave May 
708d3a51819SDave May    Input parameter:
709d3a51819SDave May .  dm - a DMSwarm
710d3a51819SDave May 
711d3a51819SDave May    Level: beginner
712d3a51819SDave May 
713d3a51819SDave May .seealso: DMSwarmRemovePointAtIndex()
714d3a51819SDave May @*/
715cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
716cb1d1399SDave May {
717cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
718cb1d1399SDave May   PetscErrorCode ierr;
719cb1d1399SDave May 
720521f74f9SMatthew G. Knepley   PetscFunctionBegin;
721cb1d1399SDave May   ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
722cb1d1399SDave May   PetscFunctionReturn(0);
723cb1d1399SDave May }
724cb1d1399SDave May 
725d3a51819SDave May /*@C
726d3a51819SDave May    DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm
727d3a51819SDave May 
728d3a51819SDave May    Not collective
729d3a51819SDave May 
730d3a51819SDave May    Input parameters:
73162741f57SDave May +  dm - a DMSwarm
73262741f57SDave May -  idx - index of point to remove
733d3a51819SDave May 
734d3a51819SDave May    Level: beginner
735d3a51819SDave May 
736d3a51819SDave May .seealso: DMSwarmRemovePoint()
737d3a51819SDave May @*/
738cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
739cb1d1399SDave May {
740cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
741cb1d1399SDave May   PetscErrorCode ierr;
742cb1d1399SDave May 
743521f74f9SMatthew G. Knepley   PetscFunctionBegin;
744cb1d1399SDave May   ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
745cb1d1399SDave May   PetscFunctionReturn(0);
746cb1d1399SDave May }
747b62e03f8SDave May 
748095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points)
7493454631fSDave May {
750dcf43ee8SDave May   PetscErrorCode ierr;
751521f74f9SMatthew G. Knepley 
752521f74f9SMatthew G. Knepley   PetscFunctionBegin;
753dcf43ee8SDave May   ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr);
7543454631fSDave May   PetscFunctionReturn(0);
7553454631fSDave May }
7563454631fSDave May 
757d3a51819SDave May /*@C
758d3a51819SDave May    DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks
759d3a51819SDave May 
760d3a51819SDave May    Collective on DM
761d3a51819SDave May 
762d3a51819SDave May    Input parameters:
76362741f57SDave May +  dm - the DMSwarm
76462741f57SDave May -  remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank
765d3a51819SDave May 
766d3a51819SDave May    Notes:
7678b8a3813SDave May    The DM will be modified to accomodate received points.
7688b8a3813SDave May    If remove_sent_points = PETSC_TRUE, any points that were sent will be removed from the DM.
7698b8a3813SDave May    Different styles of migration are supported. See DMSwarmSetMigrateType().
770d3a51819SDave May 
771d3a51819SDave May    Level: advanced
772d3a51819SDave May 
773d3a51819SDave May .seealso: DMSwarmSetMigrateType()
774d3a51819SDave May @*/
775095059a4SDave May PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points)
7763454631fSDave May {
777f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
7783454631fSDave May   PetscErrorCode ierr;
779f0cdbbbaSDave May 
780521f74f9SMatthew G. Knepley   PetscFunctionBegin;
781f0cdbbbaSDave May   switch (swarm->migrate_type) {
782f0cdbbbaSDave May     case DMSWARM_MIGRATE_BASIC:
783095059a4SDave May       ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr);
784f0cdbbbaSDave May       break;
785f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLNSCATTER:
786f0cdbbbaSDave May       ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr);
787f0cdbbbaSDave May       break;
788f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLEXACT:
789f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented");
790521f74f9SMatthew G. Knepley       /*ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr);*/
791f0cdbbbaSDave May       break;
792f0cdbbbaSDave May     case DMSWARM_MIGRATE_USER:
793f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented");
794521f74f9SMatthew G. Knepley       /*ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr);*/
795f0cdbbbaSDave May       break;
796f0cdbbbaSDave May     default:
797f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown");
798f0cdbbbaSDave May       break;
799f0cdbbbaSDave May   }
8003454631fSDave May   PetscFunctionReturn(0);
8013454631fSDave May }
8023454631fSDave May 
803f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize);
804f0cdbbbaSDave May 
805d3a51819SDave May /*
806d3a51819SDave May  DMSwarmCollectViewCreate
807d3a51819SDave May 
808d3a51819SDave May  * Applies a collection method and gathers point neighbour points into dm
809d3a51819SDave May 
810d3a51819SDave May  Notes:
8118b8a3813SDave May  Users should call DMSwarmCollectViewDestroy() after
812d3a51819SDave May  they have finished computations associated with the collected points
813d3a51819SDave May */
814d3a51819SDave May 
815d3a51819SDave May /*@C
816d3a51819SDave May    DMSwarmCollectViewCreate - Applies a collection method and gathers points
817d3a51819SDave May    in neighbour MPI-ranks into the DMSwarm
818d3a51819SDave May 
819d3a51819SDave May    Collective on DM
820d3a51819SDave May 
821d3a51819SDave May    Input parameter:
822d3a51819SDave May .  dm - the DMSwarm
823d3a51819SDave May 
824d3a51819SDave May    Notes:
825d3a51819SDave May    Users should call DMSwarmCollectViewDestroy() after
826d3a51819SDave May    they have finished computations associated with the collected points
8278b8a3813SDave May    Different collect methods are supported. See DMSwarmSetCollectType().
828d3a51819SDave May 
829d3a51819SDave May    Level: advanced
830d3a51819SDave May 
831d3a51819SDave May .seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType()
832d3a51819SDave May @*/
833fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm)
8342712d1f2SDave May {
8352712d1f2SDave May   PetscErrorCode ierr;
8362712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8372712d1f2SDave May   PetscInt ng;
8382712d1f2SDave May 
839521f74f9SMatthew G. Knepley   PetscFunctionBegin;
840480eef7bSDave May   if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active");
841480eef7bSDave May   ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr);
842480eef7bSDave May   switch (swarm->collect_type) {
843f0cdbbbaSDave May 
844480eef7bSDave May     case DMSWARM_COLLECT_BASIC:
8452712d1f2SDave May       ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr);
846480eef7bSDave May       break;
847480eef7bSDave May     case DMSWARM_COLLECT_DMDABOUNDINGBOX:
848f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented");
849521f74f9SMatthew G. Knepley       /*ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr);*/
850480eef7bSDave May       break;
851480eef7bSDave May     case DMSWARM_COLLECT_GENERAL:
852f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented");
853521f74f9SMatthew G. Knepley       /*ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr);*/
854480eef7bSDave May       break;
855480eef7bSDave May     default:
856f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown");
857480eef7bSDave May       break;
858480eef7bSDave May   }
859480eef7bSDave May   swarm->collect_view_active = PETSC_TRUE;
860480eef7bSDave May   swarm->collect_view_reset_nlocal = ng;
8612712d1f2SDave May   PetscFunctionReturn(0);
8622712d1f2SDave May }
8632712d1f2SDave May 
864d3a51819SDave May /*@C
865d3a51819SDave May    DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate()
866d3a51819SDave May 
867d3a51819SDave May    Collective on DM
868d3a51819SDave May 
869d3a51819SDave May    Input parameters:
870d3a51819SDave May .  dm - the DMSwarm
871d3a51819SDave May 
872d3a51819SDave May    Notes:
873d3a51819SDave May    Users should call DMSwarmCollectViewCreate() before this function is called.
874d3a51819SDave May 
875d3a51819SDave May    Level: advanced
876d3a51819SDave May 
877d3a51819SDave May .seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType()
878d3a51819SDave May @*/
879fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm)
8802712d1f2SDave May {
8812712d1f2SDave May   PetscErrorCode ierr;
8822712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8832712d1f2SDave May 
884521f74f9SMatthew G. Knepley   PetscFunctionBegin;
885480eef7bSDave May   if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active");
886480eef7bSDave May   ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr);
887480eef7bSDave May   swarm->collect_view_active = PETSC_FALSE;
8882712d1f2SDave May   PetscFunctionReturn(0);
8892712d1f2SDave May }
8903454631fSDave May 
891f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm)
892f0cdbbbaSDave May {
893f0cdbbbaSDave May   PetscInt dim;
894f0cdbbbaSDave May   PetscErrorCode ierr;
895f0cdbbbaSDave May 
896521f74f9SMatthew G. Knepley   PetscFunctionBegin;
897f0cdbbbaSDave May   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
898f0cdbbbaSDave May   if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
899f0cdbbbaSDave May   if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
900f0cdbbbaSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr);
901e2d107dbSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_cellid,1,PETSC_INT);CHKERRQ(ierr);
902f0cdbbbaSDave May   PetscFunctionReturn(0);
903f0cdbbbaSDave May }
904f0cdbbbaSDave May 
905d3a51819SDave May /*@C
906d3a51819SDave May    DMSwarmSetType - Set particular flavor of DMSwarm
907d3a51819SDave May 
908d3a51819SDave May    Collective on DM
909d3a51819SDave May 
910d3a51819SDave May    Input parameters:
91162741f57SDave May +  dm - the DMSwarm
91262741f57SDave May -  stype - the DMSwarm type (e.g. DMSWARM_PIC)
913d3a51819SDave May 
914d3a51819SDave May    Level: advanced
915d3a51819SDave May 
916d3a51819SDave May .seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType()
917d3a51819SDave May @*/
918f0cdbbbaSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype)
919f0cdbbbaSDave May {
920f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
921f0cdbbbaSDave May   PetscErrorCode ierr;
922f0cdbbbaSDave May 
923521f74f9SMatthew G. Knepley   PetscFunctionBegin;
924f0cdbbbaSDave May   swarm->swarm_type = stype;
925f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
926f0cdbbbaSDave May     ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr);
927f0cdbbbaSDave May   }
928f0cdbbbaSDave May   PetscFunctionReturn(0);
929f0cdbbbaSDave May }
930f0cdbbbaSDave May 
9313454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm)
9323454631fSDave May {
9333454631fSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9343454631fSDave May   PetscErrorCode ierr;
9353454631fSDave May   PetscMPIInt rank;
9363454631fSDave May   PetscInt p,npoints,*rankval;
9373454631fSDave May 
938521f74f9SMatthew G. Knepley   PetscFunctionBegin;
9393454631fSDave May   if (swarm->issetup) PetscFunctionReturn(0);
9403454631fSDave May 
9413454631fSDave May   swarm->issetup = PETSC_TRUE;
9423454631fSDave May 
943f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
944f0cdbbbaSDave May     /* check dmcell exists */
945f0cdbbbaSDave May     if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM");
946f0cdbbbaSDave May 
947f0cdbbbaSDave May     if (swarm->dmcell->ops->locatepointssubdomain) {
948f0cdbbbaSDave May       /* check methods exists for exact ownership identificiation */
949521f74f9SMatthew G. Knepley       ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");CHKERRQ(ierr);
950f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT;
951f0cdbbbaSDave May     } else {
952f0cdbbbaSDave May       /* check methods exist for point location AND rank neighbor identification */
953f0cdbbbaSDave May       if (swarm->dmcell->ops->locatepoints) {
954521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->LocatePoints\n");CHKERRQ(ierr);
955f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined");
956f0cdbbbaSDave May 
957f0cdbbbaSDave May       if (swarm->dmcell->ops->getneighbors) {
958521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->GetNeigbors\n");CHKERRQ(ierr);
959f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined");
960f0cdbbbaSDave May 
961f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER;
962f0cdbbbaSDave May     }
963f0cdbbbaSDave May   }
964f0cdbbbaSDave May 
965f0cdbbbaSDave May   ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr);
966f0cdbbbaSDave May 
9673454631fSDave May   /* check some fields were registered */
9683454631fSDave May   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
9693454631fSDave May 
9703454631fSDave May   /* check local sizes were set */
9713454631fSDave May   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
9723454631fSDave May 
9733454631fSDave May   /* initialize values in pid and rank placeholders */
9743454631fSDave May   /* TODO: [pid - use MPI_Scan] */
9753454631fSDave May   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
9763454631fSDave May   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
977f0cdbbbaSDave May   ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
9783454631fSDave May   for (p=0; p<npoints; p++) {
9793454631fSDave May     rankval[p] = (PetscInt)rank;
9803454631fSDave May   }
981f0cdbbbaSDave May   ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
9823454631fSDave May   PetscFunctionReturn(0);
9833454631fSDave May }
9843454631fSDave May 
985*dc5f5ce9SDave May extern PetscErrorCode DMSwarmSortDestroy(DMSwarmSort *_ctx);
986*dc5f5ce9SDave May 
98757795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm)
98857795646SDave May {
98957795646SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
99057795646SDave May   PetscErrorCode ierr;
99157795646SDave May 
99257795646SDave May   PetscFunctionBegin;
9936845f8f5SDave May   ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr);
994*dc5f5ce9SDave May   if (swarm->sort_context) {
995*dc5f5ce9SDave May     ierr = DMSwarmSortDestroy(&swarm->sort_context);CHKERRQ(ierr);
996*dc5f5ce9SDave May   }
99757795646SDave May   ierr = PetscFree(swarm);CHKERRQ(ierr);
99857795646SDave May   PetscFunctionReturn(0);
99957795646SDave May }
100057795646SDave May 
1001a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer)
1002a9ee3421SMatthew G. Knepley {
1003a9ee3421SMatthew G. Knepley   DM             cdm;
1004a9ee3421SMatthew G. Knepley   PetscDraw      draw;
1005a9ee3421SMatthew G. Knepley   PetscReal     *coords, oldPause;
1006a9ee3421SMatthew G. Knepley   PetscInt       Np, p, bs;
1007a9ee3421SMatthew G. Knepley   PetscErrorCode ierr;
1008a9ee3421SMatthew G. Knepley 
1009a9ee3421SMatthew G. Knepley   PetscFunctionBegin;
1010a9ee3421SMatthew G. Knepley   ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr);
1011a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr);
1012a9ee3421SMatthew G. Knepley   ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr);
1013a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr);
1014a9ee3421SMatthew G. Knepley   ierr = DMView(cdm, viewer);CHKERRQ(ierr);
1015a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr);
1016a9ee3421SMatthew G. Knepley 
1017a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr);
1018a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1019a9ee3421SMatthew G. Knepley   for (p = 0; p < Np; ++p) {
1020a9ee3421SMatthew G. Knepley     const PetscInt i = p*bs;
1021a9ee3421SMatthew G. Knepley 
1022a9ee3421SMatthew G. Knepley     ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], 0.01, 0.01, PETSC_DRAW_BLUE);CHKERRQ(ierr);
1023a9ee3421SMatthew G. Knepley   }
1024a9ee3421SMatthew G. Knepley   ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1025a9ee3421SMatthew G. Knepley   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
1026a9ee3421SMatthew G. Knepley   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
1027a9ee3421SMatthew G. Knepley   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1028a9ee3421SMatthew G. Knepley   PetscFunctionReturn(0);
1029a9ee3421SMatthew G. Knepley }
1030a9ee3421SMatthew G. Knepley 
10315f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
10325f50eb2eSDave May {
10335f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1034a9ee3421SMatthew G. Knepley   PetscBool      iascii,ibinary,ishdf5,isvtk,isdraw;
10355f50eb2eSDave May   PetscErrorCode ierr;
10365f50eb2eSDave May 
10375f50eb2eSDave May   PetscFunctionBegin;
10385f50eb2eSDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10395f50eb2eSDave May   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
10405f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
10415f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
10425f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
10435f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1044a9ee3421SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW,  &isdraw);CHKERRQ(ierr);
10455f50eb2eSDave May   if (iascii) {
10466845f8f5SDave May     ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
10475f50eb2eSDave May   } else if (ibinary) {
1048a9ee3421SMatthew G. Knepley     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support");
10495f50eb2eSDave May   } else if (ishdf5) {
10505f50eb2eSDave May #if defined(PETSC_HAVE_HDF5)
10515f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
10525f50eb2eSDave May #else
10535f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
10545f50eb2eSDave May #endif
10555f50eb2eSDave May   } else if (isvtk) {
10565f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
1057a9ee3421SMatthew G. Knepley   } else if (isdraw) {
1058a9ee3421SMatthew G. Knepley     ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr);
10595f50eb2eSDave May   }
10605f50eb2eSDave May   PetscFunctionReturn(0);
10615f50eb2eSDave May }
10625f50eb2eSDave May 
1063d3a51819SDave May /*MC
1064d3a51819SDave May 
1065d3a51819SDave May  DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type.
106662741f57SDave May  This implementation was designed for particle methods in which the underlying
1067d3a51819SDave May  data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type.
1068d3a51819SDave May 
106962741f57SDave May  User data can be represented by DMSwarm through a registering "fields".
107062741f57SDave May  To register a field, the user must provide;
107162741f57SDave May  (a) a unique name;
107262741f57SDave May  (b) the data type (or size in bytes);
107362741f57SDave May  (c) the block size of the data.
1074d3a51819SDave May 
1075d3a51819SDave May  For example, suppose the application requires a unique id, energy, momentum and density to be stored
107662741f57SDave May  on a set of of particles. Then the following code could be used
1077d3a51819SDave May 
107862741f57SDave May $    DMSwarmInitializeFieldRegister(dm)
107962741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG);
108062741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL);
108162741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL);
108262741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT);
108362741f57SDave May $    DMSwarmFinalizeFieldRegister(dm)
1084d3a51819SDave May 
1085d3a51819SDave May  The fields represented by DMSwarm are dynamic and can be re-sized at any time.
108662741f57SDave May  The only restriction imposed by DMSwarm is that all fields contain the same number of points.
1087d3a51819SDave May 
1088d3a51819SDave May  To support particle methods, "migration" techniques are provided. These methods migrate data
1089d3a51819SDave May  between MPI-ranks.
1090d3a51819SDave May 
1091d3a51819SDave May  DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector().
1092d3a51819SDave May  As a DMSwarm may internally define and store values of different data types,
109362741f57SDave May  before calling DMCreateGlobalVector() or DMCreateLocalVector(), the user must inform DMSwarm which
1094d3a51819SDave May  fields should be used to define a Vec object via
1095d3a51819SDave May    DMSwarmVectorDefineField()
1096d3a51819SDave May  The specified field can can changed be changed at any time - thereby permitting vectors
1097d3a51819SDave May  compatable with different fields to be created.
1098d3a51819SDave May 
109962741f57SDave May  A dual representation of fields in the DMSwarm and a Vec object is permitted via
1100d3a51819SDave May    DMSwarmCreateGlobalVectorFromField()
1101d3a51819SDave May  Here the data defining the field in the DMSwarm is shared with a Vec.
1102d3a51819SDave May  This is inherently unsafe if you alter the size of the field at any time between
1103d3a51819SDave May  calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField().
1104cc651181SDave May  If the local size of the DMSwarm does not match the local size of the global vector
1105cc651181SDave May  when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown.
1106d3a51819SDave May 
110762741f57SDave May  Additional high-level support is provided for Particle-In-Cell methods.
110862741f57SDave May  Please refer to the man page for DMSwarmSetType().
110962741f57SDave May 
1110d3a51819SDave May  Level: beginner
1111d3a51819SDave May 
1112d3a51819SDave May .seealso: DMType, DMCreate(), DMSetType()
1113d3a51819SDave May M*/
111457795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
111557795646SDave May {
111657795646SDave May   DM_Swarm      *swarm;
111757795646SDave May   PetscErrorCode ierr;
111857795646SDave May 
111957795646SDave May   PetscFunctionBegin;
112057795646SDave May   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
112157795646SDave May   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
1122f0cdbbbaSDave May   dm->data = swarm;
112357795646SDave May 
11246845f8f5SDave May   ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr);
1125f0cdbbbaSDave May   ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr);
1126f0cdbbbaSDave May 
1127b5bcf523SDave May   swarm->vec_field_set = PETSC_FALSE;
11283454631fSDave May   swarm->issetup = PETSC_FALSE;
1129480eef7bSDave May   swarm->swarm_type = DMSWARM_BASIC;
1130480eef7bSDave May   swarm->migrate_type = DMSWARM_MIGRATE_BASIC;
1131480eef7bSDave May   swarm->collect_type = DMSWARM_COLLECT_BASIC;
113240c453e9SDave May   swarm->migrate_error_on_missing_point = PETSC_FALSE;
1133b62e03f8SDave May 
1134f0cdbbbaSDave May   swarm->dmcell = NULL;
1135f0cdbbbaSDave May   swarm->collect_view_active = PETSC_FALSE;
1136f0cdbbbaSDave May   swarm->collect_view_reset_nlocal = -1;
113757795646SDave May 
1138f0cdbbbaSDave May   dm->dim  = 0;
11395f50eb2eSDave May   dm->ops->view                            = DMView_Swarm;
114057795646SDave May   dm->ops->load                            = NULL;
114157795646SDave May   dm->ops->setfromoptions                  = NULL;
114257795646SDave May   dm->ops->clone                           = NULL;
11433454631fSDave May   dm->ops->setup                           = DMSetup_Swarm;
114457795646SDave May   dm->ops->createdefaultsection            = NULL;
114557795646SDave May   dm->ops->createdefaultconstraints        = NULL;
1146b5bcf523SDave May   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
1147b5bcf523SDave May   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
114857795646SDave May   dm->ops->getlocaltoglobalmapping         = NULL;
114957795646SDave May   dm->ops->createfieldis                   = NULL;
115057795646SDave May   dm->ops->createcoordinatedm              = NULL;
115157795646SDave May   dm->ops->getcoloring                     = NULL;
115257795646SDave May   dm->ops->creatematrix                    = NULL;
115357795646SDave May   dm->ops->createinterpolation             = NULL;
115457795646SDave May   dm->ops->getaggregates                   = NULL;
115557795646SDave May   dm->ops->getinjection                    = NULL;
115657795646SDave May   dm->ops->refine                          = NULL;
115757795646SDave May   dm->ops->coarsen                         = NULL;
115857795646SDave May   dm->ops->refinehierarchy                 = NULL;
115957795646SDave May   dm->ops->coarsenhierarchy                = NULL;
116057795646SDave May   dm->ops->globaltolocalbegin              = NULL;
116157795646SDave May   dm->ops->globaltolocalend                = NULL;
116257795646SDave May   dm->ops->localtoglobalbegin              = NULL;
116357795646SDave May   dm->ops->localtoglobalend                = NULL;
116457795646SDave May   dm->ops->destroy                         = DMDestroy_Swarm;
116557795646SDave May   dm->ops->createsubdm                     = NULL;
116657795646SDave May   dm->ops->getdimpoints                    = NULL;
116757795646SDave May   dm->ops->locatepoints                    = NULL;
116857795646SDave May   PetscFunctionReturn(0);
116957795646SDave May }
1170