xref: /petsc/src/dm/impls/swarm/swarm.c (revision ed923d712065d5cd07973a5b5fb0ac097e7d6cf0)
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 
6*ed923d71SDave May PetscLogEvent DMSWARM_Migrate;
7*ed923d71SDave May PetscLogEvent DMSWARM_DataExchangerTopologySetup, DMSWARM_DataExchangerBegin, DMSWARM_DataExchangerEnd;
8*ed923d71SDave May PetscLogEvent DMSWARM_DataExchangerSendCount, DMSWARM_DataExchangerPack;
9*ed923d71SDave 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;
3616845f8f5SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr);
3625f50eb2eSDave May   PetscFunctionReturn(0);
3635f50eb2eSDave May }
3645f50eb2eSDave May 
365d3a51819SDave May /*@C
366d3a51819SDave May    DMSwarmSetCellDM - Attachs a DM to a DMSwarm
367d3a51819SDave May 
368d3a51819SDave May    Collective on DM
369d3a51819SDave May 
370d3a51819SDave May    Input parameters:
37162741f57SDave May +  dm - a DMSwarm
37262741f57SDave May -  dmcell - the DM to attach to the DMSwarm
373d3a51819SDave May 
374d3a51819SDave May    Level: beginner
375d3a51819SDave May 
376d3a51819SDave May    Notes:
377d3a51819SDave May    The attached DM (dmcell) will be queried for point location and
3788b8a3813SDave May    neighbor MPI-rank information if DMSwarmMigrate() is called.
379d3a51819SDave May 
3808b8a3813SDave May .seealso: DMSwarmSetType(), DMSwarmGetCellDM(), DMSwarmMigrate()
381d3a51819SDave May @*/
382b16650c8SDave May PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell)
383b16650c8SDave May {
384b16650c8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
385521f74f9SMatthew G. Knepley 
386521f74f9SMatthew G. Knepley   PetscFunctionBegin;
387b16650c8SDave May   swarm->dmcell = dmcell;
388b16650c8SDave May   PetscFunctionReturn(0);
389b16650c8SDave May }
390b16650c8SDave May 
391d3a51819SDave May /*@C
392d3a51819SDave May    DMSwarmGetCellDM - Fetches the attached cell DM
393d3a51819SDave May 
394d3a51819SDave May    Collective on DM
395d3a51819SDave May 
396d3a51819SDave May    Input parameter:
397d3a51819SDave May .  dm - a DMSwarm
398d3a51819SDave May 
399d3a51819SDave May    Output parameter:
400d3a51819SDave May .  dmcell - the DM which was attached to the DMSwarm
401d3a51819SDave May 
402d3a51819SDave May    Level: beginner
403d3a51819SDave May 
404d3a51819SDave May .seealso: DMSwarmSetCellDM()
405d3a51819SDave May @*/
406fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell)
407fe39f135SDave May {
408fe39f135SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
409521f74f9SMatthew G. Knepley 
410521f74f9SMatthew G. Knepley   PetscFunctionBegin;
411fe39f135SDave May   *dmcell = swarm->dmcell;
412fe39f135SDave May   PetscFunctionReturn(0);
413fe39f135SDave May }
414fe39f135SDave May 
415d3a51819SDave May /*@C
416d3a51819SDave May    DMSwarmGetLocalSize - Retrives the local length of fields registered
417d3a51819SDave May 
418d3a51819SDave May    Not collective
419d3a51819SDave May 
420d3a51819SDave May    Input parameter:
421d3a51819SDave May .  dm - a DMSwarm
422d3a51819SDave May 
423d3a51819SDave May    Output parameter:
424d3a51819SDave May .  nlocal - the length of each registered field
425d3a51819SDave May 
426d3a51819SDave May    Level: beginner
427d3a51819SDave May 
4288b8a3813SDave May .seealso: DMSwarmGetSize(), DMSwarmSetLocalSizes()
429d3a51819SDave May @*/
430dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal)
431dcf43ee8SDave May {
432dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
433dcf43ee8SDave May   PetscErrorCode ierr;
434dcf43ee8SDave May 
435521f74f9SMatthew G. Knepley   PetscFunctionBegin;
436521f74f9SMatthew G. Knepley   if (nlocal) {ierr = DataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);}
437dcf43ee8SDave May   PetscFunctionReturn(0);
438dcf43ee8SDave May }
439dcf43ee8SDave May 
440d3a51819SDave May /*@C
441d3a51819SDave May    DMSwarmGetSize - Retrives the total length of fields registered
442d3a51819SDave May 
443d3a51819SDave May    Collective on DM
444d3a51819SDave May 
445d3a51819SDave May    Input parameter:
446d3a51819SDave May .  dm - a DMSwarm
447d3a51819SDave May 
448d3a51819SDave May    Output parameter:
449d3a51819SDave May .  n - the total length of each registered field
450d3a51819SDave May 
451d3a51819SDave May    Level: beginner
452d3a51819SDave May 
453d3a51819SDave May    Note:
454d3a51819SDave May    This calls MPI_Allreduce upon each call (inefficient but safe)
455d3a51819SDave May 
4568b8a3813SDave May .seealso: DMSwarmGetLocalSize(), DMSwarmSetLocalSizes()
457d3a51819SDave May @*/
458dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n)
459dcf43ee8SDave May {
460dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
461dcf43ee8SDave May   PetscErrorCode ierr;
462dcf43ee8SDave May   PetscInt nlocal,ng;
463dcf43ee8SDave May 
464521f74f9SMatthew G. Knepley   PetscFunctionBegin;
465dcf43ee8SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
466dcf43ee8SDave May   ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
467dcf43ee8SDave May   if (n) { *n = ng; }
468dcf43ee8SDave May   PetscFunctionReturn(0);
469dcf43ee8SDave May }
470dcf43ee8SDave May 
471d3a51819SDave May /*@C
4728b8a3813SDave May    DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm with a native PETSc data type
473d3a51819SDave May 
474d3a51819SDave May    Collective on DM
475d3a51819SDave May 
476d3a51819SDave May    Input parameters:
47762741f57SDave May +  dm - a DMSwarm
478d3a51819SDave May .  fieldname - the textual name to identify this field
479d3a51819SDave May .  blocksize - the number of each data type
48062741f57SDave May -  type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG)
481d3a51819SDave May 
482d3a51819SDave May    Level: beginner
483d3a51819SDave May 
484d3a51819SDave May    Notes:
4858b8a3813SDave May    The textual name for each registered field must be unique.
486d3a51819SDave May 
487d3a51819SDave May .seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
488d3a51819SDave May @*/
4895f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
490b62e03f8SDave May {
4912eac95f8SDave May   PetscErrorCode ierr;
492b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
493b62e03f8SDave May   size_t size;
494b62e03f8SDave May 
495521f74f9SMatthew G. Knepley   PetscFunctionBegin;
4965f50eb2eSDave May   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
4975f50eb2eSDave May   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
4985f50eb2eSDave May 
4995f50eb2eSDave May   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5005f50eb2eSDave May   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5015f50eb2eSDave May   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5025f50eb2eSDave May   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
5035f50eb2eSDave May   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
504b62e03f8SDave May 
5052ddcf43eSMatthew G. Knepley   ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr);
506b62e03f8SDave May   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
50752c3ed93SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
50852c3ed93SDave May   {
50952c3ed93SDave May     DataField gfield;
51052c3ed93SDave May 
51152c3ed93SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
51252c3ed93SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
51352c3ed93SDave May   }
514b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
515b62e03f8SDave May   PetscFunctionReturn(0);
516b62e03f8SDave May }
517b62e03f8SDave May 
518d3a51819SDave May /*@C
519d3a51819SDave May    DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm
520d3a51819SDave May 
521d3a51819SDave May    Collective on DM
522d3a51819SDave May 
523d3a51819SDave May    Input parameters:
52462741f57SDave May +  dm - a DMSwarm
525d3a51819SDave May .  fieldname - the textual name to identify this field
52662741f57SDave May -  size - the size in bytes of the user struct of each data type
527d3a51819SDave May 
528d3a51819SDave May    Level: beginner
529d3a51819SDave May 
530d3a51819SDave May    Notes:
5318b8a3813SDave May    The textual name for each registered field must be unique.
532d3a51819SDave May 
533d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField()
534d3a51819SDave May @*/
5355f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
536b62e03f8SDave May {
5372eac95f8SDave May   PetscErrorCode ierr;
538b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
539b62e03f8SDave May 
540521f74f9SMatthew G. Knepley   PetscFunctionBegin;
5412eac95f8SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
542b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
543b62e03f8SDave May   PetscFunctionReturn(0);
544b62e03f8SDave May }
545b62e03f8SDave May 
546d3a51819SDave May /*@C
547d3a51819SDave May    DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm
548d3a51819SDave May 
549d3a51819SDave May    Collective on DM
550d3a51819SDave May 
551d3a51819SDave May    Input parameters:
55262741f57SDave May +  dm - a DMSwarm
553d3a51819SDave May .  fieldname - the textual name to identify this field
554d3a51819SDave May .  size - the size in bytes of the user data type
55562741f57SDave May -  blocksize - the number of each data type
556d3a51819SDave May 
557d3a51819SDave May    Level: beginner
558d3a51819SDave May 
559d3a51819SDave May    Notes:
5608b8a3813SDave May    The textual name for each registered field must be unique.
561d3a51819SDave May 
562d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
563d3a51819SDave May @*/
564320740a0SDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize)
565b62e03f8SDave May {
566b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
5676845f8f5SDave May   PetscErrorCode ierr;
568b62e03f8SDave May 
569521f74f9SMatthew G. Knepley   PetscFunctionBegin;
570320740a0SDave May   ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
571320740a0SDave May   {
572320740a0SDave May     DataField gfield;
573320740a0SDave May 
574320740a0SDave May     ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
575320740a0SDave May     ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
576320740a0SDave May   }
577b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
578b62e03f8SDave May   PetscFunctionReturn(0);
579b62e03f8SDave May }
580b62e03f8SDave May 
581d3a51819SDave May /*@C
582d3a51819SDave May    DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field
583d3a51819SDave May 
584d3a51819SDave May    Not collective
585d3a51819SDave May 
586d3a51819SDave May    Input parameters:
58762741f57SDave May +  dm - a DMSwarm
58862741f57SDave May -  fieldname - the textual name to identify this field
589d3a51819SDave May 
590d3a51819SDave May    Output parameters:
59162741f57SDave May +  blocksize - the number of each data type
592d3a51819SDave May .  type - the data type
59362741f57SDave May -  data - pointer to raw array
594d3a51819SDave May 
595d3a51819SDave May    Level: beginner
596d3a51819SDave May 
597d3a51819SDave May    Notes:
5988b8a3813SDave May    The array must be returned using a matching call to DMSwarmRestoreField().
599d3a51819SDave May 
600d3a51819SDave May .seealso: DMSwarmRestoreField()
601d3a51819SDave May @*/
6025f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
603b62e03f8SDave May {
604b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
605b62e03f8SDave May   DataField gfield;
6062eac95f8SDave May   PetscErrorCode ierr;
607b62e03f8SDave May 
608521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6093454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
6102eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6116845f8f5SDave May   ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr);
6126845f8f5SDave May   ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr);
6131b1ea282SDave May   if (blocksize) {*blocksize = gfield->bs; }
614b5bcf523SDave May   if (type) { *type = gfield->petsc_type; }
615b62e03f8SDave May   PetscFunctionReturn(0);
616b62e03f8SDave May }
617b62e03f8SDave May 
618d3a51819SDave May /*@C
619d3a51819SDave May    DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field
620d3a51819SDave May 
621d3a51819SDave May    Not collective
622d3a51819SDave May 
623d3a51819SDave May    Input parameters:
62462741f57SDave May +  dm - a DMSwarm
62562741f57SDave May -  fieldname - the textual name to identify this field
626d3a51819SDave May 
627d3a51819SDave May    Output parameters:
62862741f57SDave May +  blocksize - the number of each data type
629d3a51819SDave May .  type - the data type
63062741f57SDave May -  data - pointer to raw array
631d3a51819SDave May 
632d3a51819SDave May    Level: beginner
633d3a51819SDave May 
634d3a51819SDave May    Notes:
6358b8a3813SDave May    The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField().
636d3a51819SDave May 
637d3a51819SDave May .seealso: DMSwarmGetField()
638d3a51819SDave May @*/
6395f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
640b62e03f8SDave May {
641b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
642b62e03f8SDave May   DataField gfield;
6432eac95f8SDave May   PetscErrorCode ierr;
644b62e03f8SDave May 
645521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6462eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
6476845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
648b62e03f8SDave May   if (data) *data = NULL;
649b62e03f8SDave May   PetscFunctionReturn(0);
650b62e03f8SDave May }
651b62e03f8SDave May 
652d3a51819SDave May /*@C
653d3a51819SDave May    DMSwarmAddPoint - Add space for one new point in the DMSwarm
654d3a51819SDave May 
655d3a51819SDave May    Not collective
656d3a51819SDave May 
657d3a51819SDave May    Input parameter:
658d3a51819SDave May .  dm - a DMSwarm
659d3a51819SDave May 
660d3a51819SDave May    Level: beginner
661d3a51819SDave May 
662d3a51819SDave May    Notes:
6638b8a3813SDave May    The new point will have all fields initialized to zero.
664d3a51819SDave May 
665d3a51819SDave May .seealso: DMSwarmAddNPoints()
666d3a51819SDave May @*/
667cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
668cb1d1399SDave May {
669cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
670cb1d1399SDave May   PetscErrorCode ierr;
671cb1d1399SDave May 
672521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6733454631fSDave May   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
674cb1d1399SDave May   ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr);
675cb1d1399SDave May   PetscFunctionReturn(0);
676cb1d1399SDave May }
677cb1d1399SDave May 
678d3a51819SDave May /*@C
679d3a51819SDave May    DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm
680d3a51819SDave May 
681d3a51819SDave May    Not collective
682d3a51819SDave May 
683d3a51819SDave May    Input parameters:
68462741f57SDave May +  dm - a DMSwarm
68562741f57SDave May -  npoints - the number of new points to add
686d3a51819SDave May 
687d3a51819SDave May    Level: beginner
688d3a51819SDave May 
689d3a51819SDave May    Notes:
6908b8a3813SDave May    The new point will have all fields initialized to zero.
691d3a51819SDave May 
692d3a51819SDave May .seealso: DMSwarmAddPoint()
693d3a51819SDave May @*/
694cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
695cb1d1399SDave May {
696cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
697cb1d1399SDave May   PetscErrorCode ierr;
698cb1d1399SDave May   PetscInt nlocal;
699cb1d1399SDave May 
700521f74f9SMatthew G. Knepley   PetscFunctionBegin;
701cb1d1399SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
702cb1d1399SDave May   nlocal = nlocal + npoints;
70365141ba8SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,DATA_BUCKET_BUFFER_DEFAULT);CHKERRQ(ierr);
704cb1d1399SDave May   PetscFunctionReturn(0);
705cb1d1399SDave May }
706cb1d1399SDave May 
707d3a51819SDave May /*@C
708d3a51819SDave May    DMSwarmRemovePoint - Remove the last point from the DMSwarm
709d3a51819SDave May 
710d3a51819SDave May    Not collective
711d3a51819SDave May 
712d3a51819SDave May    Input parameter:
713d3a51819SDave May .  dm - a DMSwarm
714d3a51819SDave May 
715d3a51819SDave May    Level: beginner
716d3a51819SDave May 
717d3a51819SDave May .seealso: DMSwarmRemovePointAtIndex()
718d3a51819SDave May @*/
719cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
720cb1d1399SDave May {
721cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
722cb1d1399SDave May   PetscErrorCode ierr;
723cb1d1399SDave May 
724521f74f9SMatthew G. Knepley   PetscFunctionBegin;
725cb1d1399SDave May   ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
726cb1d1399SDave May   PetscFunctionReturn(0);
727cb1d1399SDave May }
728cb1d1399SDave May 
729d3a51819SDave May /*@C
730d3a51819SDave May    DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm
731d3a51819SDave May 
732d3a51819SDave May    Not collective
733d3a51819SDave May 
734d3a51819SDave May    Input parameters:
73562741f57SDave May +  dm - a DMSwarm
73662741f57SDave May -  idx - index of point to remove
737d3a51819SDave May 
738d3a51819SDave May    Level: beginner
739d3a51819SDave May 
740d3a51819SDave May .seealso: DMSwarmRemovePoint()
741d3a51819SDave May @*/
742cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
743cb1d1399SDave May {
744cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
745cb1d1399SDave May   PetscErrorCode ierr;
746cb1d1399SDave May 
747521f74f9SMatthew G. Knepley   PetscFunctionBegin;
748cb1d1399SDave May   ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
749cb1d1399SDave May   PetscFunctionReturn(0);
750cb1d1399SDave May }
751b62e03f8SDave May 
752095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points)
7533454631fSDave May {
754dcf43ee8SDave May   PetscErrorCode ierr;
755521f74f9SMatthew G. Knepley 
756521f74f9SMatthew G. Knepley   PetscFunctionBegin;
757dcf43ee8SDave May   ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr);
7583454631fSDave May   PetscFunctionReturn(0);
7593454631fSDave May }
7603454631fSDave May 
761d3a51819SDave May /*@C
762d3a51819SDave May    DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks
763d3a51819SDave May 
764d3a51819SDave May    Collective on DM
765d3a51819SDave May 
766d3a51819SDave May    Input parameters:
76762741f57SDave May +  dm - the DMSwarm
76862741f57SDave May -  remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank
769d3a51819SDave May 
770d3a51819SDave May    Notes:
7718b8a3813SDave May    The DM will be modified to accomodate received points.
7728b8a3813SDave May    If remove_sent_points = PETSC_TRUE, any points that were sent will be removed from the DM.
7738b8a3813SDave May    Different styles of migration are supported. See DMSwarmSetMigrateType().
774d3a51819SDave May 
775d3a51819SDave May    Level: advanced
776d3a51819SDave May 
777d3a51819SDave May .seealso: DMSwarmSetMigrateType()
778d3a51819SDave May @*/
779095059a4SDave May PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points)
7803454631fSDave May {
781f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
7823454631fSDave May   PetscErrorCode ierr;
783f0cdbbbaSDave May 
784521f74f9SMatthew G. Knepley   PetscFunctionBegin;
785*ed923d71SDave May   ierr = PetscLogEventBegin(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr);
786f0cdbbbaSDave May   switch (swarm->migrate_type) {
787f0cdbbbaSDave May     case DMSWARM_MIGRATE_BASIC:
788095059a4SDave May       ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr);
789f0cdbbbaSDave May       break;
790f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLNSCATTER:
791f0cdbbbaSDave May       ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr);
792f0cdbbbaSDave May       break;
793f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLEXACT:
794f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented");
795521f74f9SMatthew G. Knepley       /*ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr);*/
796f0cdbbbaSDave May       break;
797f0cdbbbaSDave May     case DMSWARM_MIGRATE_USER:
798f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented");
799521f74f9SMatthew G. Knepley       /*ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr);*/
800f0cdbbbaSDave May       break;
801f0cdbbbaSDave May     default:
802f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown");
803f0cdbbbaSDave May       break;
804f0cdbbbaSDave May   }
805*ed923d71SDave May   ierr = PetscLogEventEnd(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr);
8063454631fSDave May   PetscFunctionReturn(0);
8073454631fSDave May }
8083454631fSDave May 
809f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize);
810f0cdbbbaSDave May 
811d3a51819SDave May /*
812d3a51819SDave May  DMSwarmCollectViewCreate
813d3a51819SDave May 
814d3a51819SDave May  * Applies a collection method and gathers point neighbour points into dm
815d3a51819SDave May 
816d3a51819SDave May  Notes:
8178b8a3813SDave May  Users should call DMSwarmCollectViewDestroy() after
818d3a51819SDave May  they have finished computations associated with the collected points
819d3a51819SDave May */
820d3a51819SDave May 
821d3a51819SDave May /*@C
822d3a51819SDave May    DMSwarmCollectViewCreate - Applies a collection method and gathers points
823d3a51819SDave May    in neighbour MPI-ranks into the DMSwarm
824d3a51819SDave May 
825d3a51819SDave May    Collective on DM
826d3a51819SDave May 
827d3a51819SDave May    Input parameter:
828d3a51819SDave May .  dm - the DMSwarm
829d3a51819SDave May 
830d3a51819SDave May    Notes:
831d3a51819SDave May    Users should call DMSwarmCollectViewDestroy() after
832d3a51819SDave May    they have finished computations associated with the collected points
8338b8a3813SDave May    Different collect methods are supported. See DMSwarmSetCollectType().
834d3a51819SDave May 
835d3a51819SDave May    Level: advanced
836d3a51819SDave May 
837d3a51819SDave May .seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType()
838d3a51819SDave May @*/
839fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm)
8402712d1f2SDave May {
8412712d1f2SDave May   PetscErrorCode ierr;
8422712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8432712d1f2SDave May   PetscInt ng;
8442712d1f2SDave May 
845521f74f9SMatthew G. Knepley   PetscFunctionBegin;
846480eef7bSDave May   if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active");
847480eef7bSDave May   ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr);
848480eef7bSDave May   switch (swarm->collect_type) {
849f0cdbbbaSDave May 
850480eef7bSDave May     case DMSWARM_COLLECT_BASIC:
8512712d1f2SDave May       ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr);
852480eef7bSDave May       break;
853480eef7bSDave May     case DMSWARM_COLLECT_DMDABOUNDINGBOX:
854f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented");
855521f74f9SMatthew G. Knepley       /*ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr);*/
856480eef7bSDave May       break;
857480eef7bSDave May     case DMSWARM_COLLECT_GENERAL:
858f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented");
859521f74f9SMatthew G. Knepley       /*ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr);*/
860480eef7bSDave May       break;
861480eef7bSDave May     default:
862f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown");
863480eef7bSDave May       break;
864480eef7bSDave May   }
865480eef7bSDave May   swarm->collect_view_active = PETSC_TRUE;
866480eef7bSDave May   swarm->collect_view_reset_nlocal = ng;
8672712d1f2SDave May   PetscFunctionReturn(0);
8682712d1f2SDave May }
8692712d1f2SDave May 
870d3a51819SDave May /*@C
871d3a51819SDave May    DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate()
872d3a51819SDave May 
873d3a51819SDave May    Collective on DM
874d3a51819SDave May 
875d3a51819SDave May    Input parameters:
876d3a51819SDave May .  dm - the DMSwarm
877d3a51819SDave May 
878d3a51819SDave May    Notes:
879d3a51819SDave May    Users should call DMSwarmCollectViewCreate() before this function is called.
880d3a51819SDave May 
881d3a51819SDave May    Level: advanced
882d3a51819SDave May 
883d3a51819SDave May .seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType()
884d3a51819SDave May @*/
885fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm)
8862712d1f2SDave May {
8872712d1f2SDave May   PetscErrorCode ierr;
8882712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
8892712d1f2SDave May 
890521f74f9SMatthew G. Knepley   PetscFunctionBegin;
891480eef7bSDave May   if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active");
892480eef7bSDave May   ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr);
893480eef7bSDave May   swarm->collect_view_active = PETSC_FALSE;
8942712d1f2SDave May   PetscFunctionReturn(0);
8952712d1f2SDave May }
8963454631fSDave May 
897f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm)
898f0cdbbbaSDave May {
899f0cdbbbaSDave May   PetscInt dim;
900f0cdbbbaSDave May   PetscErrorCode ierr;
901f0cdbbbaSDave May 
902521f74f9SMatthew G. Knepley   PetscFunctionBegin;
903f0cdbbbaSDave May   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
904f0cdbbbaSDave May   if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
905f0cdbbbaSDave May   if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
906f0cdbbbaSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr);
907e2d107dbSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_cellid,1,PETSC_INT);CHKERRQ(ierr);
908f0cdbbbaSDave May   PetscFunctionReturn(0);
909f0cdbbbaSDave May }
910f0cdbbbaSDave May 
911d3a51819SDave May /*@C
912d3a51819SDave May    DMSwarmSetType - Set particular flavor of DMSwarm
913d3a51819SDave May 
914d3a51819SDave May    Collective on DM
915d3a51819SDave May 
916d3a51819SDave May    Input parameters:
91762741f57SDave May +  dm - the DMSwarm
91862741f57SDave May -  stype - the DMSwarm type (e.g. DMSWARM_PIC)
919d3a51819SDave May 
920d3a51819SDave May    Level: advanced
921d3a51819SDave May 
922d3a51819SDave May .seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType()
923d3a51819SDave May @*/
924f0cdbbbaSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype)
925f0cdbbbaSDave May {
926f0cdbbbaSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
927f0cdbbbaSDave May   PetscErrorCode ierr;
928f0cdbbbaSDave May 
929521f74f9SMatthew G. Knepley   PetscFunctionBegin;
930f0cdbbbaSDave May   swarm->swarm_type = stype;
931f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
932f0cdbbbaSDave May     ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr);
933f0cdbbbaSDave May   }
934f0cdbbbaSDave May   PetscFunctionReturn(0);
935f0cdbbbaSDave May }
936f0cdbbbaSDave May 
9373454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm)
9383454631fSDave May {
9393454631fSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
9403454631fSDave May   PetscErrorCode ierr;
9413454631fSDave May   PetscMPIInt rank;
9423454631fSDave May   PetscInt p,npoints,*rankval;
9433454631fSDave May 
944521f74f9SMatthew G. Knepley   PetscFunctionBegin;
9453454631fSDave May   if (swarm->issetup) PetscFunctionReturn(0);
9463454631fSDave May 
9473454631fSDave May   swarm->issetup = PETSC_TRUE;
9483454631fSDave May 
949f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
950f0cdbbbaSDave May     /* check dmcell exists */
951f0cdbbbaSDave May     if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM");
952f0cdbbbaSDave May 
953f0cdbbbaSDave May     if (swarm->dmcell->ops->locatepointssubdomain) {
954f0cdbbbaSDave May       /* check methods exists for exact ownership identificiation */
955521f74f9SMatthew G. Knepley       ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");CHKERRQ(ierr);
956f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT;
957f0cdbbbaSDave May     } else {
958f0cdbbbaSDave May       /* check methods exist for point location AND rank neighbor identification */
959f0cdbbbaSDave May       if (swarm->dmcell->ops->locatepoints) {
960521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->LocatePoints\n");CHKERRQ(ierr);
961f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined");
962f0cdbbbaSDave May 
963f0cdbbbaSDave May       if (swarm->dmcell->ops->getneighbors) {
964521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->GetNeigbors\n");CHKERRQ(ierr);
965f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined");
966f0cdbbbaSDave May 
967f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER;
968f0cdbbbaSDave May     }
969f0cdbbbaSDave May   }
970f0cdbbbaSDave May 
971f0cdbbbaSDave May   ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr);
972f0cdbbbaSDave May 
9733454631fSDave May   /* check some fields were registered */
9743454631fSDave May   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
9753454631fSDave May 
9763454631fSDave May   /* check local sizes were set */
9773454631fSDave May   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
9783454631fSDave May 
9793454631fSDave May   /* initialize values in pid and rank placeholders */
9803454631fSDave May   /* TODO: [pid - use MPI_Scan] */
9813454631fSDave May   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
9823454631fSDave May   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
983f0cdbbbaSDave May   ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
9843454631fSDave May   for (p=0; p<npoints; p++) {
9853454631fSDave May     rankval[p] = (PetscInt)rank;
9863454631fSDave May   }
987f0cdbbbaSDave May   ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
9883454631fSDave May   PetscFunctionReturn(0);
9893454631fSDave May }
9903454631fSDave May 
991dc5f5ce9SDave May extern PetscErrorCode DMSwarmSortDestroy(DMSwarmSort *_ctx);
992dc5f5ce9SDave May 
99357795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm)
99457795646SDave May {
99557795646SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
99657795646SDave May   PetscErrorCode ierr;
99757795646SDave May 
99857795646SDave May   PetscFunctionBegin;
9996845f8f5SDave May   ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr);
1000dc5f5ce9SDave May   if (swarm->sort_context) {
1001dc5f5ce9SDave May     ierr = DMSwarmSortDestroy(&swarm->sort_context);CHKERRQ(ierr);
1002dc5f5ce9SDave May   }
100357795646SDave May   ierr = PetscFree(swarm);CHKERRQ(ierr);
100457795646SDave May   PetscFunctionReturn(0);
100557795646SDave May }
100657795646SDave May 
1007a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer)
1008a9ee3421SMatthew G. Knepley {
1009a9ee3421SMatthew G. Knepley   DM             cdm;
1010a9ee3421SMatthew G. Knepley   PetscDraw      draw;
1011a9ee3421SMatthew G. Knepley   PetscReal     *coords, oldPause;
1012a9ee3421SMatthew G. Knepley   PetscInt       Np, p, bs;
1013a9ee3421SMatthew G. Knepley   PetscErrorCode ierr;
1014a9ee3421SMatthew G. Knepley 
1015a9ee3421SMatthew G. Knepley   PetscFunctionBegin;
1016a9ee3421SMatthew G. Knepley   ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr);
1017a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr);
1018a9ee3421SMatthew G. Knepley   ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr);
1019a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr);
1020a9ee3421SMatthew G. Knepley   ierr = DMView(cdm, viewer);CHKERRQ(ierr);
1021a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr);
1022a9ee3421SMatthew G. Knepley 
1023a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr);
1024a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1025a9ee3421SMatthew G. Knepley   for (p = 0; p < Np; ++p) {
1026a9ee3421SMatthew G. Knepley     const PetscInt i = p*bs;
1027a9ee3421SMatthew G. Knepley 
1028a9ee3421SMatthew G. Knepley     ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], 0.01, 0.01, PETSC_DRAW_BLUE);CHKERRQ(ierr);
1029a9ee3421SMatthew G. Knepley   }
1030a9ee3421SMatthew G. Knepley   ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1031a9ee3421SMatthew G. Knepley   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
1032a9ee3421SMatthew G. Knepley   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
1033a9ee3421SMatthew G. Knepley   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1034a9ee3421SMatthew G. Knepley   PetscFunctionReturn(0);
1035a9ee3421SMatthew G. Knepley }
1036a9ee3421SMatthew G. Knepley 
10375f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
10385f50eb2eSDave May {
10395f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1040a9ee3421SMatthew G. Knepley   PetscBool      iascii,ibinary,ishdf5,isvtk,isdraw;
10415f50eb2eSDave May   PetscErrorCode ierr;
10425f50eb2eSDave May 
10435f50eb2eSDave May   PetscFunctionBegin;
10445f50eb2eSDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10455f50eb2eSDave May   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
10465f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
10475f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
10485f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
10495f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1050a9ee3421SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW,  &isdraw);CHKERRQ(ierr);
10515f50eb2eSDave May   if (iascii) {
10526845f8f5SDave May     ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
10535f50eb2eSDave May   } else if (ibinary) {
1054a9ee3421SMatthew G. Knepley     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support");
10555f50eb2eSDave May   } else if (ishdf5) {
10565f50eb2eSDave May #if defined(PETSC_HAVE_HDF5)
10575f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
10585f50eb2eSDave May #else
10595f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
10605f50eb2eSDave May #endif
10615f50eb2eSDave May   } else if (isvtk) {
10625f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
1063a9ee3421SMatthew G. Knepley   } else if (isdraw) {
1064a9ee3421SMatthew G. Knepley     ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr);
10655f50eb2eSDave May   }
10665f50eb2eSDave May   PetscFunctionReturn(0);
10675f50eb2eSDave May }
10685f50eb2eSDave May 
1069d3a51819SDave May /*MC
1070d3a51819SDave May 
1071d3a51819SDave May  DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type.
107262741f57SDave May  This implementation was designed for particle methods in which the underlying
1073d3a51819SDave May  data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type.
1074d3a51819SDave May 
107562741f57SDave May  User data can be represented by DMSwarm through a registering "fields".
107662741f57SDave May  To register a field, the user must provide;
107762741f57SDave May  (a) a unique name;
107862741f57SDave May  (b) the data type (or size in bytes);
107962741f57SDave May  (c) the block size of the data.
1080d3a51819SDave May 
1081d3a51819SDave May  For example, suppose the application requires a unique id, energy, momentum and density to be stored
108262741f57SDave May  on a set of of particles. Then the following code could be used
1083d3a51819SDave May 
108462741f57SDave May $    DMSwarmInitializeFieldRegister(dm)
108562741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG);
108662741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL);
108762741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL);
108862741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT);
108962741f57SDave May $    DMSwarmFinalizeFieldRegister(dm)
1090d3a51819SDave May 
1091d3a51819SDave May  The fields represented by DMSwarm are dynamic and can be re-sized at any time.
109262741f57SDave May  The only restriction imposed by DMSwarm is that all fields contain the same number of points.
1093d3a51819SDave May 
1094d3a51819SDave May  To support particle methods, "migration" techniques are provided. These methods migrate data
1095d3a51819SDave May  between MPI-ranks.
1096d3a51819SDave May 
1097d3a51819SDave May  DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector().
1098d3a51819SDave May  As a DMSwarm may internally define and store values of different data types,
109962741f57SDave May  before calling DMCreateGlobalVector() or DMCreateLocalVector(), the user must inform DMSwarm which
1100d3a51819SDave May  fields should be used to define a Vec object via
1101d3a51819SDave May    DMSwarmVectorDefineField()
1102d3a51819SDave May  The specified field can can changed be changed at any time - thereby permitting vectors
1103d3a51819SDave May  compatable with different fields to be created.
1104d3a51819SDave May 
110562741f57SDave May  A dual representation of fields in the DMSwarm and a Vec object is permitted via
1106d3a51819SDave May    DMSwarmCreateGlobalVectorFromField()
1107d3a51819SDave May  Here the data defining the field in the DMSwarm is shared with a Vec.
1108d3a51819SDave May  This is inherently unsafe if you alter the size of the field at any time between
1109d3a51819SDave May  calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField().
1110cc651181SDave May  If the local size of the DMSwarm does not match the local size of the global vector
1111cc651181SDave May  when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown.
1112d3a51819SDave May 
111362741f57SDave May  Additional high-level support is provided for Particle-In-Cell methods.
111462741f57SDave May  Please refer to the man page for DMSwarmSetType().
111562741f57SDave May 
1116d3a51819SDave May  Level: beginner
1117d3a51819SDave May 
1118d3a51819SDave May .seealso: DMType, DMCreate(), DMSetType()
1119d3a51819SDave May M*/
112057795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
112157795646SDave May {
112257795646SDave May   DM_Swarm      *swarm;
112357795646SDave May   PetscErrorCode ierr;
112457795646SDave May 
112557795646SDave May   PetscFunctionBegin;
112657795646SDave May   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
112757795646SDave May   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
1128f0cdbbbaSDave May   dm->data = swarm;
112957795646SDave May 
11306845f8f5SDave May   ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr);
1131f0cdbbbaSDave May   ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr);
1132f0cdbbbaSDave May 
1133b5bcf523SDave May   swarm->vec_field_set = PETSC_FALSE;
11343454631fSDave May   swarm->issetup = PETSC_FALSE;
1135480eef7bSDave May   swarm->swarm_type = DMSWARM_BASIC;
1136480eef7bSDave May   swarm->migrate_type = DMSWARM_MIGRATE_BASIC;
1137480eef7bSDave May   swarm->collect_type = DMSWARM_COLLECT_BASIC;
113840c453e9SDave May   swarm->migrate_error_on_missing_point = PETSC_FALSE;
1139b62e03f8SDave May 
1140f0cdbbbaSDave May   swarm->dmcell = NULL;
1141f0cdbbbaSDave May   swarm->collect_view_active = PETSC_FALSE;
1142f0cdbbbaSDave May   swarm->collect_view_reset_nlocal = -1;
114357795646SDave May 
1144f0cdbbbaSDave May   dm->dim  = 0;
11455f50eb2eSDave May   dm->ops->view                            = DMView_Swarm;
114657795646SDave May   dm->ops->load                            = NULL;
114757795646SDave May   dm->ops->setfromoptions                  = NULL;
114857795646SDave May   dm->ops->clone                           = NULL;
11493454631fSDave May   dm->ops->setup                           = DMSetup_Swarm;
115057795646SDave May   dm->ops->createdefaultsection            = NULL;
115157795646SDave May   dm->ops->createdefaultconstraints        = NULL;
1152b5bcf523SDave May   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
1153b5bcf523SDave May   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
115457795646SDave May   dm->ops->getlocaltoglobalmapping         = NULL;
115557795646SDave May   dm->ops->createfieldis                   = NULL;
115657795646SDave May   dm->ops->createcoordinatedm              = NULL;
115757795646SDave May   dm->ops->getcoloring                     = NULL;
115857795646SDave May   dm->ops->creatematrix                    = NULL;
115957795646SDave May   dm->ops->createinterpolation             = NULL;
116057795646SDave May   dm->ops->getaggregates                   = NULL;
116157795646SDave May   dm->ops->getinjection                    = NULL;
116257795646SDave May   dm->ops->refine                          = NULL;
116357795646SDave May   dm->ops->coarsen                         = NULL;
116457795646SDave May   dm->ops->refinehierarchy                 = NULL;
116557795646SDave May   dm->ops->coarsenhierarchy                = NULL;
116657795646SDave May   dm->ops->globaltolocalbegin              = NULL;
116757795646SDave May   dm->ops->globaltolocalend                = NULL;
116857795646SDave May   dm->ops->localtoglobalbegin              = NULL;
116957795646SDave May   dm->ops->localtoglobalend                = NULL;
117057795646SDave May   dm->ops->destroy                         = DMDestroy_Swarm;
117157795646SDave May   dm->ops->createsubdm                     = NULL;
117257795646SDave May   dm->ops->getdimpoints                    = NULL;
117357795646SDave May   dm->ops->locatepoints                    = NULL;
117457795646SDave May   PetscFunctionReturn(0);
117557795646SDave May }
1176