xref: /petsc/src/dm/impls/swarm/swarm.c (revision 480eef7b45975a89e98bc4cecdc59060a0a0bd97)
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 
6dcf43ee8SDave May PetscErrorCode DMSwarmMigrate_Push_Basic(DM dm,PetscBool remove_sent_points);
7dcf43ee8SDave May 
8dcf43ee8SDave May 
957795646SDave May //typedef PetscErrorCode (*swarm_project)(DM,DM,Vec) DMSwarmProjectMethod; /* swarm, geometry, result */
1057795646SDave May 
1157795646SDave May //typedef enum { PROJECT_DMDA_AQ1=0, PROJECT_DMDA_P0 } DMSwarmDMDAProjectionType;
1257795646SDave May 
1357795646SDave May #if 0
1457795646SDave May 
1557795646SDave May /* Defines what the local space will be */
16b62e03f8SDave May PetscErrorCode DMSwarmSetOverlap(void)
1757795646SDave May {
1857795646SDave May 
19b62e03f8SDave May   PetscFunctionReturn(0);
2057795646SDave May }
2157795646SDave May 
2257795646SDave May 
2357795646SDave May /* coordinates */
2457795646SDave May /*
2557795646SDave May DMGetCoordinateDM returns self
2657795646SDave May DMGetCoordinates and DMGetCoordinatesLocal return same thing
2757795646SDave May Local view could be used to define overlapping information
2857795646SDave May */
2957795646SDave May 
3057795646SDave May #endif
3157795646SDave May 
3257795646SDave May #undef __FUNCT__
33b5bcf523SDave May #define __FUNCT__ "DMSwarmVectorDefineField"
34b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmVectorDefineField(DM dm,const char fieldname[])
35b5bcf523SDave May {
36b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
37b5bcf523SDave May   PetscErrorCode ierr;
38b5bcf523SDave May   PetscInt bs,n;
39b5bcf523SDave May   PetscScalar *array;
40b5bcf523SDave May   PetscDataType type;
41b5bcf523SDave May 
423454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
436845f8f5SDave May   ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr);
44b5bcf523SDave May   ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
45b5bcf523SDave May 
46b5bcf523SDave May   /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */
47b5bcf523SDave May   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL");
48b5bcf523SDave May 
49b5bcf523SDave May   PetscSNPrintf(swarm->vec_field_name,PETSC_MAX_PATH_LEN-1,"%s",fieldname);
50b5bcf523SDave May   swarm->vec_field_set = PETSC_TRUE;
51b5bcf523SDave May   swarm->vec_field_bs = 1;//bs;
52b5bcf523SDave May   swarm->vec_field_nlocal = n;
53dcf43ee8SDave May   ierr = DMSwarmRestoreField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
54b5bcf523SDave May 
55b5bcf523SDave May   PetscFunctionReturn(0);
56b5bcf523SDave May }
57b5bcf523SDave May 
58b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */
59b5bcf523SDave May #undef __FUNCT__
60b5bcf523SDave May #define __FUNCT__ "DMCreateGlobalVector_Swarm"
61b5bcf523SDave May PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec)
62b5bcf523SDave May {
63b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
64b5bcf523SDave May   PetscErrorCode ierr;
65b5bcf523SDave May   Vec x;
66b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
67b5bcf523SDave May 
683454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
69b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
70b5bcf523SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);
71b5bcf523SDave May   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr);
72b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
73dcf43ee8SDave May   ierr = VecSetSizes(x,swarm->db->L,PETSC_DETERMINE);CHKERRQ(ierr);
74b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
75b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
76b5bcf523SDave May   *vec = x;
77b5bcf523SDave May 
78b5bcf523SDave May   PetscFunctionReturn(0);
79b5bcf523SDave May }
80b5bcf523SDave May 
81b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */
82b5bcf523SDave May #undef __FUNCT__
83b5bcf523SDave May #define __FUNCT__ "DMCreateLocalVector_Swarm"
84b5bcf523SDave May PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec)
85b5bcf523SDave May {
86b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
87b5bcf523SDave May   PetscErrorCode ierr;
88b5bcf523SDave May   Vec x;
89b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
90b5bcf523SDave May 
913454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
92b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
93b5bcf523SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);
94b5bcf523SDave May   ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr);
95b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
96dcf43ee8SDave May   ierr = VecSetSizes(x,swarm->db->L,swarm->db->L);CHKERRQ(ierr);
97b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
98b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
99b5bcf523SDave May   *vec = x;
100b5bcf523SDave May 
101b5bcf523SDave May   PetscFunctionReturn(0);
102b5bcf523SDave May }
103b5bcf523SDave May 
104b5bcf523SDave May #undef __FUNCT__
105b5bcf523SDave May #define __FUNCT__ "DMSwarmCreateGlobalVectorFromField"
106b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
107b5bcf523SDave May {
108b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
109b5bcf523SDave May   PetscErrorCode ierr;
110b5bcf523SDave May   PetscInt bs,n;
111b5bcf523SDave May   PetscScalar *array;
112b5bcf523SDave May   Vec x;
113b5bcf523SDave May   PetscDataType type;
114b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
1153454631fSDave May   PetscMPIInt commsize;
116b5bcf523SDave May 
1173454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
1186845f8f5SDave May   ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr);
119b5bcf523SDave May   ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
120b5bcf523SDave May 
121b5bcf523SDave May   /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */
122b5bcf523SDave May   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL");
123b5bcf523SDave May 
1243454631fSDave May   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&commsize);CHKERRQ(ierr);
1253454631fSDave May   if (commsize == 1) {
126b5bcf523SDave May     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)dm),1,n,array,&x);CHKERRQ(ierr);
1273454631fSDave May   } else {
1283454631fSDave May     ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)dm),1,n,PETSC_DETERMINE,array,&x);CHKERRQ(ierr);
1293454631fSDave May   }
130dcf43ee8SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmSharedField_%s",swarm->vec_field_name);
131dcf43ee8SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
132b5bcf523SDave May 
133b5bcf523SDave May   /* Set guard */
134dcf43ee8SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarm_VecFieldInPlace_%s",fieldname);
135dcf43ee8SDave May   ierr = PetscObjectComposeFunction((PetscObject)x,name,DMSwarmDestroyGlobalVectorFromField);CHKERRQ(ierr);
136b5bcf523SDave May 
137b5bcf523SDave May   *vec = x;
138b5bcf523SDave May   PetscFunctionReturn(0);
139b5bcf523SDave May }
140b5bcf523SDave May 
141b5bcf523SDave May #undef __FUNCT__
142b5bcf523SDave May #define __FUNCT__ "DMSwarmDestroyGlobalVectorFromField"
143b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
144b5bcf523SDave May {
145b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
146b5bcf523SDave May   PetscErrorCode ierr;
147b5bcf523SDave May   DataField gfield;
148b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
149b5bcf523SDave May   void (*fptr)(void);
150b5bcf523SDave May 
151b5bcf523SDave May   /* get data field */
1522eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
153b5bcf523SDave May 
154b5bcf523SDave May   /* check vector is an inplace array */
155b5bcf523SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarm_VecFieldInPlace_%s",fieldname);
156b5bcf523SDave May   ierr = PetscObjectQueryFunction((PetscObject)(*vec),name,&fptr);CHKERRQ(ierr);
157b5bcf523SDave May   if (!fptr) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Vector being destroyed was not created from DMSwarm field(%s)",fieldname);
158b5bcf523SDave May 
159b5bcf523SDave May   /* restore data field */
1606845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
161b5bcf523SDave May 
162b5bcf523SDave May   ierr = VecDestroy(vec);CHKERRQ(ierr);
163b5bcf523SDave May 
164b5bcf523SDave May   PetscFunctionReturn(0);
165b5bcf523SDave May }
166b5bcf523SDave May 
167b5bcf523SDave May /*
168b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec)
169b5bcf523SDave May {
170b5bcf523SDave May   PetscFunctionReturn(0);
171b5bcf523SDave May }
172b5bcf523SDave May 
173b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec)
174b5bcf523SDave May {
175b5bcf523SDave May   PetscFunctionReturn(0);
176b5bcf523SDave May }
177b5bcf523SDave May */
178b5bcf523SDave May 
179b5bcf523SDave May #undef __FUNCT__
1805f50eb2eSDave May #define __FUNCT__ "DMSwarmInitializeFieldRegister"
1815f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm)
1825f50eb2eSDave May {
1835f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1843454631fSDave May   PetscErrorCode ierr;
1853454631fSDave May 
1865f50eb2eSDave May   swarm->field_registration_initialized = PETSC_TRUE;
1873454631fSDave May 
1883454631fSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,"DMSwarm_pid",1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */
1893454631fSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,"DMSwarm_rank",1,PETSC_INT);CHKERRQ(ierr); /* used for communication */
1903454631fSDave May 
1915f50eb2eSDave May   PetscFunctionReturn(0);
1925f50eb2eSDave May }
1935f50eb2eSDave May 
1945f50eb2eSDave May #undef __FUNCT__
1955f50eb2eSDave May #define __FUNCT__ "DMSwarmFinalizeFieldRegister"
1965f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm)
1975f50eb2eSDave May {
1985f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1996845f8f5SDave May   PetscErrorCode ierr;
2006845f8f5SDave May 
2015f50eb2eSDave May   swarm->field_registration_finalized = PETSC_TRUE;
2026845f8f5SDave May   ierr = DataBucketFinalize(swarm->db);CHKERRQ(ierr);
2035f50eb2eSDave May   PetscFunctionReturn(0);
2045f50eb2eSDave May }
2055f50eb2eSDave May 
2065f50eb2eSDave May #undef __FUNCT__
2075f50eb2eSDave May #define __FUNCT__ "DMSwarmSetLocalSizes"
2085f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer)
2095f50eb2eSDave May {
2105f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
2116845f8f5SDave May   PetscErrorCode ierr;
2125f50eb2eSDave May 
2136845f8f5SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr);
2145f50eb2eSDave May 
2155f50eb2eSDave May   PetscFunctionReturn(0);
2165f50eb2eSDave May }
2175f50eb2eSDave May 
2185f50eb2eSDave May #undef __FUNCT__
219b16650c8SDave May #define __FUNCT__ "DMSwarmSetCellDM"
220b16650c8SDave May PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell)
221b16650c8SDave May {
222b16650c8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
223b16650c8SDave May   swarm->dmcell = dmcell;
224b16650c8SDave May   PetscFunctionReturn(0);
225b16650c8SDave May }
226b16650c8SDave May 
227b16650c8SDave May #undef __FUNCT__
228fe39f135SDave May #define __FUNCT__ "DMSwarmGetCellDM"
229fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell)
230fe39f135SDave May {
231fe39f135SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
232fe39f135SDave May   *dmcell = swarm->dmcell;
233fe39f135SDave May   PetscFunctionReturn(0);
234fe39f135SDave May }
235fe39f135SDave May 
236fe39f135SDave May #undef __FUNCT__
237dcf43ee8SDave May #define __FUNCT__ "DMSwarmGetLocalSize"
238dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal)
239dcf43ee8SDave May {
240dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
241dcf43ee8SDave May   PetscErrorCode ierr;
242dcf43ee8SDave May 
243dcf43ee8SDave May   if (nlocal) {
244dcf43ee8SDave May     ierr = DataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);
245dcf43ee8SDave May   }
246dcf43ee8SDave May 
247dcf43ee8SDave May   PetscFunctionReturn(0);
248dcf43ee8SDave May }
249dcf43ee8SDave May 
250dcf43ee8SDave May #undef __FUNCT__
251dcf43ee8SDave May #define __FUNCT__ "DMSwarmGetSize"
252dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n)
253dcf43ee8SDave May {
254dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
255dcf43ee8SDave May   PetscErrorCode ierr;
256dcf43ee8SDave May   PetscInt nlocal,ng;
257dcf43ee8SDave May 
258dcf43ee8SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
259dcf43ee8SDave May   ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
260dcf43ee8SDave May   if (n) { *n = ng; }
261dcf43ee8SDave May   PetscFunctionReturn(0);
262dcf43ee8SDave May }
263dcf43ee8SDave May 
264dcf43ee8SDave May #undef __FUNCT__
265b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterPetscDatatypeField"
2665f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
267b62e03f8SDave May {
2682eac95f8SDave May   PetscErrorCode ierr;
269b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
270b62e03f8SDave May   size_t size;
271b62e03f8SDave May 
2725f50eb2eSDave May   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
2735f50eb2eSDave May   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
2745f50eb2eSDave May 
2755f50eb2eSDave May   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
2765f50eb2eSDave May   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
2775f50eb2eSDave May   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
2785f50eb2eSDave May   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
2795f50eb2eSDave May   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
280b62e03f8SDave May 
281b62e03f8SDave May   switch (type) {
282b62e03f8SDave May     case PETSC_CHAR:
283b62e03f8SDave May       size = sizeof(PetscChar);
284b62e03f8SDave May       break;
285b62e03f8SDave May     case PETSC_SHORT:
286b62e03f8SDave May       size = sizeof(PetscShort);
287b62e03f8SDave May       break;
288b62e03f8SDave May     case PETSC_INT:
289b62e03f8SDave May       size = sizeof(PetscInt);
290b62e03f8SDave May       break;
291b62e03f8SDave May     case PETSC_LONG:
292b62e03f8SDave May       size = sizeof(Petsc64bitInt);
293b62e03f8SDave May       break;
294b62e03f8SDave May     case PETSC_FLOAT:
295b62e03f8SDave May       size = sizeof(PetscFloat);
296b62e03f8SDave May       break;
297b62e03f8SDave May     case PETSC_DOUBLE:
298b62e03f8SDave May       size = sizeof(PetscReal);
299b62e03f8SDave May       break;
300b62e03f8SDave May 
301b62e03f8SDave May     default:
3025f50eb2eSDave May       SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
303b62e03f8SDave May       break;
304b62e03f8SDave May   }
305b62e03f8SDave May 
306b62e03f8SDave May   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
3072eac95f8SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,size,NULL);CHKERRQ(ierr);
308b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
309b62e03f8SDave May 
310b62e03f8SDave May   PetscFunctionReturn(0);
311b62e03f8SDave May }
312b62e03f8SDave May 
313b62e03f8SDave May #undef __FUNCT__
314b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterUserStructField"
3155f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
316b62e03f8SDave May {
3172eac95f8SDave May   PetscErrorCode ierr;
318b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
319b62e03f8SDave May 
3202eac95f8SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
321b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
322b62e03f8SDave May 
323b62e03f8SDave May   PetscFunctionReturn(0);
324b62e03f8SDave May }
325b62e03f8SDave May 
326b62e03f8SDave May #undef __FUNCT__
327b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterUserDatatypeField"
3285f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size)
329b62e03f8SDave May {
330b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
3316845f8f5SDave May   PetscErrorCode ierr;
332b62e03f8SDave May 
3336845f8f5SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,size,NULL);CHKERRQ(ierr);
334b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
335b62e03f8SDave May 
336b62e03f8SDave May   PetscFunctionReturn(0);
337b62e03f8SDave May }
338b62e03f8SDave May 
339b62e03f8SDave May #undef __FUNCT__
340b62e03f8SDave May #define __FUNCT__ "DMSwarmGetField"
3415f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
342b62e03f8SDave May {
343b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
344b62e03f8SDave May   DataField gfield;
3452eac95f8SDave May   PetscErrorCode ierr;
346b62e03f8SDave May 
3473454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
3483454631fSDave May 
3492eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
3506845f8f5SDave May   ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr);
3516845f8f5SDave May   ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr);
352b5bcf523SDave May   if (blocksize) {}
353b5bcf523SDave May   if (type) { *type = gfield->petsc_type; }
354b62e03f8SDave May 
355b62e03f8SDave May   PetscFunctionReturn(0);
356b62e03f8SDave May }
357b62e03f8SDave May 
358b62e03f8SDave May #undef __FUNCT__
359b62e03f8SDave May #define __FUNCT__ "DMSwarmRestoreField"
3605f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
361b62e03f8SDave May {
362b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
363b62e03f8SDave May   DataField gfield;
3642eac95f8SDave May   PetscErrorCode ierr;
365b62e03f8SDave May 
3662eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
3676845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
368b62e03f8SDave May   if (data) *data = NULL;
369b62e03f8SDave May 
370b62e03f8SDave May   PetscFunctionReturn(0);
371b62e03f8SDave May }
372b62e03f8SDave May 
373cb1d1399SDave May #undef __FUNCT__
374cb1d1399SDave May #define __FUNCT__ "DMSwarmAddPoint"
375cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
376cb1d1399SDave May {
377cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
378cb1d1399SDave May   PetscErrorCode ierr;
379cb1d1399SDave May 
3803454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
381cb1d1399SDave May   ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr);
382cb1d1399SDave May   PetscFunctionReturn(0);
383cb1d1399SDave May }
384cb1d1399SDave May 
385cb1d1399SDave May #undef __FUNCT__
386cb1d1399SDave May #define __FUNCT__ "DMSwarmAddNPoints"
387cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
388cb1d1399SDave May {
389cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
390cb1d1399SDave May   PetscErrorCode ierr;
391cb1d1399SDave May   PetscInt nlocal;
392cb1d1399SDave May 
393cb1d1399SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
394cb1d1399SDave May   nlocal = nlocal + npoints;
395cb1d1399SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,-1);CHKERRQ(ierr);
396cb1d1399SDave May   PetscFunctionReturn(0);
397cb1d1399SDave May }
398cb1d1399SDave May 
399cb1d1399SDave May #undef __FUNCT__
400cb1d1399SDave May #define __FUNCT__ "DMSwarmRemovePoint"
401cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
402cb1d1399SDave May {
403cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
404cb1d1399SDave May   PetscErrorCode ierr;
405cb1d1399SDave May 
406cb1d1399SDave May   ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
407cb1d1399SDave May   PetscFunctionReturn(0);
408cb1d1399SDave May }
409cb1d1399SDave May 
410cb1d1399SDave May #undef __FUNCT__
411cb1d1399SDave May #define __FUNCT__ "DMSwarmRemovePointAtIndex"
412cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
413cb1d1399SDave May {
414cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
415cb1d1399SDave May   PetscErrorCode ierr;
416cb1d1399SDave May 
417cb1d1399SDave May   ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
418cb1d1399SDave May   PetscFunctionReturn(0);
419cb1d1399SDave May }
420b62e03f8SDave May 
4213454631fSDave May #undef __FUNCT__
422095059a4SDave May #define __FUNCT__ "DMSwarmMigrate_Basic"
423095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points)
4243454631fSDave May {
425dcf43ee8SDave May   PetscErrorCode ierr;
426dcf43ee8SDave May   ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr);
4273454631fSDave May   PetscFunctionReturn(0);
4283454631fSDave May }
4293454631fSDave May 
4303454631fSDave May #undef __FUNCT__
431095059a4SDave May #define __FUNCT__ "DMSwarmMigrate"
432095059a4SDave May PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points)
4333454631fSDave May {
4343454631fSDave May   PetscErrorCode ierr;
435095059a4SDave May   ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr);
4363454631fSDave May   PetscFunctionReturn(0);
4373454631fSDave May }
4383454631fSDave May 
4392712d1f2SDave May #undef __FUNCT__
440fe39f135SDave May #define __FUNCT__ "DMSwarmCollectViewCreate"
441fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm)
4422712d1f2SDave May {
4432712d1f2SDave May   PetscErrorCode ierr;
4442712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
4452712d1f2SDave May   PetscInt ng;
4462712d1f2SDave May 
447*480eef7bSDave May   if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active");
448*480eef7bSDave May 
449*480eef7bSDave May   ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr);
450*480eef7bSDave May   switch (swarm->collect_type) {
451*480eef7bSDave May     case DMSWARM_COLLECT_BASIC:
4522712d1f2SDave May       ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr);
453*480eef7bSDave May       break;
454*480eef7bSDave May     case DMSWARM_COLLECT_DMDABOUNDINGBOX:
455fe39f135SDave May       //ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr);
456*480eef7bSDave May       break;
457*480eef7bSDave May     case DMSWARM_COLLECT_GENERAL:
458fe39f135SDave May       //ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr);
459*480eef7bSDave May       break;
460*480eef7bSDave May 
461*480eef7bSDave May     default:
462*480eef7bSDave May       break;
463*480eef7bSDave May   }
464*480eef7bSDave May 
465*480eef7bSDave May   swarm->collect_view_active = PETSC_TRUE;
466*480eef7bSDave May   swarm->collect_view_reset_nlocal = ng;
4672712d1f2SDave May 
4682712d1f2SDave May   PetscFunctionReturn(0);
4692712d1f2SDave May }
4702712d1f2SDave May 
4712712d1f2SDave May #undef __FUNCT__
472fe39f135SDave May #define __FUNCT__ "DMSwarmCollectViewDestroy"
473fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm)
4742712d1f2SDave May {
4752712d1f2SDave May   PetscErrorCode ierr;
4762712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
4772712d1f2SDave May 
478*480eef7bSDave May   if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active");
479*480eef7bSDave May   ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr);
480*480eef7bSDave May   swarm->collect_view_active = PETSC_FALSE;
4812712d1f2SDave May 
4822712d1f2SDave May   PetscFunctionReturn(0);
4832712d1f2SDave May }
4843454631fSDave May 
4853454631fSDave May #undef __FUNCT__
4863454631fSDave May #define __FUNCT__ "DMSetup_Swarm"
4873454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm)
4883454631fSDave May {
4893454631fSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
4903454631fSDave May   PetscErrorCode ierr;
4913454631fSDave May   PetscMPIInt rank;
4923454631fSDave May   PetscInt p,npoints,*rankval;
4933454631fSDave May 
4943454631fSDave May   if (swarm->issetup) PetscFunctionReturn(0);
4953454631fSDave May 
4963454631fSDave May   swarm->issetup = PETSC_TRUE;
4973454631fSDave May 
4983454631fSDave May   /* check some fields were registered */
4993454631fSDave May   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
5003454631fSDave May 
5013454631fSDave May   /* check local sizes were set */
5023454631fSDave May   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
5033454631fSDave May 
5043454631fSDave May   /* initialize values in pid and rank placeholders */
5053454631fSDave May   /* TODO: [pid - use MPI_Scan] */
5063454631fSDave May 
5073454631fSDave May   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
5083454631fSDave May   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
5093454631fSDave May   ierr = DMSwarmGetField(dm,"DMSwarm_rank",NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
5103454631fSDave May   for (p=0; p<npoints; p++) {
5113454631fSDave May     rankval[p] = (PetscInt)rank;
5123454631fSDave May   }
5133454631fSDave May   ierr = DMSwarmRestoreField(dm,"DMSwarm_rank",NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
5143454631fSDave May 
5153454631fSDave May   PetscFunctionReturn(0);
5163454631fSDave May }
5173454631fSDave May 
518b62e03f8SDave May #undef __FUNCT__
51957795646SDave May #define __FUNCT__ "DMDestroy_Swarm"
52057795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm)
52157795646SDave May {
52257795646SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
52357795646SDave May   PetscErrorCode ierr;
52457795646SDave May 
52557795646SDave May   PetscFunctionBegin;
5266845f8f5SDave May   ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr);
52757795646SDave May   ierr = PetscFree(swarm);CHKERRQ(ierr);
52857795646SDave May   PetscFunctionReturn(0);
52957795646SDave May }
53057795646SDave May 
53157795646SDave May #undef __FUNCT__
5325f50eb2eSDave May #define __FUNCT__ "DMView_Swarm"
5335f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
5345f50eb2eSDave May {
5355f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
5365f50eb2eSDave May   PetscBool      iascii,ibinary,ishdf5,isvtk;
5375f50eb2eSDave May   PetscErrorCode ierr;
5385f50eb2eSDave May 
5395f50eb2eSDave May   PetscFunctionBegin;
5405f50eb2eSDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5415f50eb2eSDave May   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
5425f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
5435f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
5445f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
5455f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
5465f50eb2eSDave May   if (iascii) {
5476845f8f5SDave May     ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
5485f50eb2eSDave May   } else if (ibinary) {
5495f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
5505f50eb2eSDave May   } else if (ishdf5) {
5515f50eb2eSDave May #if defined(PETSC_HAVE_HDF5)
5525f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
5535f50eb2eSDave May #else
5545f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
5555f50eb2eSDave May #endif
5565f50eb2eSDave May   } else if (isvtk) {
5575f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
5585f50eb2eSDave May   }
5595f50eb2eSDave May   PetscFunctionReturn(0);
5605f50eb2eSDave May }
5615f50eb2eSDave May 
5625f50eb2eSDave May #undef __FUNCT__
56357795646SDave May #define __FUNCT__ "DMCreate_Swarm"
56457795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
56557795646SDave May {
56657795646SDave May   DM_Swarm      *swarm;
56757795646SDave May   PetscErrorCode ierr;
56857795646SDave May 
56957795646SDave May   PetscFunctionBegin;
57057795646SDave May   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
57157795646SDave May   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
57257795646SDave May 
5736845f8f5SDave May   ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr);
574b5bcf523SDave May   swarm->vec_field_set = PETSC_FALSE;
5753454631fSDave May   swarm->issetup = PETSC_FALSE;
576*480eef7bSDave May   swarm->swarm_type = DMSWARM_BASIC;
577*480eef7bSDave May   swarm->migrate_type = DMSWARM_MIGRATE_BASIC;
578*480eef7bSDave May   swarm->collect_type = DMSWARM_COLLECT_BASIC;
579b62e03f8SDave May 
58057795646SDave May   dm->dim  = 0;
58157795646SDave May   dm->data = swarm;
58257795646SDave May 
5835f50eb2eSDave May   dm->ops->view                            = DMView_Swarm;
58457795646SDave May   dm->ops->load                            = NULL;
58557795646SDave May   dm->ops->setfromoptions                  = NULL;
58657795646SDave May   dm->ops->clone                           = NULL;
5873454631fSDave May   dm->ops->setup                           = DMSetup_Swarm;
58857795646SDave May   dm->ops->createdefaultsection            = NULL;
58957795646SDave May   dm->ops->createdefaultconstraints        = NULL;
590b5bcf523SDave May   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
591b5bcf523SDave May   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
59257795646SDave May   dm->ops->getlocaltoglobalmapping         = NULL;
59357795646SDave May   dm->ops->createfieldis                   = NULL;
59457795646SDave May   dm->ops->createcoordinatedm              = NULL;
59557795646SDave May   dm->ops->getcoloring                     = NULL;
59657795646SDave May   dm->ops->creatematrix                    = NULL;
59757795646SDave May   dm->ops->createinterpolation             = NULL;
59857795646SDave May   dm->ops->getaggregates                   = NULL;
59957795646SDave May   dm->ops->getinjection                    = NULL;
60057795646SDave May   dm->ops->refine                          = NULL;
60157795646SDave May   dm->ops->coarsen                         = NULL;
60257795646SDave May   dm->ops->refinehierarchy                 = NULL;
60357795646SDave May   dm->ops->coarsenhierarchy                = NULL;
60457795646SDave May   dm->ops->globaltolocalbegin              = NULL;
60557795646SDave May   dm->ops->globaltolocalend                = NULL;
60657795646SDave May   dm->ops->localtoglobalbegin              = NULL;
60757795646SDave May   dm->ops->localtoglobalend                = NULL;
60857795646SDave May   dm->ops->destroy                         = DMDestroy_Swarm;
60957795646SDave May   dm->ops->createsubdm                     = NULL;
61057795646SDave May   dm->ops->getdimpoints                    = NULL;
61157795646SDave May   dm->ops->locatepoints                    = NULL;
61257795646SDave May 
61357795646SDave May   PetscFunctionReturn(0);
61457795646SDave May }