xref: /petsc/src/dm/impls/swarm/swarm.c (revision 5917a6f0f052c66c284658657d15751d51c5bf50)
157795646SDave May #define PETSCDM_DLL
257795646SDave May #include <petsc/private/dmswarmimpl.h>    /*I   "petscdmswarm.h"   I*/
3*5917a6f0SStefano Zampini #include <petscviewer.h>
4*5917a6f0SStefano Zampini #include <petscdraw.h>
5b62e03f8SDave May #include "data_bucket.h"
657795646SDave May 
7f2b2bee7SDave May PetscLogEvent DMSWARM_Migrate, DMSWARM_SetSizes, DMSWARM_AddPoints, DMSWARM_RemovePoints, DMSWARM_Sort;
8ed923d71SDave May PetscLogEvent DMSWARM_DataExchangerTopologySetup, DMSWARM_DataExchangerBegin, DMSWARM_DataExchangerEnd;
9ed923d71SDave May PetscLogEvent DMSWARM_DataExchangerSendCount, DMSWARM_DataExchangerPack;
10ed923d71SDave May 
11f0cdbbbaSDave May const char* DMSwarmTypeNames[] = { "basic", "pic", 0 };
12f0cdbbbaSDave May const char* DMSwarmMigrateTypeNames[] = { "basic", "dmcellnscatter", "dmcellexact", "user", 0 };
13f0cdbbbaSDave May const char* DMSwarmCollectTypeNames[] = { "basic", "boundingbox", "general", "user", 0 };
14e2d107dbSDave May const char* DMSwarmPICLayoutTypeNames[] = { "regular", "gauss", "subdivision", 0 };
15f0cdbbbaSDave May 
16f0cdbbbaSDave May const char DMSwarmField_pid[] = "DMSwarm_pid";
17f0cdbbbaSDave May const char DMSwarmField_rank[] = "DMSwarm_rank";
18f0cdbbbaSDave May const char DMSwarmPICField_coor[] = "DMSwarmPIC_coor";
19e2d107dbSDave May const char DMSwarmPICField_cellid[] = "DMSwarm_cellid";
20f0cdbbbaSDave May 
21d3a51819SDave May /*@C
2262741f57SDave May    DMSwarmVectorDefineField - Sets the field from which to define a Vec object
2362741f57SDave May                              when DMCreateLocalVector(), or DMCreateGlobalVector() is called
2457795646SDave May 
25d3a51819SDave May    Collective on DM
2657795646SDave May 
27d3a51819SDave May    Input parameters:
2862741f57SDave May +  dm - a DMSwarm
2962741f57SDave May -  fieldname - the textual name given to a registered field
3057795646SDave May 
31d3a51819SDave May    Level: beginner
3257795646SDave May 
33d3a51819SDave May    Notes:
3462741f57SDave May    The field with name fieldname must be defined as having a data type of PetscScalar.
35d3a51819SDave May    This function must be called prior to calling DMCreateLocalVector(), DMCreateGlobalVector().
36d3a51819SDave May    Mutiple calls to DMSwarmVectorDefineField() are permitted.
3757795646SDave May 
388b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMCreateGlobalVector(), DMCreateLocalVector()
39d3a51819SDave May @*/
40b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmVectorDefineField(DM dm,const char fieldname[])
41b5bcf523SDave May {
42b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
43b5bcf523SDave May   PetscErrorCode ierr;
44b5bcf523SDave May   PetscInt bs,n;
45b5bcf523SDave May   PetscScalar *array;
46b5bcf523SDave May   PetscDataType type;
47b5bcf523SDave May 
48a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
493454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
506845f8f5SDave May   ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr);
51b5bcf523SDave May   ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
52b5bcf523SDave May 
53b5bcf523SDave May   /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */
54b5bcf523SDave May   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL");
55521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(swarm->vec_field_name,PETSC_MAX_PATH_LEN-1,"%s",fieldname);CHKERRQ(ierr);
56b5bcf523SDave May   swarm->vec_field_set = PETSC_TRUE;
571b1ea282SDave May   swarm->vec_field_bs = bs;
58b5bcf523SDave May   swarm->vec_field_nlocal = n;
59dcf43ee8SDave May   ierr = DMSwarmRestoreField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
60b5bcf523SDave May   PetscFunctionReturn(0);
61b5bcf523SDave May }
62b5bcf523SDave May 
63cc651181SDave May /* requires DMSwarmDefineFieldVector has been called */
64b5bcf523SDave May PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec)
65b5bcf523SDave May {
66b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
67b5bcf523SDave May   PetscErrorCode ierr;
68b5bcf523SDave May   Vec x;
69b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
70b5bcf523SDave May 
71a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
723454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
73b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
74cc651181SDave 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 */
75cc651181SDave May 
76521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr);
77b5bcf523SDave May   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr);
78b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
791b1ea282SDave May   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr);
80b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
81b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
82b5bcf523SDave May   *vec = x;
83b5bcf523SDave May   PetscFunctionReturn(0);
84b5bcf523SDave May }
85b5bcf523SDave May 
86b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */
87b5bcf523SDave May PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec)
88b5bcf523SDave May {
89b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
90b5bcf523SDave May   PetscErrorCode ierr;
91b5bcf523SDave May   Vec x;
92b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
93b5bcf523SDave May 
94a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
953454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
96b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
97cc651181SDave May   if (swarm->vec_field_nlocal != swarm->db->L) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSwarm sizes have changed since last call to VectorDefineField first"); /* Stale data */
98cc651181SDave May 
99521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr);
100b5bcf523SDave May   ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr);
101b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
102071900c8SMatthew G. Knepley   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr);
103b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
104b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
105b5bcf523SDave May   *vec = x;
106b5bcf523SDave May   PetscFunctionReturn(0);
107b5bcf523SDave May }
108b5bcf523SDave May 
109fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmDestroyVectorFromField_Private(DM dm, const char fieldname[], Vec *vec)
110fb1bcc12SMatthew G. Knepley {
111fb1bcc12SMatthew G. Knepley   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
112fb1bcc12SMatthew G. Knepley   DataField      gfield;
113fb1bcc12SMatthew G. Knepley   void         (*fptr)(void);
114fb1bcc12SMatthew G. Knepley   PetscInt       bs, nlocal;
115fb1bcc12SMatthew G. Knepley   char           name[PETSC_MAX_PATH_LEN];
116fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
117d3a51819SDave May 
118fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
119fb1bcc12SMatthew G. Knepley   ierr = VecGetLocalSize(*vec, &nlocal);CHKERRQ(ierr);
120fb1bcc12SMatthew G. Knepley   ierr = VecGetBlockSize(*vec, &bs);CHKERRQ(ierr);
121fb1bcc12SMatthew 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 */
122fb1bcc12SMatthew G. Knepley   ierr = DataBucketGetDataFieldByName(swarm->db, fieldname, &gfield);CHKERRQ(ierr);
123fb1bcc12SMatthew G. Knepley   /* check vector is an inplace array */
124521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr);
125fb1bcc12SMatthew G. Knepley   ierr = PetscObjectQueryFunction((PetscObject) *vec, name, &fptr);CHKERRQ(ierr);
126fb1bcc12SMatthew G. Knepley   if (!fptr) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Vector being destroyed was not created from DMSwarm field(%s)", fieldname);
127fb1bcc12SMatthew G. Knepley   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
128fb1bcc12SMatthew G. Knepley   ierr = VecDestroy(vec);CHKERRQ(ierr);
129fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
130fb1bcc12SMatthew G. Knepley }
131fb1bcc12SMatthew G. Knepley 
132fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmCreateVectorFromField_Private(DM dm, const char fieldname[], MPI_Comm comm, Vec *vec)
133fb1bcc12SMatthew G. Knepley {
134fb1bcc12SMatthew G. Knepley   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
135fb1bcc12SMatthew G. Knepley   PetscDataType  type;
136fb1bcc12SMatthew G. Knepley   PetscScalar   *array;
137fb1bcc12SMatthew G. Knepley   PetscInt       bs, n;
138fb1bcc12SMatthew G. Knepley   char           name[PETSC_MAX_PATH_LEN];
139fb1bcc12SMatthew G. Knepley   PetscMPIInt    commsize;
140fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
141fb1bcc12SMatthew G. Knepley 
142fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
143fb1bcc12SMatthew G. Knepley   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
144fb1bcc12SMatthew G. Knepley   ierr = DataBucketGetSizes(swarm->db, &n, NULL, NULL);CHKERRQ(ierr);
145fb1bcc12SMatthew G. Knepley   ierr = DMSwarmGetField(dm, fieldname, &bs, &type, (void **) &array);CHKERRQ(ierr);
146fb1bcc12SMatthew G. Knepley   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Only valid for PETSC_REAL");
147fb1bcc12SMatthew G. Knepley 
148fb1bcc12SMatthew G. Knepley   ierr = MPI_Comm_size(comm, &commsize);CHKERRQ(ierr);
149fb1bcc12SMatthew G. Knepley   if (commsize == 1) {
150fb1bcc12SMatthew G. Knepley     ierr = VecCreateSeqWithArray(comm, bs, n*bs, array, vec);CHKERRQ(ierr);
151fb1bcc12SMatthew G. Knepley   } else {
152fb1bcc12SMatthew G. Knepley     ierr = VecCreateMPIWithArray(comm, bs, n*bs, PETSC_DETERMINE, array, vec);CHKERRQ(ierr);
153fb1bcc12SMatthew G. Knepley   }
154fb1bcc12SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarmSharedField_%s", fieldname);CHKERRQ(ierr);
155fb1bcc12SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) *vec, name);CHKERRQ(ierr);
156fb1bcc12SMatthew G. Knepley 
157fb1bcc12SMatthew G. Knepley   /* Set guard */
158fb1bcc12SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr);
159fb1bcc12SMatthew G. Knepley   ierr = PetscObjectComposeFunction((PetscObject) *vec, name, DMSwarmDestroyVectorFromField_Private);CHKERRQ(ierr);
160fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
161fb1bcc12SMatthew G. Knepley }
162fb1bcc12SMatthew G. Knepley 
163fb1bcc12SMatthew G. Knepley /*@C
164d3a51819SDave May    DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field
165d3a51819SDave May 
166d3a51819SDave May    Collective on DM
167d3a51819SDave May 
168d3a51819SDave May    Input parameters:
16962741f57SDave May +  dm - a DMSwarm
17062741f57SDave May -  fieldname - the textual name given to a registered field
171d3a51819SDave May 
1728b8a3813SDave May    Output parameter:
173d3a51819SDave May .  vec - the vector
174d3a51819SDave May 
175d3a51819SDave May    Level: beginner
176d3a51819SDave May 
1778b8a3813SDave May    Notes:
1788b8a3813SDave May    The vector must be returned using a matching call to DMSwarmDestroyGlobalVectorFromField().
1798b8a3813SDave May 
1808b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyGlobalVectorFromField()
181d3a51819SDave May @*/
182b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
183b5bcf523SDave May {
184fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PetscObjectComm((PetscObject) dm);
185b5bcf523SDave May   PetscErrorCode ierr;
186b5bcf523SDave May 
187fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
188fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
189b5bcf523SDave May   PetscFunctionReturn(0);
190b5bcf523SDave May }
191b5bcf523SDave May 
192d3a51819SDave May /*@C
193d3a51819SDave May    DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field
194d3a51819SDave May 
195d3a51819SDave May    Collective on DM
196d3a51819SDave May 
197d3a51819SDave May    Input parameters:
19862741f57SDave May +  dm - a DMSwarm
19962741f57SDave May -  fieldname - the textual name given to a registered field
200d3a51819SDave May 
2018b8a3813SDave May    Output parameter:
202d3a51819SDave May .  vec - the vector
203d3a51819SDave May 
204d3a51819SDave May    Level: beginner
205d3a51819SDave May 
2068b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateGlobalVectorFromField()
207d3a51819SDave May @*/
208b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
209b5bcf523SDave May {
210b5bcf523SDave May   PetscErrorCode ierr;
211cc651181SDave May 
212fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
213fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
214b5bcf523SDave May   PetscFunctionReturn(0);
215b5bcf523SDave May }
216b5bcf523SDave May 
217fb1bcc12SMatthew G. Knepley /*@C
218fb1bcc12SMatthew G. Knepley    DMSwarmCreateLocalVectorFromField - Creates a Vec object sharing the array associated with a given field
219fb1bcc12SMatthew G. Knepley 
220fb1bcc12SMatthew G. Knepley    Collective on DM
221fb1bcc12SMatthew G. Knepley 
222fb1bcc12SMatthew G. Knepley    Input parameters:
22362741f57SDave May +  dm - a DMSwarm
22462741f57SDave May -  fieldname - the textual name given to a registered field
225fb1bcc12SMatthew G. Knepley 
2268b8a3813SDave May    Output parameter:
227fb1bcc12SMatthew G. Knepley .  vec - the vector
228fb1bcc12SMatthew G. Knepley 
229fb1bcc12SMatthew G. Knepley    Level: beginner
230fb1bcc12SMatthew G. Knepley 
2318b8a3813SDave May    Notes:
2328b8a3813SDave May    The vector must be returned using a matching call to DMSwarmDestroyLocalVectorFromField().
2338b8a3813SDave May 
2348b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyLocalVectorFromField()
235fb1bcc12SMatthew G. Knepley @*/
236fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmCreateLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
237bbe8250bSMatthew G. Knepley {
238fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PETSC_COMM_SELF;
239bbe8250bSMatthew G. Knepley   PetscErrorCode ierr;
240bbe8250bSMatthew G. Knepley 
241fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
242fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
243fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
244bbe8250bSMatthew G. Knepley }
245fb1bcc12SMatthew G. Knepley 
246fb1bcc12SMatthew G. Knepley /*@C
247fb1bcc12SMatthew G. Knepley    DMSwarmDestroyLocalVectorFromField - Destroys the Vec object which share the array associated with a given field
248fb1bcc12SMatthew G. Knepley 
249fb1bcc12SMatthew G. Knepley    Collective on DM
250fb1bcc12SMatthew G. Knepley 
251fb1bcc12SMatthew G. Knepley    Input parameters:
25262741f57SDave May +  dm - a DMSwarm
25362741f57SDave May -  fieldname - the textual name given to a registered field
254fb1bcc12SMatthew G. Knepley 
2558b8a3813SDave May    Output parameter:
256fb1bcc12SMatthew G. Knepley .  vec - the vector
257fb1bcc12SMatthew G. Knepley 
258fb1bcc12SMatthew G. Knepley    Level: beginner
259fb1bcc12SMatthew G. Knepley 
2608b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateLocalVectorFromField()
261fb1bcc12SMatthew G. Knepley @*/
262fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmDestroyLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
263fb1bcc12SMatthew G. Knepley {
264fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
265fb1bcc12SMatthew G. Knepley 
266fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
267fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
268bbe8250bSMatthew G. Knepley   PetscFunctionReturn(0);
269bbe8250bSMatthew G. Knepley }
270bbe8250bSMatthew G. Knepley 
271b5bcf523SDave May /*
272b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec)
273b5bcf523SDave May {
274b5bcf523SDave May   PetscFunctionReturn(0);
275b5bcf523SDave May }
276b5bcf523SDave May 
277b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec)
278b5bcf523SDave May {
279b5bcf523SDave May   PetscFunctionReturn(0);
280b5bcf523SDave May }
281b5bcf523SDave May */
282b5bcf523SDave May 
283d3a51819SDave May /*@C
284d3a51819SDave May    DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm
285d3a51819SDave May 
286d3a51819SDave May    Collective on DM
287d3a51819SDave May 
288d3a51819SDave May    Input parameter:
289d3a51819SDave May .  dm - a DMSwarm
290d3a51819SDave May 
291d3a51819SDave May    Level: beginner
292d3a51819SDave May 
293d3a51819SDave May    Notes:
2948b8a3813SDave May    After all fields have been registered, you must call DMSwarmFinalizeFieldRegister().
295d3a51819SDave May 
296d3a51819SDave May .seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
297d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
298d3a51819SDave May @*/
2995f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm)
3005f50eb2eSDave May {
3015f50eb2eSDave May   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
3023454631fSDave May   PetscErrorCode ierr;
3033454631fSDave May 
304521f74f9SMatthew G. Knepley   PetscFunctionBegin;
305cc651181SDave May   if (!swarm->field_registration_initialized) {
3065f50eb2eSDave May     swarm->field_registration_initialized = PETSC_TRUE;
307f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */
308f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */
309cc651181SDave May   }
3105f50eb2eSDave May   PetscFunctionReturn(0);
3115f50eb2eSDave May }
3125f50eb2eSDave May 
313d3a51819SDave May /*@C
314d3a51819SDave May    DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm
315d3a51819SDave May 
316d3a51819SDave May    Collective on DM
317d3a51819SDave May 
318d3a51819SDave May    Input parameter:
319d3a51819SDave May .  dm - a DMSwarm
320d3a51819SDave May 
321d3a51819SDave May    Level: beginner
322d3a51819SDave May 
323d3a51819SDave May    Notes:
32462741f57SDave May    After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined on the DMSwarm.
325d3a51819SDave May 
326d3a51819SDave May .seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
327d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
328d3a51819SDave May @*/
3295f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm)
3305f50eb2eSDave May {
3315f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3326845f8f5SDave May   PetscErrorCode ierr;
3336845f8f5SDave May 
334521f74f9SMatthew G. Knepley   PetscFunctionBegin;
335f0cdbbbaSDave May   if (!swarm->field_registration_finalized) {
3366845f8f5SDave May     ierr = DataBucketFinalize(swarm->db);CHKERRQ(ierr);
337f0cdbbbaSDave May   }
338f0cdbbbaSDave May   swarm->field_registration_finalized = PETSC_TRUE;
3395f50eb2eSDave May   PetscFunctionReturn(0);
3405f50eb2eSDave May }
3415f50eb2eSDave May 
342d3a51819SDave May /*@C
343d3a51819SDave May    DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm
344d3a51819SDave May 
345d3a51819SDave May    Not collective
346d3a51819SDave May 
347d3a51819SDave May    Input parameters:
34862741f57SDave May +  dm - a DMSwarm
349d3a51819SDave May .  nlocal - the length of each registered field
35062741f57SDave May -  buffer - the length of the buffer used to efficient dynamic re-sizing
351d3a51819SDave May 
352d3a51819SDave May    Level: beginner
353d3a51819SDave May 
354d3a51819SDave May .seealso: DMSwarmGetLocalSize()
355d3a51819SDave May @*/
3565f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer)
3575f50eb2eSDave May {
3585f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3596845f8f5SDave May   PetscErrorCode ierr;
3605f50eb2eSDave May 
361521f74f9SMatthew G. Knepley   PetscFunctionBegin;
362f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr);
3636845f8f5SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr);
364f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr);
3655f50eb2eSDave May   PetscFunctionReturn(0);
3665f50eb2eSDave May }
3675f50eb2eSDave May 
368d3a51819SDave May /*@C
369d3a51819SDave May    DMSwarmSetCellDM - Attachs a DM to a DMSwarm
370d3a51819SDave May 
371d3a51819SDave May    Collective on DM
372d3a51819SDave May 
373d3a51819SDave May    Input parameters:
37462741f57SDave May +  dm - a DMSwarm
37562741f57SDave May -  dmcell - the DM to attach to the DMSwarm
376d3a51819SDave May 
377d3a51819SDave May    Level: beginner
378d3a51819SDave May 
379d3a51819SDave May    Notes:
380d3a51819SDave May    The attached DM (dmcell) will be queried for point location and
3818b8a3813SDave May    neighbor MPI-rank information if DMSwarmMigrate() is called.
382d3a51819SDave May 
3838b8a3813SDave May .seealso: DMSwarmSetType(), DMSwarmGetCellDM(), DMSwarmMigrate()
384d3a51819SDave May @*/
385b16650c8SDave May PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell)
386b16650c8SDave May {
387b16650c8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
388521f74f9SMatthew G. Knepley 
389521f74f9SMatthew G. Knepley   PetscFunctionBegin;
390b16650c8SDave May   swarm->dmcell = dmcell;
391b16650c8SDave May   PetscFunctionReturn(0);
392b16650c8SDave May }
393b16650c8SDave May 
394d3a51819SDave May /*@C
395d3a51819SDave May    DMSwarmGetCellDM - Fetches the attached cell DM
396d3a51819SDave May 
397d3a51819SDave May    Collective on DM
398d3a51819SDave May 
399d3a51819SDave May    Input parameter:
400d3a51819SDave May .  dm - a DMSwarm
401d3a51819SDave May 
402d3a51819SDave May    Output parameter:
403d3a51819SDave May .  dmcell - the DM which was attached to the DMSwarm
404d3a51819SDave May 
405d3a51819SDave May    Level: beginner
406d3a51819SDave May 
407d3a51819SDave May .seealso: DMSwarmSetCellDM()
408d3a51819SDave May @*/
409fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell)
410fe39f135SDave May {
411fe39f135SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
412521f74f9SMatthew G. Knepley 
413521f74f9SMatthew G. Knepley   PetscFunctionBegin;
414fe39f135SDave May   *dmcell = swarm->dmcell;
415fe39f135SDave May   PetscFunctionReturn(0);
416fe39f135SDave May }
417fe39f135SDave May 
418d3a51819SDave May /*@C
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 
4318b8a3813SDave May .seealso: DMSwarmGetSize(), 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    DMSwarmGetSize - Retrives the total length of fields registered
445d3a51819SDave May 
446d3a51819SDave May    Collective on DM
447d3a51819SDave May 
448d3a51819SDave May    Input parameter:
449d3a51819SDave May .  dm - a DMSwarm
450d3a51819SDave May 
451d3a51819SDave May    Output parameter:
452d3a51819SDave May .  n - the total length of each registered field
453d3a51819SDave May 
454d3a51819SDave May    Level: beginner
455d3a51819SDave May 
456d3a51819SDave May    Note:
457d3a51819SDave May    This calls MPI_Allreduce upon each call (inefficient but safe)
458d3a51819SDave May 
4598b8a3813SDave May .seealso: DMSwarmGetLocalSize(), DMSwarmSetLocalSizes()
460d3a51819SDave May @*/
461dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n)
462dcf43ee8SDave May {
463dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
464dcf43ee8SDave May   PetscErrorCode ierr;
465dcf43ee8SDave May   PetscInt nlocal,ng;
466dcf43ee8SDave May 
467521f74f9SMatthew G. Knepley   PetscFunctionBegin;
468dcf43ee8SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
469dcf43ee8SDave May   ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
470dcf43ee8SDave May   if (n) { *n = ng; }
471dcf43ee8SDave May   PetscFunctionReturn(0);
472dcf43ee8SDave May }
473dcf43ee8SDave May 
474d3a51819SDave May /*@C
4758b8a3813SDave May    DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm with a native PETSc data type
476d3a51819SDave May 
477d3a51819SDave May    Collective on DM
478d3a51819SDave May 
479d3a51819SDave May    Input parameters:
48062741f57SDave May +  dm - a DMSwarm
481d3a51819SDave May .  fieldname - the textual name to identify this field
482d3a51819SDave May .  blocksize - the number of each data type
48362741f57SDave May -  type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG)
484d3a51819SDave May 
485d3a51819SDave May    Level: beginner
486d3a51819SDave May 
487d3a51819SDave May    Notes:
4888b8a3813SDave May    The textual name for each registered field must be unique.
489d3a51819SDave May 
490d3a51819SDave May .seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
491d3a51819SDave May @*/
4925f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
493b62e03f8SDave May {
4942eac95f8SDave May   PetscErrorCode ierr;
495b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
496b62e03f8SDave May   size_t size;
497b62e03f8SDave May 
498521f74f9SMatthew G. Knepley   PetscFunctionBegin;
4995f50eb2eSDave May   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
5005f50eb2eSDave May   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
5015f50eb2eSDave May 
5025f50eb2eSDave May   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5035f50eb2eSDave May   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5045f50eb2eSDave May   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5055f50eb2eSDave May   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5065f50eb2eSDave May   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
507b62e03f8SDave May 
5082ddcf43eSMatthew G. Knepley   ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr);
509b62e03f8SDave May   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
51052c3ed93SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
51152c3ed93SDave May   {
51252c3ed93SDave May     DataField gfield;
51352c3ed93SDave May 
51452c3ed93SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
51552c3ed93SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
51652c3ed93SDave May   }
517b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
518b62e03f8SDave May   PetscFunctionReturn(0);
519b62e03f8SDave May }
520b62e03f8SDave May 
521d3a51819SDave May /*@C
522d3a51819SDave May    DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm
523d3a51819SDave May 
524d3a51819SDave May    Collective on DM
525d3a51819SDave May 
526d3a51819SDave May    Input parameters:
52762741f57SDave May +  dm - a DMSwarm
528d3a51819SDave May .  fieldname - the textual name to identify this field
52962741f57SDave May -  size - the size in bytes of the user struct of each data type
530d3a51819SDave May 
531d3a51819SDave May    Level: beginner
532d3a51819SDave May 
533d3a51819SDave May    Notes:
5348b8a3813SDave May    The textual name for each registered field must be unique.
535d3a51819SDave May 
536d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField()
537d3a51819SDave May @*/
5385f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
539b62e03f8SDave May {
5402eac95f8SDave May   PetscErrorCode ierr;
541b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
542b62e03f8SDave May 
543521f74f9SMatthew G. Knepley   PetscFunctionBegin;
5442eac95f8SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
545b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
546b62e03f8SDave May   PetscFunctionReturn(0);
547b62e03f8SDave May }
548b62e03f8SDave May 
549d3a51819SDave May /*@C
550d3a51819SDave May    DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm
551d3a51819SDave May 
552d3a51819SDave May    Collective on DM
553d3a51819SDave May 
554d3a51819SDave May    Input parameters:
55562741f57SDave May +  dm - a DMSwarm
556d3a51819SDave May .  fieldname - the textual name to identify this field
557d3a51819SDave May .  size - the size in bytes of the user data type
55862741f57SDave May -  blocksize - the number of each data type
559d3a51819SDave May 
560d3a51819SDave May    Level: beginner
561d3a51819SDave May 
562d3a51819SDave May    Notes:
5638b8a3813SDave May    The textual name for each registered field must be unique.
564d3a51819SDave May 
565d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
566d3a51819SDave May @*/
567320740a0SDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize)
568b62e03f8SDave May {
569b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
5706845f8f5SDave May   PetscErrorCode ierr;
571b62e03f8SDave May 
572521f74f9SMatthew G. Knepley   PetscFunctionBegin;
573320740a0SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
574320740a0SDave May   {
575320740a0SDave May     DataField gfield;
576320740a0SDave May 
577320740a0SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
578320740a0SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
579320740a0SDave May   }
580b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
581b62e03f8SDave May   PetscFunctionReturn(0);
582b62e03f8SDave May }
583b62e03f8SDave May 
584d3a51819SDave May /*@C
585d3a51819SDave May    DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field
586d3a51819SDave May 
587d3a51819SDave May    Not collective
588d3a51819SDave May 
589d3a51819SDave May    Input parameters:
59062741f57SDave May +  dm - a DMSwarm
59162741f57SDave May -  fieldname - the textual name to identify this field
592d3a51819SDave May 
593d3a51819SDave May    Output parameters:
59462741f57SDave May +  blocksize - the number of each data type
595d3a51819SDave May .  type - the data type
59662741f57SDave May -  data - pointer to raw array
597d3a51819SDave May 
598d3a51819SDave May    Level: beginner
599d3a51819SDave May 
600d3a51819SDave May    Notes:
6018b8a3813SDave May    The array must be returned using a matching call to DMSwarmRestoreField().
602d3a51819SDave May 
603d3a51819SDave May .seealso: DMSwarmRestoreField()
604d3a51819SDave May @*/
6055f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
606b62e03f8SDave May {
607b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
608b62e03f8SDave May   DataField gfield;
6092eac95f8SDave May   PetscErrorCode ierr;
610b62e03f8SDave May 
611521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6123454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
6132eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6146845f8f5SDave May   ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr);
6156845f8f5SDave May   ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr);
6161b1ea282SDave May   if (blocksize) {*blocksize = gfield->bs; }
617b5bcf523SDave May   if (type) { *type = gfield->petsc_type; }
618b62e03f8SDave May   PetscFunctionReturn(0);
619b62e03f8SDave May }
620b62e03f8SDave May 
621d3a51819SDave May /*@C
622d3a51819SDave May    DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field
623d3a51819SDave May 
624d3a51819SDave May    Not collective
625d3a51819SDave May 
626d3a51819SDave May    Input parameters:
62762741f57SDave May +  dm - a DMSwarm
62862741f57SDave May -  fieldname - the textual name to identify this field
629d3a51819SDave May 
630d3a51819SDave May    Output parameters:
63162741f57SDave May +  blocksize - the number of each data type
632d3a51819SDave May .  type - the data type
63362741f57SDave May -  data - pointer to raw array
634d3a51819SDave May 
635d3a51819SDave May    Level: beginner
636d3a51819SDave May 
637d3a51819SDave May    Notes:
6388b8a3813SDave May    The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField().
639d3a51819SDave May 
640d3a51819SDave May .seealso: DMSwarmGetField()
641d3a51819SDave May @*/
6425f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
643b62e03f8SDave May {
644b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
645b62e03f8SDave May   DataField gfield;
6462eac95f8SDave May   PetscErrorCode ierr;
647b62e03f8SDave May 
648521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6492eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6506845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
651b62e03f8SDave May   if (data) *data = NULL;
652b62e03f8SDave May   PetscFunctionReturn(0);
653b62e03f8SDave May }
654b62e03f8SDave May 
655d3a51819SDave May /*@C
656d3a51819SDave May    DMSwarmAddPoint - Add space for one new point in the DMSwarm
657d3a51819SDave May 
658d3a51819SDave May    Not collective
659d3a51819SDave May 
660d3a51819SDave May    Input parameter:
661d3a51819SDave May .  dm - a DMSwarm
662d3a51819SDave May 
663d3a51819SDave May    Level: beginner
664d3a51819SDave May 
665d3a51819SDave May    Notes:
6668b8a3813SDave May    The new point will have all fields initialized to zero.
667d3a51819SDave May 
668d3a51819SDave May .seealso: DMSwarmAddNPoints()
669d3a51819SDave May @*/
670cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
671cb1d1399SDave May {
672cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
673cb1d1399SDave May   PetscErrorCode ierr;
674cb1d1399SDave May 
675521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6763454631fSDave May   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
677f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr);
678cb1d1399SDave May   ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr);
679f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr);
680cb1d1399SDave May   PetscFunctionReturn(0);
681cb1d1399SDave May }
682cb1d1399SDave May 
683d3a51819SDave May /*@C
684d3a51819SDave May    DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm
685d3a51819SDave May 
686d3a51819SDave May    Not collective
687d3a51819SDave May 
688d3a51819SDave May    Input parameters:
68962741f57SDave May +  dm - a DMSwarm
69062741f57SDave May -  npoints - the number of new points to add
691d3a51819SDave May 
692d3a51819SDave May    Level: beginner
693d3a51819SDave May 
694d3a51819SDave May    Notes:
6958b8a3813SDave May    The new point will have all fields initialized to zero.
696d3a51819SDave May 
697d3a51819SDave May .seealso: DMSwarmAddPoint()
698d3a51819SDave May @*/
699cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
700cb1d1399SDave May {
701cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
702cb1d1399SDave May   PetscErrorCode ierr;
703cb1d1399SDave May   PetscInt nlocal;
704cb1d1399SDave May 
705521f74f9SMatthew G. Knepley   PetscFunctionBegin;
706f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr);
707cb1d1399SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
708cb1d1399SDave May   nlocal = nlocal + npoints;
70965141ba8SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,DATA_BUCKET_BUFFER_DEFAULT);CHKERRQ(ierr);
710f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr);
711cb1d1399SDave May   PetscFunctionReturn(0);
712cb1d1399SDave May }
713cb1d1399SDave May 
714d3a51819SDave May /*@C
715d3a51819SDave May    DMSwarmRemovePoint - Remove the last point from the DMSwarm
716d3a51819SDave May 
717d3a51819SDave May    Not collective
718d3a51819SDave May 
719d3a51819SDave May    Input parameter:
720d3a51819SDave May .  dm - a DMSwarm
721d3a51819SDave May 
722d3a51819SDave May    Level: beginner
723d3a51819SDave May 
724d3a51819SDave May .seealso: DMSwarmRemovePointAtIndex()
725d3a51819SDave May @*/
726cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
727cb1d1399SDave May {
728cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
729cb1d1399SDave May   PetscErrorCode ierr;
730cb1d1399SDave May 
731521f74f9SMatthew G. Knepley   PetscFunctionBegin;
732f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr);
733cb1d1399SDave May   ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
734f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr);
735cb1d1399SDave May   PetscFunctionReturn(0);
736cb1d1399SDave May }
737cb1d1399SDave May 
738d3a51819SDave May /*@C
739d3a51819SDave May    DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm
740d3a51819SDave May 
741d3a51819SDave May    Not collective
742d3a51819SDave May 
743d3a51819SDave May    Input parameters:
74462741f57SDave May +  dm - a DMSwarm
74562741f57SDave May -  idx - index of point to remove
746d3a51819SDave May 
747d3a51819SDave May    Level: beginner
748d3a51819SDave May 
749d3a51819SDave May .seealso: DMSwarmRemovePoint()
750d3a51819SDave May @*/
751cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
752cb1d1399SDave May {
753cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
754cb1d1399SDave May   PetscErrorCode ierr;
755cb1d1399SDave May 
756521f74f9SMatthew G. Knepley   PetscFunctionBegin;
757f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr);
758cb1d1399SDave May   ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
759f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr);
760cb1d1399SDave May   PetscFunctionReturn(0);
761cb1d1399SDave May }
762b62e03f8SDave May 
763ba4fc9c6SDave May /*@C
764ba4fc9c6SDave May    DMSwarmCopyPoint - Copy point pj to point pi in the DMSwarm
765ba4fc9c6SDave May 
766ba4fc9c6SDave May    Not collective
767ba4fc9c6SDave May 
768ba4fc9c6SDave May    Input parameters:
769ba4fc9c6SDave May +  dm - a DMSwarm
770ba4fc9c6SDave May .  pi - the index of the point to copy
771ba4fc9c6SDave May -  pj - the point index where the copy should be located
772ba4fc9c6SDave May 
773ba4fc9c6SDave May  Level: beginner
774ba4fc9c6SDave May 
775ba4fc9c6SDave May .seealso: DMSwarmRemovePoint()
776ba4fc9c6SDave May @*/
777ba4fc9c6SDave May PETSC_EXTERN PetscErrorCode DMSwarmCopyPoint(DM dm,PetscInt pi,PetscInt pj)
778ba4fc9c6SDave May {
779ba4fc9c6SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
780ba4fc9c6SDave May   PetscErrorCode ierr;
781ba4fc9c6SDave May 
782ba4fc9c6SDave May   PetscFunctionBegin;
783ba4fc9c6SDave May   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
784ba4fc9c6SDave May   ierr = DataBucketCopyPoint(swarm->db,pi,swarm->db,pj);CHKERRQ(ierr);
785ba4fc9c6SDave May   PetscFunctionReturn(0);
786ba4fc9c6SDave May }
787ba4fc9c6SDave May 
788095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points)
7893454631fSDave May {
790dcf43ee8SDave May   PetscErrorCode ierr;
791521f74f9SMatthew G. Knepley 
792521f74f9SMatthew G. Knepley   PetscFunctionBegin;
793dcf43ee8SDave May   ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr);
7943454631fSDave May   PetscFunctionReturn(0);
7953454631fSDave May }
7963454631fSDave May 
797d3a51819SDave May /*@C
798d3a51819SDave May    DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks
799d3a51819SDave May 
800d3a51819SDave May    Collective on DM
801d3a51819SDave May 
802d3a51819SDave May    Input parameters:
80362741f57SDave May +  dm - the DMSwarm
80462741f57SDave May -  remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank
805d3a51819SDave May 
806d3a51819SDave May    Notes:
8078b8a3813SDave May    The DM will be modified to accomodate received points.
8088b8a3813SDave May    If remove_sent_points = PETSC_TRUE, any points that were sent will be removed from the DM.
8098b8a3813SDave May    Different styles of migration are supported. See DMSwarmSetMigrateType().
810d3a51819SDave May 
811d3a51819SDave May    Level: advanced
812d3a51819SDave May 
813d3a51819SDave May .seealso: DMSwarmSetMigrateType()
814d3a51819SDave May @*/
815095059a4SDave May PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points)
8163454631fSDave May {
817f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8183454631fSDave May   PetscErrorCode ierr;
819f0cdbbbaSDave May 
820521f74f9SMatthew G. Knepley   PetscFunctionBegin;
821ed923d71SDave May   ierr = PetscLogEventBegin(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr);
822f0cdbbbaSDave May   switch (swarm->migrate_type) {
823f0cdbbbaSDave May     case DMSWARM_MIGRATE_BASIC:
824095059a4SDave May       ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr);
825f0cdbbbaSDave May       break;
826f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLNSCATTER:
827f0cdbbbaSDave May       ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr);
828f0cdbbbaSDave May       break;
829f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLEXACT:
830f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented");
831521f74f9SMatthew G. Knepley       /*ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr);*/
832f0cdbbbaSDave May       break;
833f0cdbbbaSDave May     case DMSWARM_MIGRATE_USER:
834f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented");
835521f74f9SMatthew G. Knepley       /*ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr);*/
836f0cdbbbaSDave May       break;
837f0cdbbbaSDave May     default:
838f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown");
839f0cdbbbaSDave May       break;
840f0cdbbbaSDave May   }
841ed923d71SDave May   ierr = PetscLogEventEnd(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr);
8423454631fSDave May   PetscFunctionReturn(0);
8433454631fSDave May }
8443454631fSDave May 
845f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize);
846f0cdbbbaSDave May 
847d3a51819SDave May /*
848d3a51819SDave May  DMSwarmCollectViewCreate
849d3a51819SDave May 
850d3a51819SDave May  * Applies a collection method and gathers point neighbour points into dm
851d3a51819SDave May 
852d3a51819SDave May  Notes:
8538b8a3813SDave May  Users should call DMSwarmCollectViewDestroy() after
854d3a51819SDave May  they have finished computations associated with the collected points
855d3a51819SDave May */
856d3a51819SDave May 
857d3a51819SDave May /*@C
858d3a51819SDave May    DMSwarmCollectViewCreate - Applies a collection method and gathers points
859d3a51819SDave May    in neighbour MPI-ranks into the DMSwarm
860d3a51819SDave May 
861d3a51819SDave May    Collective on DM
862d3a51819SDave May 
863d3a51819SDave May    Input parameter:
864d3a51819SDave May .  dm - the DMSwarm
865d3a51819SDave May 
866d3a51819SDave May    Notes:
867d3a51819SDave May    Users should call DMSwarmCollectViewDestroy() after
868d3a51819SDave May    they have finished computations associated with the collected points
8698b8a3813SDave May    Different collect methods are supported. See DMSwarmSetCollectType().
870d3a51819SDave May 
871d3a51819SDave May    Level: advanced
872d3a51819SDave May 
873d3a51819SDave May .seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType()
874d3a51819SDave May @*/
875fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm)
8762712d1f2SDave May {
8772712d1f2SDave May   PetscErrorCode ierr;
8782712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8792712d1f2SDave May   PetscInt ng;
8802712d1f2SDave May 
881521f74f9SMatthew G. Knepley   PetscFunctionBegin;
882480eef7bSDave May   if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active");
883480eef7bSDave May   ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr);
884480eef7bSDave May   switch (swarm->collect_type) {
885f0cdbbbaSDave May 
886480eef7bSDave May     case DMSWARM_COLLECT_BASIC:
8872712d1f2SDave May       ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr);
888480eef7bSDave May       break;
889480eef7bSDave May     case DMSWARM_COLLECT_DMDABOUNDINGBOX:
890f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented");
891521f74f9SMatthew G. Knepley       /*ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr);*/
892480eef7bSDave May       break;
893480eef7bSDave May     case DMSWARM_COLLECT_GENERAL:
894f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented");
895521f74f9SMatthew G. Knepley       /*ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr);*/
896480eef7bSDave May       break;
897480eef7bSDave May     default:
898f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown");
899480eef7bSDave May       break;
900480eef7bSDave May   }
901480eef7bSDave May   swarm->collect_view_active = PETSC_TRUE;
902480eef7bSDave May   swarm->collect_view_reset_nlocal = ng;
9032712d1f2SDave May   PetscFunctionReturn(0);
9042712d1f2SDave May }
9052712d1f2SDave May 
906d3a51819SDave May /*@C
907d3a51819SDave May    DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate()
908d3a51819SDave May 
909d3a51819SDave May    Collective on DM
910d3a51819SDave May 
911d3a51819SDave May    Input parameters:
912d3a51819SDave May .  dm - the DMSwarm
913d3a51819SDave May 
914d3a51819SDave May    Notes:
915d3a51819SDave May    Users should call DMSwarmCollectViewCreate() before this function is called.
916d3a51819SDave May 
917d3a51819SDave May    Level: advanced
918d3a51819SDave May 
919d3a51819SDave May .seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType()
920d3a51819SDave May @*/
921fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm)
9222712d1f2SDave May {
9232712d1f2SDave May   PetscErrorCode ierr;
9242712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9252712d1f2SDave May 
926521f74f9SMatthew G. Knepley   PetscFunctionBegin;
927480eef7bSDave May   if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active");
928480eef7bSDave May   ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr);
929480eef7bSDave May   swarm->collect_view_active = PETSC_FALSE;
9302712d1f2SDave May   PetscFunctionReturn(0);
9312712d1f2SDave May }
9323454631fSDave May 
933f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm)
934f0cdbbbaSDave May {
935f0cdbbbaSDave May   PetscInt dim;
936f0cdbbbaSDave May   PetscErrorCode ierr;
937f0cdbbbaSDave May 
938521f74f9SMatthew G. Knepley   PetscFunctionBegin;
939f0cdbbbaSDave May   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
940f0cdbbbaSDave May   if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
941f0cdbbbaSDave May   if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
942f0cdbbbaSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr);
943e2d107dbSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_cellid,1,PETSC_INT);CHKERRQ(ierr);
944f0cdbbbaSDave May   PetscFunctionReturn(0);
945f0cdbbbaSDave May }
946f0cdbbbaSDave May 
947d3a51819SDave May /*@C
948d3a51819SDave May    DMSwarmSetType - Set particular flavor of DMSwarm
949d3a51819SDave May 
950d3a51819SDave May    Collective on DM
951d3a51819SDave May 
952d3a51819SDave May    Input parameters:
95362741f57SDave May +  dm - the DMSwarm
95462741f57SDave May -  stype - the DMSwarm type (e.g. DMSWARM_PIC)
955d3a51819SDave May 
956d3a51819SDave May    Level: advanced
957d3a51819SDave May 
958d3a51819SDave May .seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType()
959d3a51819SDave May @*/
960f0cdbbbaSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype)
961f0cdbbbaSDave May {
962f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
963f0cdbbbaSDave May   PetscErrorCode ierr;
964f0cdbbbaSDave May 
965521f74f9SMatthew G. Knepley   PetscFunctionBegin;
966f0cdbbbaSDave May   swarm->swarm_type = stype;
967f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
968f0cdbbbaSDave May     ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr);
969f0cdbbbaSDave May   }
970f0cdbbbaSDave May   PetscFunctionReturn(0);
971f0cdbbbaSDave May }
972f0cdbbbaSDave May 
9733454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm)
9743454631fSDave May {
9753454631fSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9763454631fSDave May   PetscErrorCode ierr;
9773454631fSDave May   PetscMPIInt rank;
9783454631fSDave May   PetscInt p,npoints,*rankval;
9793454631fSDave May 
980521f74f9SMatthew G. Knepley   PetscFunctionBegin;
9813454631fSDave May   if (swarm->issetup) PetscFunctionReturn(0);
9823454631fSDave May 
9833454631fSDave May   swarm->issetup = PETSC_TRUE;
9843454631fSDave May 
985f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
986f0cdbbbaSDave May     /* check dmcell exists */
987f0cdbbbaSDave May     if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM");
988f0cdbbbaSDave May 
989f0cdbbbaSDave May     if (swarm->dmcell->ops->locatepointssubdomain) {
990f0cdbbbaSDave May       /* check methods exists for exact ownership identificiation */
991521f74f9SMatthew G. Knepley       ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");CHKERRQ(ierr);
992f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT;
993f0cdbbbaSDave May     } else {
994f0cdbbbaSDave May       /* check methods exist for point location AND rank neighbor identification */
995f0cdbbbaSDave May       if (swarm->dmcell->ops->locatepoints) {
996521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->LocatePoints\n");CHKERRQ(ierr);
997f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined");
998f0cdbbbaSDave May 
999f0cdbbbaSDave May       if (swarm->dmcell->ops->getneighbors) {
1000521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->GetNeigbors\n");CHKERRQ(ierr);
1001f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined");
1002f0cdbbbaSDave May 
1003f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER;
1004f0cdbbbaSDave May     }
1005f0cdbbbaSDave May   }
1006f0cdbbbaSDave May 
1007f0cdbbbaSDave May   ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr);
1008f0cdbbbaSDave May 
10093454631fSDave May   /* check some fields were registered */
10103454631fSDave May   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
10113454631fSDave May 
10123454631fSDave May   /* check local sizes were set */
10133454631fSDave May   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
10143454631fSDave May 
10153454631fSDave May   /* initialize values in pid and rank placeholders */
10163454631fSDave May   /* TODO: [pid - use MPI_Scan] */
10173454631fSDave May   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
10183454631fSDave May   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
1019f0cdbbbaSDave May   ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10203454631fSDave May   for (p=0; p<npoints; p++) {
10213454631fSDave May     rankval[p] = (PetscInt)rank;
10223454631fSDave May   }
1023f0cdbbbaSDave May   ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10243454631fSDave May   PetscFunctionReturn(0);
10253454631fSDave May }
10263454631fSDave May 
1027dc5f5ce9SDave May extern PetscErrorCode DMSwarmSortDestroy(DMSwarmSort *_ctx);
1028dc5f5ce9SDave May 
102957795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm)
103057795646SDave May {
103157795646SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
103257795646SDave May   PetscErrorCode ierr;
103357795646SDave May 
103457795646SDave May   PetscFunctionBegin;
10356845f8f5SDave May   ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr);
1036dc5f5ce9SDave May   if (swarm->sort_context) {
1037dc5f5ce9SDave May     ierr = DMSwarmSortDestroy(&swarm->sort_context);CHKERRQ(ierr);
1038dc5f5ce9SDave May   }
103957795646SDave May   ierr = PetscFree(swarm);CHKERRQ(ierr);
104057795646SDave May   PetscFunctionReturn(0);
104157795646SDave May }
104257795646SDave May 
1043a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer)
1044a9ee3421SMatthew G. Knepley {
1045a9ee3421SMatthew G. Knepley   DM             cdm;
1046a9ee3421SMatthew G. Knepley   PetscDraw      draw;
1047a9ee3421SMatthew G. Knepley   PetscReal     *coords, oldPause;
1048a9ee3421SMatthew G. Knepley   PetscInt       Np, p, bs;
1049a9ee3421SMatthew G. Knepley   PetscErrorCode ierr;
1050a9ee3421SMatthew G. Knepley 
1051a9ee3421SMatthew G. Knepley   PetscFunctionBegin;
1052a9ee3421SMatthew G. Knepley   ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr);
1053a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr);
1054a9ee3421SMatthew G. Knepley   ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr);
1055a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr);
1056a9ee3421SMatthew G. Knepley   ierr = DMView(cdm, viewer);CHKERRQ(ierr);
1057a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr);
1058a9ee3421SMatthew G. Knepley 
1059a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr);
1060a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1061a9ee3421SMatthew G. Knepley   for (p = 0; p < Np; ++p) {
1062a9ee3421SMatthew G. Knepley     const PetscInt i = p*bs;
1063a9ee3421SMatthew G. Knepley 
1064a9ee3421SMatthew G. Knepley     ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], 0.01, 0.01, PETSC_DRAW_BLUE);CHKERRQ(ierr);
1065a9ee3421SMatthew G. Knepley   }
1066a9ee3421SMatthew G. Knepley   ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1067a9ee3421SMatthew G. Knepley   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
1068a9ee3421SMatthew G. Knepley   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
1069a9ee3421SMatthew G. Knepley   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1070a9ee3421SMatthew G. Knepley   PetscFunctionReturn(0);
1071a9ee3421SMatthew G. Knepley }
1072a9ee3421SMatthew G. Knepley 
10735f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
10745f50eb2eSDave May {
10755f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1076a9ee3421SMatthew G. Knepley   PetscBool      iascii,ibinary,ishdf5,isvtk,isdraw;
10775f50eb2eSDave May   PetscErrorCode ierr;
10785f50eb2eSDave May 
10795f50eb2eSDave May   PetscFunctionBegin;
10805f50eb2eSDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10815f50eb2eSDave May   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
10825f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
10835f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
10845f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
10855f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1086a9ee3421SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW,  &isdraw);CHKERRQ(ierr);
10875f50eb2eSDave May   if (iascii) {
10886845f8f5SDave May     ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
10895f50eb2eSDave May   } else if (ibinary) {
1090a9ee3421SMatthew G. Knepley     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support");
10915f50eb2eSDave May   } else if (ishdf5) {
10925f50eb2eSDave May #if defined(PETSC_HAVE_HDF5)
10935f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
10945f50eb2eSDave May #else
10955f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
10965f50eb2eSDave May #endif
10975f50eb2eSDave May   } else if (isvtk) {
10985f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
1099a9ee3421SMatthew G. Knepley   } else if (isdraw) {
1100a9ee3421SMatthew G. Knepley     ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr);
11015f50eb2eSDave May   }
11025f50eb2eSDave May   PetscFunctionReturn(0);
11035f50eb2eSDave May }
11045f50eb2eSDave May 
1105d3a51819SDave May /*MC
1106d3a51819SDave May 
1107d3a51819SDave May  DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type.
110862741f57SDave May  This implementation was designed for particle methods in which the underlying
1109d3a51819SDave May  data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type.
1110d3a51819SDave May 
111162741f57SDave May  User data can be represented by DMSwarm through a registering "fields".
111262741f57SDave May  To register a field, the user must provide;
111362741f57SDave May  (a) a unique name;
111462741f57SDave May  (b) the data type (or size in bytes);
111562741f57SDave May  (c) the block size of the data.
1116d3a51819SDave May 
1117d3a51819SDave May  For example, suppose the application requires a unique id, energy, momentum and density to be stored
111862741f57SDave May  on a set of of particles. Then the following code could be used
1119d3a51819SDave May 
112062741f57SDave May $    DMSwarmInitializeFieldRegister(dm)
112162741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG);
112262741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL);
112362741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL);
112462741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT);
112562741f57SDave May $    DMSwarmFinalizeFieldRegister(dm)
1126d3a51819SDave May 
1127d3a51819SDave May  The fields represented by DMSwarm are dynamic and can be re-sized at any time.
112862741f57SDave May  The only restriction imposed by DMSwarm is that all fields contain the same number of points.
1129d3a51819SDave May 
1130d3a51819SDave May  To support particle methods, "migration" techniques are provided. These methods migrate data
1131d3a51819SDave May  between MPI-ranks.
1132d3a51819SDave May 
1133d3a51819SDave May  DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector().
1134d3a51819SDave May  As a DMSwarm may internally define and store values of different data types,
113562741f57SDave May  before calling DMCreateGlobalVector() or DMCreateLocalVector(), the user must inform DMSwarm which
1136d3a51819SDave May  fields should be used to define a Vec object via
1137d3a51819SDave May    DMSwarmVectorDefineField()
1138d3a51819SDave May  The specified field can can changed be changed at any time - thereby permitting vectors
1139d3a51819SDave May  compatable with different fields to be created.
1140d3a51819SDave May 
114162741f57SDave May  A dual representation of fields in the DMSwarm and a Vec object is permitted via
1142d3a51819SDave May    DMSwarmCreateGlobalVectorFromField()
1143d3a51819SDave May  Here the data defining the field in the DMSwarm is shared with a Vec.
1144d3a51819SDave May  This is inherently unsafe if you alter the size of the field at any time between
1145d3a51819SDave May  calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField().
1146cc651181SDave May  If the local size of the DMSwarm does not match the local size of the global vector
1147cc651181SDave May  when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown.
1148d3a51819SDave May 
114962741f57SDave May  Additional high-level support is provided for Particle-In-Cell methods.
115062741f57SDave May  Please refer to the man page for DMSwarmSetType().
115162741f57SDave May 
1152d3a51819SDave May  Level: beginner
1153d3a51819SDave May 
1154d3a51819SDave May .seealso: DMType, DMCreate(), DMSetType()
1155d3a51819SDave May M*/
115657795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
115757795646SDave May {
115857795646SDave May   DM_Swarm      *swarm;
115957795646SDave May   PetscErrorCode ierr;
116057795646SDave May 
116157795646SDave May   PetscFunctionBegin;
116257795646SDave May   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
116357795646SDave May   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
1164f0cdbbbaSDave May   dm->data = swarm;
116557795646SDave May 
11666845f8f5SDave May   ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr);
1167f0cdbbbaSDave May   ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr);
1168f0cdbbbaSDave May 
1169b5bcf523SDave May   swarm->vec_field_set = PETSC_FALSE;
11703454631fSDave May   swarm->issetup = PETSC_FALSE;
1171480eef7bSDave May   swarm->swarm_type = DMSWARM_BASIC;
1172480eef7bSDave May   swarm->migrate_type = DMSWARM_MIGRATE_BASIC;
1173480eef7bSDave May   swarm->collect_type = DMSWARM_COLLECT_BASIC;
117440c453e9SDave May   swarm->migrate_error_on_missing_point = PETSC_FALSE;
1175b62e03f8SDave May 
1176f0cdbbbaSDave May   swarm->dmcell = NULL;
1177f0cdbbbaSDave May   swarm->collect_view_active = PETSC_FALSE;
1178f0cdbbbaSDave May   swarm->collect_view_reset_nlocal = -1;
117957795646SDave May 
1180f0cdbbbaSDave May   dm->dim  = 0;
11815f50eb2eSDave May   dm->ops->view                            = DMView_Swarm;
118257795646SDave May   dm->ops->load                            = NULL;
118357795646SDave May   dm->ops->setfromoptions                  = NULL;
118457795646SDave May   dm->ops->clone                           = NULL;
11853454631fSDave May   dm->ops->setup                           = DMSetup_Swarm;
118657795646SDave May   dm->ops->createdefaultsection            = NULL;
118757795646SDave May   dm->ops->createdefaultconstraints        = NULL;
1188b5bcf523SDave May   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
1189b5bcf523SDave May   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
119057795646SDave May   dm->ops->getlocaltoglobalmapping         = NULL;
119157795646SDave May   dm->ops->createfieldis                   = NULL;
119257795646SDave May   dm->ops->createcoordinatedm              = NULL;
119357795646SDave May   dm->ops->getcoloring                     = NULL;
119457795646SDave May   dm->ops->creatematrix                    = NULL;
119557795646SDave May   dm->ops->createinterpolation             = NULL;
119657795646SDave May   dm->ops->getaggregates                   = NULL;
119757795646SDave May   dm->ops->getinjection                    = NULL;
119857795646SDave May   dm->ops->refine                          = NULL;
119957795646SDave May   dm->ops->coarsen                         = NULL;
120057795646SDave May   dm->ops->refinehierarchy                 = NULL;
120157795646SDave May   dm->ops->coarsenhierarchy                = NULL;
120257795646SDave May   dm->ops->globaltolocalbegin              = NULL;
120357795646SDave May   dm->ops->globaltolocalend                = NULL;
120457795646SDave May   dm->ops->localtoglobalbegin              = NULL;
120557795646SDave May   dm->ops->localtoglobalend                = NULL;
120657795646SDave May   dm->ops->destroy                         = DMDestroy_Swarm;
120757795646SDave May   dm->ops->createsubdm                     = NULL;
120857795646SDave May   dm->ops->getdimpoints                    = NULL;
120957795646SDave May   dm->ops->locatepoints                    = NULL;
121057795646SDave May   PetscFunctionReturn(0);
121157795646SDave May }
1212