xref: /petsc/src/dm/impls/swarm/swarm.c (revision ba4fc9c60a32c7d973d2e8d3ca57c5a3933626b8)
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 
6f2b2bee7SDave May PetscLogEvent DMSWARM_Migrate, DMSWARM_SetSizes, DMSWARM_AddPoints, DMSWARM_RemovePoints, DMSWARM_Sort;
7ed923d71SDave May PetscLogEvent DMSWARM_DataExchangerTopologySetup, DMSWARM_DataExchangerBegin, DMSWARM_DataExchangerEnd;
8ed923d71SDave May PetscLogEvent DMSWARM_DataExchangerSendCount, DMSWARM_DataExchangerPack;
9ed923d71SDave May 
10f0cdbbbaSDave May const char* DMSwarmTypeNames[] = { "basic", "pic", 0 };
11f0cdbbbaSDave May const char* DMSwarmMigrateTypeNames[] = { "basic", "dmcellnscatter", "dmcellexact", "user", 0 };
12f0cdbbbaSDave May const char* DMSwarmCollectTypeNames[] = { "basic", "boundingbox", "general", "user", 0 };
13e2d107dbSDave May const char* DMSwarmPICLayoutTypeNames[] = { "regular", "gauss", "subdivision", 0 };
14f0cdbbbaSDave May 
15f0cdbbbaSDave May const char DMSwarmField_pid[] = "DMSwarm_pid";
16f0cdbbbaSDave May const char DMSwarmField_rank[] = "DMSwarm_rank";
17f0cdbbbaSDave May const char DMSwarmPICField_coor[] = "DMSwarmPIC_coor";
18e2d107dbSDave May const char DMSwarmPICField_cellid[] = "DMSwarm_cellid";
19f0cdbbbaSDave May 
20d3a51819SDave May /*@C
2162741f57SDave May    DMSwarmVectorDefineField - Sets the field from which to define a Vec object
2262741f57SDave May                              when DMCreateLocalVector(), or DMCreateGlobalVector() is called
2357795646SDave May 
24d3a51819SDave May    Collective on DM
2557795646SDave May 
26d3a51819SDave May    Input parameters:
2762741f57SDave May +  dm - a DMSwarm
2862741f57SDave May -  fieldname - the textual name given to a registered field
2957795646SDave May 
30d3a51819SDave May    Level: beginner
3157795646SDave May 
32d3a51819SDave May    Notes:
3362741f57SDave May    The field with name fieldname must be defined as having a data type of PetscScalar.
34d3a51819SDave May    This function must be called prior to calling DMCreateLocalVector(), DMCreateGlobalVector().
35d3a51819SDave May    Mutiple calls to DMSwarmVectorDefineField() are permitted.
3657795646SDave May 
378b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMCreateGlobalVector(), DMCreateLocalVector()
38d3a51819SDave May @*/
39b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmVectorDefineField(DM dm,const char fieldname[])
40b5bcf523SDave May {
41b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
42b5bcf523SDave May   PetscErrorCode ierr;
43b5bcf523SDave May   PetscInt bs,n;
44b5bcf523SDave May   PetscScalar *array;
45b5bcf523SDave May   PetscDataType type;
46b5bcf523SDave May 
47a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
483454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
496845f8f5SDave May   ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr);
50b5bcf523SDave May   ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
51b5bcf523SDave May 
52b5bcf523SDave May   /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */
53b5bcf523SDave May   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL");
54521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(swarm->vec_field_name,PETSC_MAX_PATH_LEN-1,"%s",fieldname);CHKERRQ(ierr);
55b5bcf523SDave May   swarm->vec_field_set = PETSC_TRUE;
561b1ea282SDave May   swarm->vec_field_bs = bs;
57b5bcf523SDave May   swarm->vec_field_nlocal = n;
58dcf43ee8SDave May   ierr = DMSwarmRestoreField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
59b5bcf523SDave May   PetscFunctionReturn(0);
60b5bcf523SDave May }
61b5bcf523SDave May 
62cc651181SDave May /* requires DMSwarmDefineFieldVector has been called */
63b5bcf523SDave May PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec)
64b5bcf523SDave May {
65b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
66b5bcf523SDave May   PetscErrorCode ierr;
67b5bcf523SDave May   Vec x;
68b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
69b5bcf523SDave May 
70a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
713454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
72b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
73cc651181SDave 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 */
74cc651181SDave May 
75521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr);
76b5bcf523SDave May   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr);
77b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
781b1ea282SDave May   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr);
79b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
80b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
81b5bcf523SDave May   *vec = x;
82b5bcf523SDave May   PetscFunctionReturn(0);
83b5bcf523SDave May }
84b5bcf523SDave May 
85b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */
86b5bcf523SDave May PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec)
87b5bcf523SDave May {
88b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
89b5bcf523SDave May   PetscErrorCode ierr;
90b5bcf523SDave May   Vec x;
91b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
92b5bcf523SDave May 
93a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
943454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
95b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
96cc651181SDave 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 */
97cc651181SDave May 
98521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr);
99b5bcf523SDave May   ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr);
100b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
101071900c8SMatthew G. Knepley   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr);
102b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
103b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
104b5bcf523SDave May   *vec = x;
105b5bcf523SDave May   PetscFunctionReturn(0);
106b5bcf523SDave May }
107b5bcf523SDave May 
108fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmDestroyVectorFromField_Private(DM dm, const char fieldname[], Vec *vec)
109fb1bcc12SMatthew G. Knepley {
110fb1bcc12SMatthew G. Knepley   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
111fb1bcc12SMatthew G. Knepley   DataField      gfield;
112fb1bcc12SMatthew G. Knepley   void         (*fptr)(void);
113fb1bcc12SMatthew G. Knepley   PetscInt       bs, nlocal;
114fb1bcc12SMatthew G. Knepley   char           name[PETSC_MAX_PATH_LEN];
115fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
116d3a51819SDave May 
117fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
118fb1bcc12SMatthew G. Knepley   ierr = VecGetLocalSize(*vec, &nlocal);CHKERRQ(ierr);
119fb1bcc12SMatthew G. Knepley   ierr = VecGetBlockSize(*vec, &bs);CHKERRQ(ierr);
120fb1bcc12SMatthew 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 */
121fb1bcc12SMatthew G. Knepley   ierr = DataBucketGetDataFieldByName(swarm->db, fieldname, &gfield);CHKERRQ(ierr);
122fb1bcc12SMatthew G. Knepley   /* check vector is an inplace array */
123521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr);
124fb1bcc12SMatthew G. Knepley   ierr = PetscObjectQueryFunction((PetscObject) *vec, name, &fptr);CHKERRQ(ierr);
125fb1bcc12SMatthew G. Knepley   if (!fptr) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Vector being destroyed was not created from DMSwarm field(%s)", fieldname);
126fb1bcc12SMatthew G. Knepley   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
127fb1bcc12SMatthew G. Knepley   ierr = VecDestroy(vec);CHKERRQ(ierr);
128fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
129fb1bcc12SMatthew G. Knepley }
130fb1bcc12SMatthew G. Knepley 
131fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmCreateVectorFromField_Private(DM dm, const char fieldname[], MPI_Comm comm, Vec *vec)
132fb1bcc12SMatthew G. Knepley {
133fb1bcc12SMatthew G. Knepley   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
134fb1bcc12SMatthew G. Knepley   PetscDataType  type;
135fb1bcc12SMatthew G. Knepley   PetscScalar   *array;
136fb1bcc12SMatthew G. Knepley   PetscInt       bs, n;
137fb1bcc12SMatthew G. Knepley   char           name[PETSC_MAX_PATH_LEN];
138fb1bcc12SMatthew G. Knepley   PetscMPIInt    commsize;
139fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
140fb1bcc12SMatthew G. Knepley 
141fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
142fb1bcc12SMatthew G. Knepley   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
143fb1bcc12SMatthew G. Knepley   ierr = DataBucketGetSizes(swarm->db, &n, NULL, NULL);CHKERRQ(ierr);
144fb1bcc12SMatthew G. Knepley   ierr = DMSwarmGetField(dm, fieldname, &bs, &type, (void **) &array);CHKERRQ(ierr);
145fb1bcc12SMatthew G. Knepley   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Only valid for PETSC_REAL");
146fb1bcc12SMatthew G. Knepley 
147fb1bcc12SMatthew G. Knepley   ierr = MPI_Comm_size(comm, &commsize);CHKERRQ(ierr);
148fb1bcc12SMatthew G. Knepley   if (commsize == 1) {
149fb1bcc12SMatthew G. Knepley     ierr = VecCreateSeqWithArray(comm, bs, n*bs, array, vec);CHKERRQ(ierr);
150fb1bcc12SMatthew G. Knepley   } else {
151fb1bcc12SMatthew G. Knepley     ierr = VecCreateMPIWithArray(comm, bs, n*bs, PETSC_DETERMINE, array, vec);CHKERRQ(ierr);
152fb1bcc12SMatthew G. Knepley   }
153fb1bcc12SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarmSharedField_%s", fieldname);CHKERRQ(ierr);
154fb1bcc12SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) *vec, name);CHKERRQ(ierr);
155fb1bcc12SMatthew G. Knepley 
156fb1bcc12SMatthew G. Knepley   /* Set guard */
157fb1bcc12SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr);
158fb1bcc12SMatthew G. Knepley   ierr = PetscObjectComposeFunction((PetscObject) *vec, name, DMSwarmDestroyVectorFromField_Private);CHKERRQ(ierr);
159fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
160fb1bcc12SMatthew G. Knepley }
161fb1bcc12SMatthew G. Knepley 
162fb1bcc12SMatthew G. Knepley /*@C
163d3a51819SDave May    DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field
164d3a51819SDave May 
165d3a51819SDave May    Collective on DM
166d3a51819SDave May 
167d3a51819SDave May    Input parameters:
16862741f57SDave May +  dm - a DMSwarm
16962741f57SDave May -  fieldname - the textual name given to a registered field
170d3a51819SDave May 
1718b8a3813SDave May    Output parameter:
172d3a51819SDave May .  vec - the vector
173d3a51819SDave May 
174d3a51819SDave May    Level: beginner
175d3a51819SDave May 
1768b8a3813SDave May    Notes:
1778b8a3813SDave May    The vector must be returned using a matching call to DMSwarmDestroyGlobalVectorFromField().
1788b8a3813SDave May 
1798b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyGlobalVectorFromField()
180d3a51819SDave May @*/
181b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
182b5bcf523SDave May {
183fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PetscObjectComm((PetscObject) dm);
184b5bcf523SDave May   PetscErrorCode ierr;
185b5bcf523SDave May 
186fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
187fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
188b5bcf523SDave May   PetscFunctionReturn(0);
189b5bcf523SDave May }
190b5bcf523SDave May 
191d3a51819SDave May /*@C
192d3a51819SDave May    DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field
193d3a51819SDave May 
194d3a51819SDave May    Collective on DM
195d3a51819SDave May 
196d3a51819SDave May    Input parameters:
19762741f57SDave May +  dm - a DMSwarm
19862741f57SDave May -  fieldname - the textual name given to a registered field
199d3a51819SDave May 
2008b8a3813SDave May    Output parameter:
201d3a51819SDave May .  vec - the vector
202d3a51819SDave May 
203d3a51819SDave May    Level: beginner
204d3a51819SDave May 
2058b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateGlobalVectorFromField()
206d3a51819SDave May @*/
207b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
208b5bcf523SDave May {
209b5bcf523SDave May   PetscErrorCode ierr;
210cc651181SDave May 
211fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
212fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
213b5bcf523SDave May   PetscFunctionReturn(0);
214b5bcf523SDave May }
215b5bcf523SDave May 
216fb1bcc12SMatthew G. Knepley /*@C
217fb1bcc12SMatthew G. Knepley    DMSwarmCreateLocalVectorFromField - Creates a Vec object sharing the array associated with a given field
218fb1bcc12SMatthew G. Knepley 
219fb1bcc12SMatthew G. Knepley    Collective on DM
220fb1bcc12SMatthew G. Knepley 
221fb1bcc12SMatthew G. Knepley    Input parameters:
22262741f57SDave May +  dm - a DMSwarm
22362741f57SDave May -  fieldname - the textual name given to a registered field
224fb1bcc12SMatthew G. Knepley 
2258b8a3813SDave May    Output parameter:
226fb1bcc12SMatthew G. Knepley .  vec - the vector
227fb1bcc12SMatthew G. Knepley 
228fb1bcc12SMatthew G. Knepley    Level: beginner
229fb1bcc12SMatthew G. Knepley 
2308b8a3813SDave May    Notes:
2318b8a3813SDave May    The vector must be returned using a matching call to DMSwarmDestroyLocalVectorFromField().
2328b8a3813SDave May 
2338b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyLocalVectorFromField()
234fb1bcc12SMatthew G. Knepley @*/
235fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmCreateLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
236bbe8250bSMatthew G. Knepley {
237fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PETSC_COMM_SELF;
238bbe8250bSMatthew G. Knepley   PetscErrorCode ierr;
239bbe8250bSMatthew G. Knepley 
240fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
241fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
242fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
243bbe8250bSMatthew G. Knepley }
244fb1bcc12SMatthew G. Knepley 
245fb1bcc12SMatthew G. Knepley /*@C
246fb1bcc12SMatthew G. Knepley    DMSwarmDestroyLocalVectorFromField - Destroys the Vec object which share the array associated with a given field
247fb1bcc12SMatthew G. Knepley 
248fb1bcc12SMatthew G. Knepley    Collective on DM
249fb1bcc12SMatthew G. Knepley 
250fb1bcc12SMatthew G. Knepley    Input parameters:
25162741f57SDave May +  dm - a DMSwarm
25262741f57SDave May -  fieldname - the textual name given to a registered field
253fb1bcc12SMatthew G. Knepley 
2548b8a3813SDave May    Output parameter:
255fb1bcc12SMatthew G. Knepley .  vec - the vector
256fb1bcc12SMatthew G. Knepley 
257fb1bcc12SMatthew G. Knepley    Level: beginner
258fb1bcc12SMatthew G. Knepley 
2598b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateLocalVectorFromField()
260fb1bcc12SMatthew G. Knepley @*/
261fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmDestroyLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
262fb1bcc12SMatthew G. Knepley {
263fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
264fb1bcc12SMatthew G. Knepley 
265fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
266fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
267bbe8250bSMatthew G. Knepley   PetscFunctionReturn(0);
268bbe8250bSMatthew G. Knepley }
269bbe8250bSMatthew G. Knepley 
270b5bcf523SDave May /*
271b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec)
272b5bcf523SDave May {
273b5bcf523SDave May   PetscFunctionReturn(0);
274b5bcf523SDave May }
275b5bcf523SDave May 
276b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec)
277b5bcf523SDave May {
278b5bcf523SDave May   PetscFunctionReturn(0);
279b5bcf523SDave May }
280b5bcf523SDave May */
281b5bcf523SDave May 
282d3a51819SDave May /*@C
283d3a51819SDave May    DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm
284d3a51819SDave May 
285d3a51819SDave May    Collective on DM
286d3a51819SDave May 
287d3a51819SDave May    Input parameter:
288d3a51819SDave May .  dm - a DMSwarm
289d3a51819SDave May 
290d3a51819SDave May    Level: beginner
291d3a51819SDave May 
292d3a51819SDave May    Notes:
2938b8a3813SDave May    After all fields have been registered, you must call DMSwarmFinalizeFieldRegister().
294d3a51819SDave May 
295d3a51819SDave May .seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
296d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
297d3a51819SDave May @*/
2985f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm)
2995f50eb2eSDave May {
3005f50eb2eSDave May   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
3013454631fSDave May   PetscErrorCode ierr;
3023454631fSDave May 
303521f74f9SMatthew G. Knepley   PetscFunctionBegin;
304cc651181SDave May   if (!swarm->field_registration_initialized) {
3055f50eb2eSDave May     swarm->field_registration_initialized = PETSC_TRUE;
306f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */
307f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */
308cc651181SDave May   }
3095f50eb2eSDave May   PetscFunctionReturn(0);
3105f50eb2eSDave May }
3115f50eb2eSDave May 
312d3a51819SDave May /*@C
313d3a51819SDave May    DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm
314d3a51819SDave May 
315d3a51819SDave May    Collective on DM
316d3a51819SDave May 
317d3a51819SDave May    Input parameter:
318d3a51819SDave May .  dm - a DMSwarm
319d3a51819SDave May 
320d3a51819SDave May    Level: beginner
321d3a51819SDave May 
322d3a51819SDave May    Notes:
32362741f57SDave May    After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined on the DMSwarm.
324d3a51819SDave May 
325d3a51819SDave May .seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
326d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
327d3a51819SDave May @*/
3285f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm)
3295f50eb2eSDave May {
3305f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3316845f8f5SDave May   PetscErrorCode ierr;
3326845f8f5SDave May 
333521f74f9SMatthew G. Knepley   PetscFunctionBegin;
334f0cdbbbaSDave May   if (!swarm->field_registration_finalized) {
3356845f8f5SDave May     ierr = DataBucketFinalize(swarm->db);CHKERRQ(ierr);
336f0cdbbbaSDave May   }
337f0cdbbbaSDave May   swarm->field_registration_finalized = PETSC_TRUE;
3385f50eb2eSDave May   PetscFunctionReturn(0);
3395f50eb2eSDave May }
3405f50eb2eSDave May 
341d3a51819SDave May /*@C
342d3a51819SDave May    DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm
343d3a51819SDave May 
344d3a51819SDave May    Not collective
345d3a51819SDave May 
346d3a51819SDave May    Input parameters:
34762741f57SDave May +  dm - a DMSwarm
348d3a51819SDave May .  nlocal - the length of each registered field
34962741f57SDave May -  buffer - the length of the buffer used to efficient dynamic re-sizing
350d3a51819SDave May 
351d3a51819SDave May    Level: beginner
352d3a51819SDave May 
353d3a51819SDave May .seealso: DMSwarmGetLocalSize()
354d3a51819SDave May @*/
3555f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer)
3565f50eb2eSDave May {
3575f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3586845f8f5SDave May   PetscErrorCode ierr;
3595f50eb2eSDave May 
360521f74f9SMatthew G. Knepley   PetscFunctionBegin;
361f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr);
3626845f8f5SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr);
363f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr);
3645f50eb2eSDave May   PetscFunctionReturn(0);
3655f50eb2eSDave May }
3665f50eb2eSDave May 
367d3a51819SDave May /*@C
368d3a51819SDave May    DMSwarmSetCellDM - Attachs a DM to a DMSwarm
369d3a51819SDave May 
370d3a51819SDave May    Collective on DM
371d3a51819SDave May 
372d3a51819SDave May    Input parameters:
37362741f57SDave May +  dm - a DMSwarm
37462741f57SDave May -  dmcell - the DM to attach to the DMSwarm
375d3a51819SDave May 
376d3a51819SDave May    Level: beginner
377d3a51819SDave May 
378d3a51819SDave May    Notes:
379d3a51819SDave May    The attached DM (dmcell) will be queried for point location and
3808b8a3813SDave May    neighbor MPI-rank information if DMSwarmMigrate() is called.
381d3a51819SDave May 
3828b8a3813SDave May .seealso: DMSwarmSetType(), DMSwarmGetCellDM(), DMSwarmMigrate()
383d3a51819SDave May @*/
384b16650c8SDave May PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell)
385b16650c8SDave May {
386b16650c8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
387521f74f9SMatthew G. Knepley 
388521f74f9SMatthew G. Knepley   PetscFunctionBegin;
389b16650c8SDave May   swarm->dmcell = dmcell;
390b16650c8SDave May   PetscFunctionReturn(0);
391b16650c8SDave May }
392b16650c8SDave May 
393d3a51819SDave May /*@C
394d3a51819SDave May    DMSwarmGetCellDM - Fetches the attached cell DM
395d3a51819SDave May 
396d3a51819SDave May    Collective on DM
397d3a51819SDave May 
398d3a51819SDave May    Input parameter:
399d3a51819SDave May .  dm - a DMSwarm
400d3a51819SDave May 
401d3a51819SDave May    Output parameter:
402d3a51819SDave May .  dmcell - the DM which was attached to the DMSwarm
403d3a51819SDave May 
404d3a51819SDave May    Level: beginner
405d3a51819SDave May 
406d3a51819SDave May .seealso: DMSwarmSetCellDM()
407d3a51819SDave May @*/
408fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell)
409fe39f135SDave May {
410fe39f135SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
411521f74f9SMatthew G. Knepley 
412521f74f9SMatthew G. Knepley   PetscFunctionBegin;
413fe39f135SDave May   *dmcell = swarm->dmcell;
414fe39f135SDave May   PetscFunctionReturn(0);
415fe39f135SDave May }
416fe39f135SDave May 
417d3a51819SDave May /*@C
418d3a51819SDave May    DMSwarmGetLocalSize - Retrives the local length of fields registered
419d3a51819SDave May 
420d3a51819SDave May    Not collective
421d3a51819SDave May 
422d3a51819SDave May    Input parameter:
423d3a51819SDave May .  dm - a DMSwarm
424d3a51819SDave May 
425d3a51819SDave May    Output parameter:
426d3a51819SDave May .  nlocal - the length of each registered field
427d3a51819SDave May 
428d3a51819SDave May    Level: beginner
429d3a51819SDave May 
4308b8a3813SDave May .seealso: DMSwarmGetSize(), DMSwarmSetLocalSizes()
431d3a51819SDave May @*/
432dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal)
433dcf43ee8SDave May {
434dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
435dcf43ee8SDave May   PetscErrorCode ierr;
436dcf43ee8SDave May 
437521f74f9SMatthew G. Knepley   PetscFunctionBegin;
438521f74f9SMatthew G. Knepley   if (nlocal) {ierr = DataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);}
439dcf43ee8SDave May   PetscFunctionReturn(0);
440dcf43ee8SDave May }
441dcf43ee8SDave May 
442d3a51819SDave May /*@C
443d3a51819SDave May    DMSwarmGetSize - Retrives the total length of fields registered
444d3a51819SDave May 
445d3a51819SDave May    Collective on DM
446d3a51819SDave May 
447d3a51819SDave May    Input parameter:
448d3a51819SDave May .  dm - a DMSwarm
449d3a51819SDave May 
450d3a51819SDave May    Output parameter:
451d3a51819SDave May .  n - the total length of each registered field
452d3a51819SDave May 
453d3a51819SDave May    Level: beginner
454d3a51819SDave May 
455d3a51819SDave May    Note:
456d3a51819SDave May    This calls MPI_Allreduce upon each call (inefficient but safe)
457d3a51819SDave May 
4588b8a3813SDave May .seealso: DMSwarmGetLocalSize(), DMSwarmSetLocalSizes()
459d3a51819SDave May @*/
460dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n)
461dcf43ee8SDave May {
462dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
463dcf43ee8SDave May   PetscErrorCode ierr;
464dcf43ee8SDave May   PetscInt nlocal,ng;
465dcf43ee8SDave May 
466521f74f9SMatthew G. Knepley   PetscFunctionBegin;
467dcf43ee8SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
468dcf43ee8SDave May   ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
469dcf43ee8SDave May   if (n) { *n = ng; }
470dcf43ee8SDave May   PetscFunctionReturn(0);
471dcf43ee8SDave May }
472dcf43ee8SDave May 
473d3a51819SDave May /*@C
4748b8a3813SDave May    DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm with a native PETSc data type
475d3a51819SDave May 
476d3a51819SDave May    Collective on DM
477d3a51819SDave May 
478d3a51819SDave May    Input parameters:
47962741f57SDave May +  dm - a DMSwarm
480d3a51819SDave May .  fieldname - the textual name to identify this field
481d3a51819SDave May .  blocksize - the number of each data type
48262741f57SDave May -  type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG)
483d3a51819SDave May 
484d3a51819SDave May    Level: beginner
485d3a51819SDave May 
486d3a51819SDave May    Notes:
4878b8a3813SDave May    The textual name for each registered field must be unique.
488d3a51819SDave May 
489d3a51819SDave May .seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
490d3a51819SDave May @*/
4915f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
492b62e03f8SDave May {
4932eac95f8SDave May   PetscErrorCode ierr;
494b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
495b62e03f8SDave May   size_t size;
496b62e03f8SDave May 
497521f74f9SMatthew G. Knepley   PetscFunctionBegin;
4985f50eb2eSDave May   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
4995f50eb2eSDave May   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
5005f50eb2eSDave May 
5015f50eb2eSDave May   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5025f50eb2eSDave May   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5035f50eb2eSDave May   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5045f50eb2eSDave May   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5055f50eb2eSDave May   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
506b62e03f8SDave May 
5072ddcf43eSMatthew G. Knepley   ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr);
508b62e03f8SDave May   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
50952c3ed93SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
51052c3ed93SDave May   {
51152c3ed93SDave May     DataField gfield;
51252c3ed93SDave May 
51352c3ed93SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
51452c3ed93SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
51552c3ed93SDave May   }
516b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
517b62e03f8SDave May   PetscFunctionReturn(0);
518b62e03f8SDave May }
519b62e03f8SDave May 
520d3a51819SDave May /*@C
521d3a51819SDave May    DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm
522d3a51819SDave May 
523d3a51819SDave May    Collective on DM
524d3a51819SDave May 
525d3a51819SDave May    Input parameters:
52662741f57SDave May +  dm - a DMSwarm
527d3a51819SDave May .  fieldname - the textual name to identify this field
52862741f57SDave May -  size - the size in bytes of the user struct of each data type
529d3a51819SDave May 
530d3a51819SDave May    Level: beginner
531d3a51819SDave May 
532d3a51819SDave May    Notes:
5338b8a3813SDave May    The textual name for each registered field must be unique.
534d3a51819SDave May 
535d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField()
536d3a51819SDave May @*/
5375f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
538b62e03f8SDave May {
5392eac95f8SDave May   PetscErrorCode ierr;
540b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
541b62e03f8SDave May 
542521f74f9SMatthew G. Knepley   PetscFunctionBegin;
5432eac95f8SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
544b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
545b62e03f8SDave May   PetscFunctionReturn(0);
546b62e03f8SDave May }
547b62e03f8SDave May 
548d3a51819SDave May /*@C
549d3a51819SDave May    DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm
550d3a51819SDave May 
551d3a51819SDave May    Collective on DM
552d3a51819SDave May 
553d3a51819SDave May    Input parameters:
55462741f57SDave May +  dm - a DMSwarm
555d3a51819SDave May .  fieldname - the textual name to identify this field
556d3a51819SDave May .  size - the size in bytes of the user data type
55762741f57SDave May -  blocksize - the number of each data type
558d3a51819SDave May 
559d3a51819SDave May    Level: beginner
560d3a51819SDave May 
561d3a51819SDave May    Notes:
5628b8a3813SDave May    The textual name for each registered field must be unique.
563d3a51819SDave May 
564d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
565d3a51819SDave May @*/
566320740a0SDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize)
567b62e03f8SDave May {
568b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
5696845f8f5SDave May   PetscErrorCode ierr;
570b62e03f8SDave May 
571521f74f9SMatthew G. Knepley   PetscFunctionBegin;
572320740a0SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
573320740a0SDave May   {
574320740a0SDave May     DataField gfield;
575320740a0SDave May 
576320740a0SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
577320740a0SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
578320740a0SDave May   }
579b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
580b62e03f8SDave May   PetscFunctionReturn(0);
581b62e03f8SDave May }
582b62e03f8SDave May 
583d3a51819SDave May /*@C
584d3a51819SDave May    DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field
585d3a51819SDave May 
586d3a51819SDave May    Not collective
587d3a51819SDave May 
588d3a51819SDave May    Input parameters:
58962741f57SDave May +  dm - a DMSwarm
59062741f57SDave May -  fieldname - the textual name to identify this field
591d3a51819SDave May 
592d3a51819SDave May    Output parameters:
59362741f57SDave May +  blocksize - the number of each data type
594d3a51819SDave May .  type - the data type
59562741f57SDave May -  data - pointer to raw array
596d3a51819SDave May 
597d3a51819SDave May    Level: beginner
598d3a51819SDave May 
599d3a51819SDave May    Notes:
6008b8a3813SDave May    The array must be returned using a matching call to DMSwarmRestoreField().
601d3a51819SDave May 
602d3a51819SDave May .seealso: DMSwarmRestoreField()
603d3a51819SDave May @*/
6045f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
605b62e03f8SDave May {
606b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
607b62e03f8SDave May   DataField gfield;
6082eac95f8SDave May   PetscErrorCode ierr;
609b62e03f8SDave May 
610521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6113454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
6122eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6136845f8f5SDave May   ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr);
6146845f8f5SDave May   ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr);
6151b1ea282SDave May   if (blocksize) {*blocksize = gfield->bs; }
616b5bcf523SDave May   if (type) { *type = gfield->petsc_type; }
617b62e03f8SDave May   PetscFunctionReturn(0);
618b62e03f8SDave May }
619b62e03f8SDave May 
620d3a51819SDave May /*@C
621d3a51819SDave May    DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field
622d3a51819SDave May 
623d3a51819SDave May    Not collective
624d3a51819SDave May 
625d3a51819SDave May    Input parameters:
62662741f57SDave May +  dm - a DMSwarm
62762741f57SDave May -  fieldname - the textual name to identify this field
628d3a51819SDave May 
629d3a51819SDave May    Output parameters:
63062741f57SDave May +  blocksize - the number of each data type
631d3a51819SDave May .  type - the data type
63262741f57SDave May -  data - pointer to raw array
633d3a51819SDave May 
634d3a51819SDave May    Level: beginner
635d3a51819SDave May 
636d3a51819SDave May    Notes:
6378b8a3813SDave May    The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField().
638d3a51819SDave May 
639d3a51819SDave May .seealso: DMSwarmGetField()
640d3a51819SDave May @*/
6415f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
642b62e03f8SDave May {
643b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
644b62e03f8SDave May   DataField gfield;
6452eac95f8SDave May   PetscErrorCode ierr;
646b62e03f8SDave May 
647521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6482eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6496845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
650b62e03f8SDave May   if (data) *data = NULL;
651b62e03f8SDave May   PetscFunctionReturn(0);
652b62e03f8SDave May }
653b62e03f8SDave May 
654d3a51819SDave May /*@C
655d3a51819SDave May    DMSwarmAddPoint - Add space for one new point in the DMSwarm
656d3a51819SDave May 
657d3a51819SDave May    Not collective
658d3a51819SDave May 
659d3a51819SDave May    Input parameter:
660d3a51819SDave May .  dm - a DMSwarm
661d3a51819SDave May 
662d3a51819SDave May    Level: beginner
663d3a51819SDave May 
664d3a51819SDave May    Notes:
6658b8a3813SDave May    The new point will have all fields initialized to zero.
666d3a51819SDave May 
667d3a51819SDave May .seealso: DMSwarmAddNPoints()
668d3a51819SDave May @*/
669cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
670cb1d1399SDave May {
671cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
672cb1d1399SDave May   PetscErrorCode ierr;
673cb1d1399SDave May 
674521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6753454631fSDave May   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
676f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr);
677cb1d1399SDave May   ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr);
678f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr);
679cb1d1399SDave May   PetscFunctionReturn(0);
680cb1d1399SDave May }
681cb1d1399SDave May 
682d3a51819SDave May /*@C
683d3a51819SDave May    DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm
684d3a51819SDave May 
685d3a51819SDave May    Not collective
686d3a51819SDave May 
687d3a51819SDave May    Input parameters:
68862741f57SDave May +  dm - a DMSwarm
68962741f57SDave May -  npoints - the number of new points to add
690d3a51819SDave May 
691d3a51819SDave May    Level: beginner
692d3a51819SDave May 
693d3a51819SDave May    Notes:
6948b8a3813SDave May    The new point will have all fields initialized to zero.
695d3a51819SDave May 
696d3a51819SDave May .seealso: DMSwarmAddPoint()
697d3a51819SDave May @*/
698cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
699cb1d1399SDave May {
700cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
701cb1d1399SDave May   PetscErrorCode ierr;
702cb1d1399SDave May   PetscInt nlocal;
703cb1d1399SDave May 
704521f74f9SMatthew G. Knepley   PetscFunctionBegin;
705f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr);
706cb1d1399SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
707cb1d1399SDave May   nlocal = nlocal + npoints;
70865141ba8SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,DATA_BUCKET_BUFFER_DEFAULT);CHKERRQ(ierr);
709f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr);
710cb1d1399SDave May   PetscFunctionReturn(0);
711cb1d1399SDave May }
712cb1d1399SDave May 
713d3a51819SDave May /*@C
714d3a51819SDave May    DMSwarmRemovePoint - Remove the last point from the DMSwarm
715d3a51819SDave May 
716d3a51819SDave May    Not collective
717d3a51819SDave May 
718d3a51819SDave May    Input parameter:
719d3a51819SDave May .  dm - a DMSwarm
720d3a51819SDave May 
721d3a51819SDave May    Level: beginner
722d3a51819SDave May 
723d3a51819SDave May .seealso: DMSwarmRemovePointAtIndex()
724d3a51819SDave May @*/
725cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
726cb1d1399SDave May {
727cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
728cb1d1399SDave May   PetscErrorCode ierr;
729cb1d1399SDave May 
730521f74f9SMatthew G. Knepley   PetscFunctionBegin;
731f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr);
732cb1d1399SDave May   ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
733f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr);
734cb1d1399SDave May   PetscFunctionReturn(0);
735cb1d1399SDave May }
736cb1d1399SDave May 
737d3a51819SDave May /*@C
738d3a51819SDave May    DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm
739d3a51819SDave May 
740d3a51819SDave May    Not collective
741d3a51819SDave May 
742d3a51819SDave May    Input parameters:
74362741f57SDave May +  dm - a DMSwarm
74462741f57SDave May -  idx - index of point to remove
745d3a51819SDave May 
746d3a51819SDave May    Level: beginner
747d3a51819SDave May 
748d3a51819SDave May .seealso: DMSwarmRemovePoint()
749d3a51819SDave May @*/
750cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
751cb1d1399SDave May {
752cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
753cb1d1399SDave May   PetscErrorCode ierr;
754cb1d1399SDave May 
755521f74f9SMatthew G. Knepley   PetscFunctionBegin;
756f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr);
757cb1d1399SDave May   ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
758f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr);
759cb1d1399SDave May   PetscFunctionReturn(0);
760cb1d1399SDave May }
761b62e03f8SDave May 
762*ba4fc9c6SDave May /*@C
763*ba4fc9c6SDave May    DMSwarmCopyPoint - Copy point pj to point pi in the DMSwarm
764*ba4fc9c6SDave May 
765*ba4fc9c6SDave May    Not collective
766*ba4fc9c6SDave May 
767*ba4fc9c6SDave May    Input parameters:
768*ba4fc9c6SDave May +  dm - a DMSwarm
769*ba4fc9c6SDave May .  pi - the index of the point to copy
770*ba4fc9c6SDave May -  pj - the point index where the copy should be located
771*ba4fc9c6SDave May 
772*ba4fc9c6SDave May  Level: beginner
773*ba4fc9c6SDave May 
774*ba4fc9c6SDave May .seealso: DMSwarmRemovePoint()
775*ba4fc9c6SDave May @*/
776*ba4fc9c6SDave May PETSC_EXTERN PetscErrorCode DMSwarmCopyPoint(DM dm,PetscInt pi,PetscInt pj)
777*ba4fc9c6SDave May {
778*ba4fc9c6SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
779*ba4fc9c6SDave May   PetscErrorCode ierr;
780*ba4fc9c6SDave May 
781*ba4fc9c6SDave May   PetscFunctionBegin;
782*ba4fc9c6SDave May   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
783*ba4fc9c6SDave May   ierr = DataBucketCopyPoint(swarm->db,pi,swarm->db,pj);CHKERRQ(ierr);
784*ba4fc9c6SDave May   PetscFunctionReturn(0);
785*ba4fc9c6SDave May }
786*ba4fc9c6SDave May 
787095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points)
7883454631fSDave May {
789dcf43ee8SDave May   PetscErrorCode ierr;
790521f74f9SMatthew G. Knepley 
791521f74f9SMatthew G. Knepley   PetscFunctionBegin;
792dcf43ee8SDave May   ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr);
7933454631fSDave May   PetscFunctionReturn(0);
7943454631fSDave May }
7953454631fSDave May 
796d3a51819SDave May /*@C
797d3a51819SDave May    DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks
798d3a51819SDave May 
799d3a51819SDave May    Collective on DM
800d3a51819SDave May 
801d3a51819SDave May    Input parameters:
80262741f57SDave May +  dm - the DMSwarm
80362741f57SDave May -  remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank
804d3a51819SDave May 
805d3a51819SDave May    Notes:
8068b8a3813SDave May    The DM will be modified to accomodate received points.
8078b8a3813SDave May    If remove_sent_points = PETSC_TRUE, any points that were sent will be removed from the DM.
8088b8a3813SDave May    Different styles of migration are supported. See DMSwarmSetMigrateType().
809d3a51819SDave May 
810d3a51819SDave May    Level: advanced
811d3a51819SDave May 
812d3a51819SDave May .seealso: DMSwarmSetMigrateType()
813d3a51819SDave May @*/
814095059a4SDave May PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points)
8153454631fSDave May {
816f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8173454631fSDave May   PetscErrorCode ierr;
818f0cdbbbaSDave May 
819521f74f9SMatthew G. Knepley   PetscFunctionBegin;
820ed923d71SDave May   ierr = PetscLogEventBegin(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr);
821f0cdbbbaSDave May   switch (swarm->migrate_type) {
822f0cdbbbaSDave May     case DMSWARM_MIGRATE_BASIC:
823095059a4SDave May       ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr);
824f0cdbbbaSDave May       break;
825f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLNSCATTER:
826f0cdbbbaSDave May       ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr);
827f0cdbbbaSDave May       break;
828f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLEXACT:
829f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented");
830521f74f9SMatthew G. Knepley       /*ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr);*/
831f0cdbbbaSDave May       break;
832f0cdbbbaSDave May     case DMSWARM_MIGRATE_USER:
833f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented");
834521f74f9SMatthew G. Knepley       /*ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr);*/
835f0cdbbbaSDave May       break;
836f0cdbbbaSDave May     default:
837f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown");
838f0cdbbbaSDave May       break;
839f0cdbbbaSDave May   }
840ed923d71SDave May   ierr = PetscLogEventEnd(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr);
8413454631fSDave May   PetscFunctionReturn(0);
8423454631fSDave May }
8433454631fSDave May 
844f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize);
845f0cdbbbaSDave May 
846d3a51819SDave May /*
847d3a51819SDave May  DMSwarmCollectViewCreate
848d3a51819SDave May 
849d3a51819SDave May  * Applies a collection method and gathers point neighbour points into dm
850d3a51819SDave May 
851d3a51819SDave May  Notes:
8528b8a3813SDave May  Users should call DMSwarmCollectViewDestroy() after
853d3a51819SDave May  they have finished computations associated with the collected points
854d3a51819SDave May */
855d3a51819SDave May 
856d3a51819SDave May /*@C
857d3a51819SDave May    DMSwarmCollectViewCreate - Applies a collection method and gathers points
858d3a51819SDave May    in neighbour MPI-ranks into the DMSwarm
859d3a51819SDave May 
860d3a51819SDave May    Collective on DM
861d3a51819SDave May 
862d3a51819SDave May    Input parameter:
863d3a51819SDave May .  dm - the DMSwarm
864d3a51819SDave May 
865d3a51819SDave May    Notes:
866d3a51819SDave May    Users should call DMSwarmCollectViewDestroy() after
867d3a51819SDave May    they have finished computations associated with the collected points
8688b8a3813SDave May    Different collect methods are supported. See DMSwarmSetCollectType().
869d3a51819SDave May 
870d3a51819SDave May    Level: advanced
871d3a51819SDave May 
872d3a51819SDave May .seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType()
873d3a51819SDave May @*/
874fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm)
8752712d1f2SDave May {
8762712d1f2SDave May   PetscErrorCode ierr;
8772712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8782712d1f2SDave May   PetscInt ng;
8792712d1f2SDave May 
880521f74f9SMatthew G. Knepley   PetscFunctionBegin;
881480eef7bSDave May   if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active");
882480eef7bSDave May   ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr);
883480eef7bSDave May   switch (swarm->collect_type) {
884f0cdbbbaSDave May 
885480eef7bSDave May     case DMSWARM_COLLECT_BASIC:
8862712d1f2SDave May       ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr);
887480eef7bSDave May       break;
888480eef7bSDave May     case DMSWARM_COLLECT_DMDABOUNDINGBOX:
889f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented");
890521f74f9SMatthew G. Knepley       /*ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr);*/
891480eef7bSDave May       break;
892480eef7bSDave May     case DMSWARM_COLLECT_GENERAL:
893f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented");
894521f74f9SMatthew G. Knepley       /*ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr);*/
895480eef7bSDave May       break;
896480eef7bSDave May     default:
897f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown");
898480eef7bSDave May       break;
899480eef7bSDave May   }
900480eef7bSDave May   swarm->collect_view_active = PETSC_TRUE;
901480eef7bSDave May   swarm->collect_view_reset_nlocal = ng;
9022712d1f2SDave May   PetscFunctionReturn(0);
9032712d1f2SDave May }
9042712d1f2SDave May 
905d3a51819SDave May /*@C
906d3a51819SDave May    DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate()
907d3a51819SDave May 
908d3a51819SDave May    Collective on DM
909d3a51819SDave May 
910d3a51819SDave May    Input parameters:
911d3a51819SDave May .  dm - the DMSwarm
912d3a51819SDave May 
913d3a51819SDave May    Notes:
914d3a51819SDave May    Users should call DMSwarmCollectViewCreate() before this function is called.
915d3a51819SDave May 
916d3a51819SDave May    Level: advanced
917d3a51819SDave May 
918d3a51819SDave May .seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType()
919d3a51819SDave May @*/
920fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm)
9212712d1f2SDave May {
9222712d1f2SDave May   PetscErrorCode ierr;
9232712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9242712d1f2SDave May 
925521f74f9SMatthew G. Knepley   PetscFunctionBegin;
926480eef7bSDave May   if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active");
927480eef7bSDave May   ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr);
928480eef7bSDave May   swarm->collect_view_active = PETSC_FALSE;
9292712d1f2SDave May   PetscFunctionReturn(0);
9302712d1f2SDave May }
9313454631fSDave May 
932f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm)
933f0cdbbbaSDave May {
934f0cdbbbaSDave May   PetscInt dim;
935f0cdbbbaSDave May   PetscErrorCode ierr;
936f0cdbbbaSDave May 
937521f74f9SMatthew G. Knepley   PetscFunctionBegin;
938f0cdbbbaSDave May   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
939f0cdbbbaSDave May   if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
940f0cdbbbaSDave May   if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
941f0cdbbbaSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr);
942e2d107dbSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_cellid,1,PETSC_INT);CHKERRQ(ierr);
943f0cdbbbaSDave May   PetscFunctionReturn(0);
944f0cdbbbaSDave May }
945f0cdbbbaSDave May 
946d3a51819SDave May /*@C
947d3a51819SDave May    DMSwarmSetType - Set particular flavor of DMSwarm
948d3a51819SDave May 
949d3a51819SDave May    Collective on DM
950d3a51819SDave May 
951d3a51819SDave May    Input parameters:
95262741f57SDave May +  dm - the DMSwarm
95362741f57SDave May -  stype - the DMSwarm type (e.g. DMSWARM_PIC)
954d3a51819SDave May 
955d3a51819SDave May    Level: advanced
956d3a51819SDave May 
957d3a51819SDave May .seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType()
958d3a51819SDave May @*/
959f0cdbbbaSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype)
960f0cdbbbaSDave May {
961f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
962f0cdbbbaSDave May   PetscErrorCode ierr;
963f0cdbbbaSDave May 
964521f74f9SMatthew G. Knepley   PetscFunctionBegin;
965f0cdbbbaSDave May   swarm->swarm_type = stype;
966f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
967f0cdbbbaSDave May     ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr);
968f0cdbbbaSDave May   }
969f0cdbbbaSDave May   PetscFunctionReturn(0);
970f0cdbbbaSDave May }
971f0cdbbbaSDave May 
9723454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm)
9733454631fSDave May {
9743454631fSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9753454631fSDave May   PetscErrorCode ierr;
9763454631fSDave May   PetscMPIInt rank;
9773454631fSDave May   PetscInt p,npoints,*rankval;
9783454631fSDave May 
979521f74f9SMatthew G. Knepley   PetscFunctionBegin;
9803454631fSDave May   if (swarm->issetup) PetscFunctionReturn(0);
9813454631fSDave May 
9823454631fSDave May   swarm->issetup = PETSC_TRUE;
9833454631fSDave May 
984f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
985f0cdbbbaSDave May     /* check dmcell exists */
986f0cdbbbaSDave May     if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM");
987f0cdbbbaSDave May 
988f0cdbbbaSDave May     if (swarm->dmcell->ops->locatepointssubdomain) {
989f0cdbbbaSDave May       /* check methods exists for exact ownership identificiation */
990521f74f9SMatthew G. Knepley       ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");CHKERRQ(ierr);
991f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT;
992f0cdbbbaSDave May     } else {
993f0cdbbbaSDave May       /* check methods exist for point location AND rank neighbor identification */
994f0cdbbbaSDave May       if (swarm->dmcell->ops->locatepoints) {
995521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->LocatePoints\n");CHKERRQ(ierr);
996f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined");
997f0cdbbbaSDave May 
998f0cdbbbaSDave May       if (swarm->dmcell->ops->getneighbors) {
999521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->GetNeigbors\n");CHKERRQ(ierr);
1000f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined");
1001f0cdbbbaSDave May 
1002f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER;
1003f0cdbbbaSDave May     }
1004f0cdbbbaSDave May   }
1005f0cdbbbaSDave May 
1006f0cdbbbaSDave May   ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr);
1007f0cdbbbaSDave May 
10083454631fSDave May   /* check some fields were registered */
10093454631fSDave May   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
10103454631fSDave May 
10113454631fSDave May   /* check local sizes were set */
10123454631fSDave May   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
10133454631fSDave May 
10143454631fSDave May   /* initialize values in pid and rank placeholders */
10153454631fSDave May   /* TODO: [pid - use MPI_Scan] */
10163454631fSDave May   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
10173454631fSDave May   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
1018f0cdbbbaSDave May   ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10193454631fSDave May   for (p=0; p<npoints; p++) {
10203454631fSDave May     rankval[p] = (PetscInt)rank;
10213454631fSDave May   }
1022f0cdbbbaSDave May   ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
10233454631fSDave May   PetscFunctionReturn(0);
10243454631fSDave May }
10253454631fSDave May 
1026dc5f5ce9SDave May extern PetscErrorCode DMSwarmSortDestroy(DMSwarmSort *_ctx);
1027dc5f5ce9SDave May 
102857795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm)
102957795646SDave May {
103057795646SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
103157795646SDave May   PetscErrorCode ierr;
103257795646SDave May 
103357795646SDave May   PetscFunctionBegin;
10346845f8f5SDave May   ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr);
1035dc5f5ce9SDave May   if (swarm->sort_context) {
1036dc5f5ce9SDave May     ierr = DMSwarmSortDestroy(&swarm->sort_context);CHKERRQ(ierr);
1037dc5f5ce9SDave May   }
103857795646SDave May   ierr = PetscFree(swarm);CHKERRQ(ierr);
103957795646SDave May   PetscFunctionReturn(0);
104057795646SDave May }
104157795646SDave May 
1042a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer)
1043a9ee3421SMatthew G. Knepley {
1044a9ee3421SMatthew G. Knepley   DM             cdm;
1045a9ee3421SMatthew G. Knepley   PetscDraw      draw;
1046a9ee3421SMatthew G. Knepley   PetscReal     *coords, oldPause;
1047a9ee3421SMatthew G. Knepley   PetscInt       Np, p, bs;
1048a9ee3421SMatthew G. Knepley   PetscErrorCode ierr;
1049a9ee3421SMatthew G. Knepley 
1050a9ee3421SMatthew G. Knepley   PetscFunctionBegin;
1051a9ee3421SMatthew G. Knepley   ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr);
1052a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr);
1053a9ee3421SMatthew G. Knepley   ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr);
1054a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr);
1055a9ee3421SMatthew G. Knepley   ierr = DMView(cdm, viewer);CHKERRQ(ierr);
1056a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr);
1057a9ee3421SMatthew G. Knepley 
1058a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr);
1059a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1060a9ee3421SMatthew G. Knepley   for (p = 0; p < Np; ++p) {
1061a9ee3421SMatthew G. Knepley     const PetscInt i = p*bs;
1062a9ee3421SMatthew G. Knepley 
1063a9ee3421SMatthew G. Knepley     ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], 0.01, 0.01, PETSC_DRAW_BLUE);CHKERRQ(ierr);
1064a9ee3421SMatthew G. Knepley   }
1065a9ee3421SMatthew G. Knepley   ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1066a9ee3421SMatthew G. Knepley   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
1067a9ee3421SMatthew G. Knepley   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
1068a9ee3421SMatthew G. Knepley   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1069a9ee3421SMatthew G. Knepley   PetscFunctionReturn(0);
1070a9ee3421SMatthew G. Knepley }
1071a9ee3421SMatthew G. Knepley 
10725f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
10735f50eb2eSDave May {
10745f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1075a9ee3421SMatthew G. Knepley   PetscBool      iascii,ibinary,ishdf5,isvtk,isdraw;
10765f50eb2eSDave May   PetscErrorCode ierr;
10775f50eb2eSDave May 
10785f50eb2eSDave May   PetscFunctionBegin;
10795f50eb2eSDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10805f50eb2eSDave May   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
10815f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
10825f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
10835f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
10845f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1085a9ee3421SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW,  &isdraw);CHKERRQ(ierr);
10865f50eb2eSDave May   if (iascii) {
10876845f8f5SDave May     ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
10885f50eb2eSDave May   } else if (ibinary) {
1089a9ee3421SMatthew G. Knepley     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support");
10905f50eb2eSDave May   } else if (ishdf5) {
10915f50eb2eSDave May #if defined(PETSC_HAVE_HDF5)
10925f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
10935f50eb2eSDave May #else
10945f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
10955f50eb2eSDave May #endif
10965f50eb2eSDave May   } else if (isvtk) {
10975f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
1098a9ee3421SMatthew G. Knepley   } else if (isdraw) {
1099a9ee3421SMatthew G. Knepley     ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr);
11005f50eb2eSDave May   }
11015f50eb2eSDave May   PetscFunctionReturn(0);
11025f50eb2eSDave May }
11035f50eb2eSDave May 
1104d3a51819SDave May /*MC
1105d3a51819SDave May 
1106d3a51819SDave May  DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type.
110762741f57SDave May  This implementation was designed for particle methods in which the underlying
1108d3a51819SDave May  data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type.
1109d3a51819SDave May 
111062741f57SDave May  User data can be represented by DMSwarm through a registering "fields".
111162741f57SDave May  To register a field, the user must provide;
111262741f57SDave May  (a) a unique name;
111362741f57SDave May  (b) the data type (or size in bytes);
111462741f57SDave May  (c) the block size of the data.
1115d3a51819SDave May 
1116d3a51819SDave May  For example, suppose the application requires a unique id, energy, momentum and density to be stored
111762741f57SDave May  on a set of of particles. Then the following code could be used
1118d3a51819SDave May 
111962741f57SDave May $    DMSwarmInitializeFieldRegister(dm)
112062741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG);
112162741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL);
112262741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL);
112362741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT);
112462741f57SDave May $    DMSwarmFinalizeFieldRegister(dm)
1125d3a51819SDave May 
1126d3a51819SDave May  The fields represented by DMSwarm are dynamic and can be re-sized at any time.
112762741f57SDave May  The only restriction imposed by DMSwarm is that all fields contain the same number of points.
1128d3a51819SDave May 
1129d3a51819SDave May  To support particle methods, "migration" techniques are provided. These methods migrate data
1130d3a51819SDave May  between MPI-ranks.
1131d3a51819SDave May 
1132d3a51819SDave May  DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector().
1133d3a51819SDave May  As a DMSwarm may internally define and store values of different data types,
113462741f57SDave May  before calling DMCreateGlobalVector() or DMCreateLocalVector(), the user must inform DMSwarm which
1135d3a51819SDave May  fields should be used to define a Vec object via
1136d3a51819SDave May    DMSwarmVectorDefineField()
1137d3a51819SDave May  The specified field can can changed be changed at any time - thereby permitting vectors
1138d3a51819SDave May  compatable with different fields to be created.
1139d3a51819SDave May 
114062741f57SDave May  A dual representation of fields in the DMSwarm and a Vec object is permitted via
1141d3a51819SDave May    DMSwarmCreateGlobalVectorFromField()
1142d3a51819SDave May  Here the data defining the field in the DMSwarm is shared with a Vec.
1143d3a51819SDave May  This is inherently unsafe if you alter the size of the field at any time between
1144d3a51819SDave May  calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField().
1145cc651181SDave May  If the local size of the DMSwarm does not match the local size of the global vector
1146cc651181SDave May  when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown.
1147d3a51819SDave May 
114862741f57SDave May  Additional high-level support is provided for Particle-In-Cell methods.
114962741f57SDave May  Please refer to the man page for DMSwarmSetType().
115062741f57SDave May 
1151d3a51819SDave May  Level: beginner
1152d3a51819SDave May 
1153d3a51819SDave May .seealso: DMType, DMCreate(), DMSetType()
1154d3a51819SDave May M*/
115557795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
115657795646SDave May {
115757795646SDave May   DM_Swarm      *swarm;
115857795646SDave May   PetscErrorCode ierr;
115957795646SDave May 
116057795646SDave May   PetscFunctionBegin;
116157795646SDave May   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
116257795646SDave May   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
1163f0cdbbbaSDave May   dm->data = swarm;
116457795646SDave May 
11656845f8f5SDave May   ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr);
1166f0cdbbbaSDave May   ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr);
1167f0cdbbbaSDave May 
1168b5bcf523SDave May   swarm->vec_field_set = PETSC_FALSE;
11693454631fSDave May   swarm->issetup = PETSC_FALSE;
1170480eef7bSDave May   swarm->swarm_type = DMSWARM_BASIC;
1171480eef7bSDave May   swarm->migrate_type = DMSWARM_MIGRATE_BASIC;
1172480eef7bSDave May   swarm->collect_type = DMSWARM_COLLECT_BASIC;
117340c453e9SDave May   swarm->migrate_error_on_missing_point = PETSC_FALSE;
1174b62e03f8SDave May 
1175f0cdbbbaSDave May   swarm->dmcell = NULL;
1176f0cdbbbaSDave May   swarm->collect_view_active = PETSC_FALSE;
1177f0cdbbbaSDave May   swarm->collect_view_reset_nlocal = -1;
117857795646SDave May 
1179f0cdbbbaSDave May   dm->dim  = 0;
11805f50eb2eSDave May   dm->ops->view                            = DMView_Swarm;
118157795646SDave May   dm->ops->load                            = NULL;
118257795646SDave May   dm->ops->setfromoptions                  = NULL;
118357795646SDave May   dm->ops->clone                           = NULL;
11843454631fSDave May   dm->ops->setup                           = DMSetup_Swarm;
118557795646SDave May   dm->ops->createdefaultsection            = NULL;
118657795646SDave May   dm->ops->createdefaultconstraints        = NULL;
1187b5bcf523SDave May   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
1188b5bcf523SDave May   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
118957795646SDave May   dm->ops->getlocaltoglobalmapping         = NULL;
119057795646SDave May   dm->ops->createfieldis                   = NULL;
119157795646SDave May   dm->ops->createcoordinatedm              = NULL;
119257795646SDave May   dm->ops->getcoloring                     = NULL;
119357795646SDave May   dm->ops->creatematrix                    = NULL;
119457795646SDave May   dm->ops->createinterpolation             = NULL;
119557795646SDave May   dm->ops->getaggregates                   = NULL;
119657795646SDave May   dm->ops->getinjection                    = NULL;
119757795646SDave May   dm->ops->refine                          = NULL;
119857795646SDave May   dm->ops->coarsen                         = NULL;
119957795646SDave May   dm->ops->refinehierarchy                 = NULL;
120057795646SDave May   dm->ops->coarsenhierarchy                = NULL;
120157795646SDave May   dm->ops->globaltolocalbegin              = NULL;
120257795646SDave May   dm->ops->globaltolocalend                = NULL;
120357795646SDave May   dm->ops->localtoglobalbegin              = NULL;
120457795646SDave May   dm->ops->localtoglobalend                = NULL;
120557795646SDave May   dm->ops->destroy                         = DMDestroy_Swarm;
120657795646SDave May   dm->ops->createsubdm                     = NULL;
120757795646SDave May   dm->ops->getdimpoints                    = NULL;
120857795646SDave May   dm->ops->locatepoints                    = NULL;
120957795646SDave May   PetscFunctionReturn(0);
121057795646SDave May }
1211