xref: /petsc/src/dm/impls/swarm/swarm.c (revision 3454631f4aaa15891cb2714934d2ee90b7996f8c)
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 
657795646SDave May //typedef PetscErrorCode (*swarm_project)(DM,DM,Vec) DMSwarmProjectMethod; /* swarm, geometry, result */
757795646SDave May 
857795646SDave May //typedef enum { PROJECT_DMDA_AQ1=0, PROJECT_DMDA_P0 } DMSwarmDMDAProjectionType;
957795646SDave May 
1057795646SDave May #if 0
1157795646SDave May 
1257795646SDave May /* Defines what the local space will be */
13b62e03f8SDave May PetscErrorCode DMSwarmSetOverlap(void)
1457795646SDave May {
1557795646SDave May 
16b62e03f8SDave May   PetscFunctionReturn(0);
1757795646SDave May }
1857795646SDave May 
1957795646SDave May 
2057795646SDave May /* coordinates */
2157795646SDave May /*
2257795646SDave May DMGetCoordinateDM returns self
2357795646SDave May DMGetCoordinates and DMGetCoordinatesLocal return same thing
2457795646SDave May Local view could be used to define overlapping information
2557795646SDave May */
2657795646SDave May 
2757795646SDave May #endif
2857795646SDave May 
2957795646SDave May #undef __FUNCT__
30b5bcf523SDave May #define __FUNCT__ "DMSwarmVectorDefineField"
31b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmVectorDefineField(DM dm,const char fieldname[])
32b5bcf523SDave May {
33b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
34b5bcf523SDave May   PetscErrorCode ierr;
35b5bcf523SDave May   PetscInt bs,n;
36b5bcf523SDave May   PetscScalar *array;
37b5bcf523SDave May   PetscDataType type;
38b5bcf523SDave May 
39*3454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
406845f8f5SDave May   ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr);
41b5bcf523SDave May   ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
42b5bcf523SDave May 
43b5bcf523SDave May   /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */
44b5bcf523SDave May   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL");
45b5bcf523SDave May 
46b5bcf523SDave May   PetscSNPrintf(swarm->vec_field_name,PETSC_MAX_PATH_LEN-1,"%s",fieldname);
47b5bcf523SDave May   swarm->vec_field_set = PETSC_TRUE;
48b5bcf523SDave May   swarm->vec_field_bs = 1;//bs;
49b5bcf523SDave May   swarm->vec_field_nlocal = n;
50b5bcf523SDave May 
51b5bcf523SDave May   PetscFunctionReturn(0);
52b5bcf523SDave May }
53b5bcf523SDave May 
54b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */
55b5bcf523SDave May #undef __FUNCT__
56b5bcf523SDave May #define __FUNCT__ "DMCreateGlobalVector_Swarm"
57b5bcf523SDave May PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec)
58b5bcf523SDave May {
59b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
60b5bcf523SDave May   PetscErrorCode ierr;
61b5bcf523SDave May   Vec x;
62b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
63b5bcf523SDave May 
64*3454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
65b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
66b5bcf523SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);
67b5bcf523SDave May   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr);
68b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
69b5bcf523SDave May   ierr = VecSetSizes(x,swarm->vec_field_nlocal,PETSC_DETERMINE);CHKERRQ(ierr);
70b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
71b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
72b5bcf523SDave May   *vec = x;
73b5bcf523SDave May 
74b5bcf523SDave May   PetscFunctionReturn(0);
75b5bcf523SDave May }
76b5bcf523SDave May 
77b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */
78b5bcf523SDave May #undef __FUNCT__
79b5bcf523SDave May #define __FUNCT__ "DMCreateLocalVector_Swarm"
80b5bcf523SDave May PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec)
81b5bcf523SDave May {
82b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
83b5bcf523SDave May   PetscErrorCode ierr;
84b5bcf523SDave May   Vec x;
85b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
86b5bcf523SDave May 
87*3454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
88b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
89b5bcf523SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);
90b5bcf523SDave May   ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr);
91b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
92b5bcf523SDave May   ierr = VecSetSizes(x,swarm->vec_field_nlocal,swarm->vec_field_nlocal);CHKERRQ(ierr);
93b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
94b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
95b5bcf523SDave May   *vec = x;
96b5bcf523SDave May 
97b5bcf523SDave May   PetscFunctionReturn(0);
98b5bcf523SDave May }
99b5bcf523SDave May 
100b5bcf523SDave May #undef __FUNCT__
101b5bcf523SDave May #define __FUNCT__ "DMSwarmCreateGlobalVectorFromField"
102b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
103b5bcf523SDave May {
104b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
105b5bcf523SDave May   PetscErrorCode ierr;
106b5bcf523SDave May   PetscInt bs,n;
107b5bcf523SDave May   PetscScalar *array;
108b5bcf523SDave May   Vec x;
109b5bcf523SDave May   PetscDataType type;
110b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
111*3454631fSDave May   PetscMPIInt commsize;
112b5bcf523SDave May 
113*3454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
1146845f8f5SDave May   ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr);
115b5bcf523SDave May   ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr);
116b5bcf523SDave May 
117b5bcf523SDave May   /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */
118b5bcf523SDave May   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL");
119b5bcf523SDave May 
120*3454631fSDave May   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&commsize);CHKERRQ(ierr);
121*3454631fSDave May   if (commsize == 1) {
122b5bcf523SDave May     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)dm),1,n,array,&x);CHKERRQ(ierr);
123*3454631fSDave May   } else {
124*3454631fSDave May     ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)dm),1,n,PETSC_DETERMINE,array,&x);CHKERRQ(ierr);
125*3454631fSDave May   }
126b5bcf523SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarm_VecFieldInPlace_%s",fieldname);
127b5bcf523SDave May   ierr = PetscObjectComposeFunction((PetscObject)x,name,DMSwarmDestroyGlobalVectorFromField);CHKERRQ(ierr);
128b5bcf523SDave May 
129b5bcf523SDave May   /* Set guard */
130b5bcf523SDave May 
131b5bcf523SDave May   *vec = x;
132b5bcf523SDave May   PetscFunctionReturn(0);
133b5bcf523SDave May }
134b5bcf523SDave May 
135b5bcf523SDave May #undef __FUNCT__
136b5bcf523SDave May #define __FUNCT__ "DMSwarmDestroyGlobalVectorFromField"
137b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
138b5bcf523SDave May {
139b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
140b5bcf523SDave May   PetscErrorCode ierr;
141b5bcf523SDave May   DataField gfield;
142b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
143b5bcf523SDave May   void (*fptr)(void);
144b5bcf523SDave May 
145b5bcf523SDave May   /* get data field */
1462eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
147b5bcf523SDave May 
148b5bcf523SDave May   /* check vector is an inplace array */
149b5bcf523SDave May   PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarm_VecFieldInPlace_%s",fieldname);
150b5bcf523SDave May   ierr = PetscObjectQueryFunction((PetscObject)(*vec),name,&fptr);CHKERRQ(ierr);
151b5bcf523SDave May   if (!fptr) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Vector being destroyed was not created from DMSwarm field(%s)",fieldname);
152b5bcf523SDave May 
153b5bcf523SDave May   /* restore data field */
1546845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
155b5bcf523SDave May 
156b5bcf523SDave May   ierr = VecDestroy(vec);CHKERRQ(ierr);
157b5bcf523SDave May 
158b5bcf523SDave May   PetscFunctionReturn(0);
159b5bcf523SDave May }
160b5bcf523SDave May 
161b5bcf523SDave May /*
162b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec)
163b5bcf523SDave May {
164b5bcf523SDave May   PetscFunctionReturn(0);
165b5bcf523SDave May }
166b5bcf523SDave May 
167b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec)
168b5bcf523SDave May {
169b5bcf523SDave May   PetscFunctionReturn(0);
170b5bcf523SDave May }
171b5bcf523SDave May */
172b5bcf523SDave May 
173b5bcf523SDave May #undef __FUNCT__
1745f50eb2eSDave May #define __FUNCT__ "DMSwarmInitializeFieldRegister"
1755f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm)
1765f50eb2eSDave May {
1775f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
178*3454631fSDave May   PetscErrorCode ierr;
179*3454631fSDave May 
1805f50eb2eSDave May   swarm->field_registration_initialized = PETSC_TRUE;
181*3454631fSDave May 
182*3454631fSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,"DMSwarm_pid",1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */
183*3454631fSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,"DMSwarm_rank",1,PETSC_INT);CHKERRQ(ierr); /* used for communication */
184*3454631fSDave May 
1855f50eb2eSDave May   PetscFunctionReturn(0);
1865f50eb2eSDave May }
1875f50eb2eSDave May 
1885f50eb2eSDave May #undef __FUNCT__
1895f50eb2eSDave May #define __FUNCT__ "DMSwarmFinalizeFieldRegister"
1905f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm)
1915f50eb2eSDave May {
1925f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
1936845f8f5SDave May   PetscErrorCode ierr;
1946845f8f5SDave May 
1955f50eb2eSDave May   swarm->field_registration_finalized = PETSC_TRUE;
1966845f8f5SDave May   ierr = DataBucketFinalize(swarm->db);CHKERRQ(ierr);
1975f50eb2eSDave May   PetscFunctionReturn(0);
1985f50eb2eSDave May }
1995f50eb2eSDave May 
2005f50eb2eSDave May #undef __FUNCT__
2015f50eb2eSDave May #define __FUNCT__ "DMSwarmSetLocalSizes"
2025f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer)
2035f50eb2eSDave May {
2045f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
2056845f8f5SDave May   PetscErrorCode ierr;
2065f50eb2eSDave May 
2076845f8f5SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr);
2085f50eb2eSDave May 
2095f50eb2eSDave May   PetscFunctionReturn(0);
2105f50eb2eSDave May }
2115f50eb2eSDave May 
2125f50eb2eSDave May #undef __FUNCT__
213b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterPetscDatatypeField"
2145f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
215b62e03f8SDave May {
2162eac95f8SDave May   PetscErrorCode ierr;
217b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
218b62e03f8SDave May   size_t size;
219b62e03f8SDave May 
2205f50eb2eSDave May   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
2215f50eb2eSDave May   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
2225f50eb2eSDave May 
2235f50eb2eSDave May   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
2245f50eb2eSDave May   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
2255f50eb2eSDave May   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
2265f50eb2eSDave May   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
2275f50eb2eSDave May   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
228b62e03f8SDave May 
229b62e03f8SDave May   switch (type) {
230b62e03f8SDave May     case PETSC_CHAR:
231b62e03f8SDave May       size = sizeof(PetscChar);
232b62e03f8SDave May       break;
233b62e03f8SDave May     case PETSC_SHORT:
234b62e03f8SDave May       size = sizeof(PetscShort);
235b62e03f8SDave May       break;
236b62e03f8SDave May     case PETSC_INT:
237b62e03f8SDave May       size = sizeof(PetscInt);
238b62e03f8SDave May       break;
239b62e03f8SDave May     case PETSC_LONG:
240b62e03f8SDave May       size = sizeof(Petsc64bitInt);
241b62e03f8SDave May       break;
242b62e03f8SDave May     case PETSC_FLOAT:
243b62e03f8SDave May       size = sizeof(PetscFloat);
244b62e03f8SDave May       break;
245b62e03f8SDave May     case PETSC_DOUBLE:
246b62e03f8SDave May       size = sizeof(PetscReal);
247b62e03f8SDave May       break;
248b62e03f8SDave May 
249b62e03f8SDave May     default:
2505f50eb2eSDave May       SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
251b62e03f8SDave May       break;
252b62e03f8SDave May   }
253b62e03f8SDave May 
254b62e03f8SDave May   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
2552eac95f8SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,size,NULL);CHKERRQ(ierr);
256b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
257b62e03f8SDave May 
258b62e03f8SDave May   PetscFunctionReturn(0);
259b62e03f8SDave May }
260b62e03f8SDave May 
261b62e03f8SDave May #undef __FUNCT__
262b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterUserStructField"
2635f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
264b62e03f8SDave May {
2652eac95f8SDave May   PetscErrorCode ierr;
266b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
267b62e03f8SDave May 
2682eac95f8SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
269b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
270b62e03f8SDave May 
271b62e03f8SDave May   PetscFunctionReturn(0);
272b62e03f8SDave May }
273b62e03f8SDave May 
274b62e03f8SDave May #undef __FUNCT__
275b62e03f8SDave May #define __FUNCT__ "DMSwarmRegisterUserDatatypeField"
2765f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size)
277b62e03f8SDave May {
278b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
2796845f8f5SDave May   PetscErrorCode ierr;
280b62e03f8SDave May 
2816845f8f5SDave May 	ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,size,NULL);CHKERRQ(ierr);
282b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
283b62e03f8SDave May 
284b62e03f8SDave May   PetscFunctionReturn(0);
285b62e03f8SDave May }
286b62e03f8SDave May 
287b62e03f8SDave May #undef __FUNCT__
288b62e03f8SDave May #define __FUNCT__ "DMSwarmGetField"
2895f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
290b62e03f8SDave May {
291b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
292b62e03f8SDave May   DataField gfield;
2932eac95f8SDave May   PetscErrorCode ierr;
294b62e03f8SDave May 
295*3454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
296*3454631fSDave May 
2972eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
2986845f8f5SDave May   ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr);
2996845f8f5SDave May   ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr);
300b5bcf523SDave May   if (blocksize) {}
301b5bcf523SDave May   if (type) { *type = gfield->petsc_type; }
302b62e03f8SDave May 
303b62e03f8SDave May   PetscFunctionReturn(0);
304b62e03f8SDave May }
305b62e03f8SDave May 
306b62e03f8SDave May #undef __FUNCT__
307b62e03f8SDave May #define __FUNCT__ "DMSwarmRestoreField"
3085f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
309b62e03f8SDave May {
310b62e03f8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
311b62e03f8SDave May   DataField gfield;
3122eac95f8SDave May   PetscErrorCode ierr;
313b62e03f8SDave May 
3142eac95f8SDave May   ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
3156845f8f5SDave May   ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr);
316b62e03f8SDave May   if (data) *data = NULL;
317b62e03f8SDave May 
318b62e03f8SDave May   PetscFunctionReturn(0);
319b62e03f8SDave May }
320b62e03f8SDave May 
321cb1d1399SDave May #undef __FUNCT__
322cb1d1399SDave May #define __FUNCT__ "DMSwarmAddPoint"
323cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
324cb1d1399SDave May {
325cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
326cb1d1399SDave May   PetscErrorCode ierr;
327cb1d1399SDave May 
328*3454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
329cb1d1399SDave May   ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr);
330cb1d1399SDave May   PetscFunctionReturn(0);
331cb1d1399SDave May }
332cb1d1399SDave May 
333cb1d1399SDave May #undef __FUNCT__
334cb1d1399SDave May #define __FUNCT__ "DMSwarmAddNPoints"
335cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
336cb1d1399SDave May {
337cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
338cb1d1399SDave May   PetscErrorCode ierr;
339cb1d1399SDave May   PetscInt nlocal;
340cb1d1399SDave May 
341cb1d1399SDave May   ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
342cb1d1399SDave May   nlocal = nlocal + npoints;
343cb1d1399SDave May   ierr = DataBucketSetSizes(swarm->db,nlocal,-1);CHKERRQ(ierr);
344cb1d1399SDave May   PetscFunctionReturn(0);
345cb1d1399SDave May }
346cb1d1399SDave May 
347cb1d1399SDave May #undef __FUNCT__
348cb1d1399SDave May #define __FUNCT__ "DMSwarmRemovePoint"
349cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
350cb1d1399SDave May {
351cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
352cb1d1399SDave May   PetscErrorCode ierr;
353cb1d1399SDave May 
354cb1d1399SDave May   ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
355cb1d1399SDave May   PetscFunctionReturn(0);
356cb1d1399SDave May }
357cb1d1399SDave May 
358cb1d1399SDave May #undef __FUNCT__
359cb1d1399SDave May #define __FUNCT__ "DMSwarmRemovePointAtIndex"
360cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
361cb1d1399SDave May {
362cb1d1399SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
363cb1d1399SDave May   PetscErrorCode ierr;
364cb1d1399SDave May 
365cb1d1399SDave May   ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
366cb1d1399SDave May   PetscFunctionReturn(0);
367cb1d1399SDave May }
368b62e03f8SDave May 
369*3454631fSDave May /*
370*3454631fSDave May  (i) examines DMSwarm field named DMSwarm_rank
371*3454631fSDave May  (ii) all entries label with field_rank[] != rank are pushed to processor rank
372*3454631fSDave May  (iii) points sent can be optionaly removd from local list
373*3454631fSDave May */
374*3454631fSDave May #undef __FUNCT__
375*3454631fSDave May #define __FUNCT__ "DMSwarmPush_Basic"
376*3454631fSDave May PetscErrorCode DMSwarmPush_Basic(DM dm,PetscBool remove_sent_points)
377*3454631fSDave May {
378*3454631fSDave May #if 0
379*3454631fSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
380*3454631fSDave May   PetscErrorCode ierr;
381*3454631fSDave May   MPI_Comm comm;
382*3454631fSDave May   PetscMPIInt *toranks,nfrom,*fromranks,rank;
383*3454631fSDave May   PetscInt p,k,pk,npoints,*rankval,nto,sendcount;
384*3454631fSDave May   char *todata,*fromdata;
385*3454631fSDave May   void *singlebuffer;
386*3454631fSDave May   size_t sizeof_dmswarm_point;
387*3454631fSDave May 
388*3454631fSDave May   comm = PetscObjectComm((PetscObject)dm);
389*3454631fSDave May   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
390*3454631fSDave May 
391*3454631fSDave May   ierr = DataBucketCreatePackedArray(swarm->db,&sizeof_dmswarm_point,&singlebuffer);CHKERRQ(ierr);
392*3454631fSDave May 
393*3454631fSDave May   /* two pass */
394*3454631fSDave May   /* a) count total amount of points to send : count */
395*3454631fSDave May 
396*3454631fSDave May   PetscMalloc1(50,&toranks);
397*3454631fSDave May   for (k=0; k<50; k++) { toranks[k] = -1; }
398*3454631fSDave May 
399*3454631fSDave May   nto = 0;
400*3454631fSDave May   sendcount  = 0;
401*3454631fSDave May   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
402*3454631fSDave May   ierr = DMSwarmGetField(dm,"DMSwarm_rank",NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
403*3454631fSDave May   for (p=0; p<npoints; p++) {
404*3454631fSDave May     if (rankval[p] != (PetscInt)rank) {
405*3454631fSDave May       PetscBool found_rank;
406*3454631fSDave May 
407*3454631fSDave May       sendcount++;
408*3454631fSDave May 
409*3454631fSDave May       for (k=0; k<50; k++) {
410*3454631fSDave May         if (toranks[k] == (PetscMPIInt)rankval[p]) { found_rank = PETSC_TRUE; }
411*3454631fSDave May       }
412*3454631fSDave May       if (!found_rank) {
413*3454631fSDave May         toranks[nto] = (PetscMPIInt)rankval[p];
414*3454631fSDave May         nto++;
415*3454631fSDave May       }
416*3454631fSDave May 
417*3454631fSDave May     }
418*3454631fSDave May   }
419*3454631fSDave May 
420*3454631fSDave May   PetscMalloc1(sizeof_dmswarm_point*sendcount,&todata);
421*3454631fSDave May   pk = 0;
422*3454631fSDave May   for (p=0; p<npoints; p++) {
423*3454631fSDave May     if (rankval[p] != (PetscInt)rank) {
424*3454631fSDave May 
425*3454631fSDave May       ierr = DataBucketFillPackedArray(swarm->db,p,singlebuffer);CHKERRQ(ierr);
426*3454631fSDave May       memcpy(todata + pk*sizeof_dmswarm_point,singlebuffer,sizeof_dmswarm_point);
427*3454631fSDave May       pk++;
428*3454631fSDave May     }
429*3454631fSDave May   }
430*3454631fSDave May 
431*3454631fSDave May   ierr = DMSwarmRestoreField(dm,"DMSwarm_rank",NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
432*3454631fSDave May 
433*3454631fSDave May   if (nto == 0) {
434*3454631fSDave May     PetscPrintf(PETSC_COMM_SELF,"rank[%d] sending nothing\n",rank);
435*3454631fSDave May   } else if (nto == 1) {
436*3454631fSDave May     PetscPrintf(PETSC_COMM_SELF,"rank[%d] sending %D to rank %D\n",rank,sendcount,toranks[0]);
437*3454631fSDave May   } else if (nto == 2) {
438*3454631fSDave May     PetscPrintf(PETSC_COMM_SELF,"rank[%d] sending %D to ranks %D %D\n",rank,sendcount,toranks[0],toranks[1]);
439*3454631fSDave May   } else if (nto == 3) {
440*3454631fSDave May     PetscPrintf(PETSC_COMM_SELF,"rank[%d] sending %D to ranks %D %D %D\n",rank,sendcount,toranks[0],toranks[1],toranks[2]);
441*3454631fSDave May   } else if (nto == 4) {
442*3454631fSDave May     PetscPrintf(PETSC_COMM_SELF,"rank[%d] sending %D to ranks %D %D %D %D\n",rank,sendcount,toranks[0],toranks[1],toranks[2],toranks[3]);
443*3454631fSDave May   } else if (nto == 5) {
444*3454631fSDave May     PetscPrintf(PETSC_COMM_SELF,"rank[%d] sending %D to ranks %D %D %D %D %D\n",rank,sendcount,toranks[0],toranks[1],toranks[2],toranks[3],toranks[4]);
445*3454631fSDave May   }
446*3454631fSDave May 
447*3454631fSDave May   /* this function is not going to be useful if the count has to be equal on all ranks */
448*3454631fSDave May   ierr = PetscCommBuildTwoSided( comm, 1, MPI_CHAR, nto, toranks, (void*)todata,
449*3454631fSDave May                                 &nfrom, &fromranks, (void**)&fromdata);CHKERRQ(ierr);
450*3454631fSDave May 
451*3454631fSDave May 
452*3454631fSDave May   if (nfrom == 0) {
453*3454631fSDave May     PetscPrintf(PETSC_COMM_SELF,"rank[%d] recievd nothing\n",rank);
454*3454631fSDave May   } else if (nfrom == 1) {
455*3454631fSDave May     PetscPrintf(PETSC_COMM_SELF,"rank[%d] recieving %D from rank %D\n",rank,sendcount,fromranks[0]);
456*3454631fSDave May   } else if (nfrom == 2) {
457*3454631fSDave May     PetscPrintf(PETSC_COMM_SELF,"rank[%d] recieving %D from ranks %D %D\n",rank,sendcount,fromranks[0],fromranks[1]);
458*3454631fSDave May   } else if (nfrom == 3) {
459*3454631fSDave May     PetscPrintf(PETSC_COMM_SELF,"rank[%d] recieving %D from ranks %D %D %D\n",rank,sendcount,fromranks[0],fromranks[1],fromranks[2]);
460*3454631fSDave May   } else if (nfrom == 4) {
461*3454631fSDave May     PetscPrintf(PETSC_COMM_SELF,"rank[%d] recieving %D from ranks %D %D %D %D\n",rank,sendcount,fromranks[0],fromranks[1],fromranks[2],fromranks[3]);
462*3454631fSDave May   } else if (nfrom == 5) {
463*3454631fSDave May     PetscPrintf(PETSC_COMM_SELF,"rank[%d] recieving %D from ranks %D %D %D %D %D\n",rank,sendcount,fromranks[0],fromranks[1],fromranks[2],fromranks[3],fromranks[4]);
464*3454631fSDave May   }
465*3454631fSDave May 
466*3454631fSDave May 
467*3454631fSDave May 
468*3454631fSDave May   ierr = DataBucketDestroyPackedArray(swarm->db,&singlebuffer);CHKERRQ(ierr);
469*3454631fSDave May   PetscFree(toranks);
470*3454631fSDave May   PetscFree(fromranks);
471*3454631fSDave May   PetscFree(todata);
472*3454631fSDave May #endif
473*3454631fSDave May   PetscFunctionReturn(0);
474*3454631fSDave May }
475*3454631fSDave May 
476*3454631fSDave May #undef __FUNCT__
477*3454631fSDave May #define __FUNCT__ "DMSwarmPush"
478*3454631fSDave May PETSC_EXTERN PetscErrorCode DMSwarmPush(DM dm,PetscBool remove_sent_points)
479*3454631fSDave May {
480*3454631fSDave May   PetscErrorCode ierr;
481*3454631fSDave May   ierr = DMSwarmPush_Basic(dm,remove_sent_points);CHKERRQ(ierr);
482*3454631fSDave May   PetscFunctionReturn(0);
483*3454631fSDave May }
484*3454631fSDave May 
485*3454631fSDave May 
486*3454631fSDave May #undef __FUNCT__
487*3454631fSDave May #define __FUNCT__ "DMSetup_Swarm"
488*3454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm)
489*3454631fSDave May {
490*3454631fSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
491*3454631fSDave May   PetscErrorCode ierr;
492*3454631fSDave May   PetscMPIInt rank;
493*3454631fSDave May   PetscInt p,npoints,*rankval;
494*3454631fSDave May 
495*3454631fSDave May   if (swarm->issetup) PetscFunctionReturn(0);
496*3454631fSDave May 
497*3454631fSDave May   PetscPrintf(PETSC_COMM_SELF,"Swarm setup \n");
498*3454631fSDave May   swarm->issetup = PETSC_TRUE;
499*3454631fSDave May 
500*3454631fSDave May   /* check some fields were registered */
501*3454631fSDave May   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
502*3454631fSDave May 
503*3454631fSDave May   /* check local sizes were set */
504*3454631fSDave May   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
505*3454631fSDave May 
506*3454631fSDave May   /* initialize values in pid and rank placeholders */
507*3454631fSDave May   /* TODO: [pid - use MPI_Scan] */
508*3454631fSDave May 
509*3454631fSDave May   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
510*3454631fSDave May   ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
511*3454631fSDave May   ierr = DMSwarmGetField(dm,"DMSwarm_rank",NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
512*3454631fSDave May   for (p=0; p<npoints; p++) {
513*3454631fSDave May     rankval[p] = (PetscInt)rank;
514*3454631fSDave May   }
515*3454631fSDave May   ierr = DMSwarmRestoreField(dm,"DMSwarm_rank",NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
516*3454631fSDave May 
517*3454631fSDave May   PetscFunctionReturn(0);
518*3454631fSDave May }
519*3454631fSDave May 
520b62e03f8SDave May #undef __FUNCT__
52157795646SDave May #define __FUNCT__ "DMDestroy_Swarm"
52257795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm)
52357795646SDave May {
52457795646SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
52557795646SDave May   PetscErrorCode ierr;
52657795646SDave May 
52757795646SDave May   PetscFunctionBegin;
5286845f8f5SDave May   ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr);
52957795646SDave May   ierr = PetscFree(swarm);CHKERRQ(ierr);
53057795646SDave May   PetscFunctionReturn(0);
53157795646SDave May }
53257795646SDave May 
53357795646SDave May #undef __FUNCT__
5345f50eb2eSDave May #define __FUNCT__ "DMView_Swarm"
5355f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
5365f50eb2eSDave May {
5375f50eb2eSDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
5385f50eb2eSDave May   PetscBool      iascii,ibinary,ishdf5,isvtk;
5395f50eb2eSDave May   PetscErrorCode ierr;
5405f50eb2eSDave May 
5415f50eb2eSDave May   PetscFunctionBegin;
5425f50eb2eSDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5435f50eb2eSDave May   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
5445f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
5455f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
5465f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
5475f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
5485f50eb2eSDave May   if (iascii) {
5496845f8f5SDave May     ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
5505f50eb2eSDave May   } else if (ibinary) {
5515f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
5525f50eb2eSDave May   } else if (ishdf5) {
5535f50eb2eSDave May #if defined(PETSC_HAVE_HDF5)
5545f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
5555f50eb2eSDave May #else
5565f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
5575f50eb2eSDave May #endif
5585f50eb2eSDave May   } else if (isvtk) {
5595f50eb2eSDave May     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
5605f50eb2eSDave May   }
5615f50eb2eSDave May   PetscFunctionReturn(0);
5625f50eb2eSDave May }
5635f50eb2eSDave May 
5645f50eb2eSDave May #undef __FUNCT__
56557795646SDave May #define __FUNCT__ "DMCreate_Swarm"
56657795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
56757795646SDave May {
56857795646SDave May   DM_Swarm      *swarm;
56957795646SDave May   PetscErrorCode ierr;
57057795646SDave May 
57157795646SDave May   PetscFunctionBegin;
57257795646SDave May   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
57357795646SDave May   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
57457795646SDave May 
5756845f8f5SDave May   ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr);
576b5bcf523SDave May   swarm->vec_field_set = PETSC_FALSE;
577*3454631fSDave May   swarm->issetup = PETSC_FALSE;
578b62e03f8SDave May 
57957795646SDave May   dm->dim  = 0;
58057795646SDave May   dm->data = swarm;
58157795646SDave May 
5825f50eb2eSDave May   dm->ops->view                            = DMView_Swarm;
58357795646SDave May   dm->ops->load                            = NULL;
58457795646SDave May   dm->ops->setfromoptions                  = NULL;
58557795646SDave May   dm->ops->clone                           = NULL;
586*3454631fSDave May   dm->ops->setup                           = DMSetup_Swarm;
58757795646SDave May   dm->ops->createdefaultsection            = NULL;
58857795646SDave May   dm->ops->createdefaultconstraints        = NULL;
589b5bcf523SDave May   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
590b5bcf523SDave May   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
59157795646SDave May   dm->ops->getlocaltoglobalmapping         = NULL;
59257795646SDave May   dm->ops->createfieldis                   = NULL;
59357795646SDave May   dm->ops->createcoordinatedm              = NULL;
59457795646SDave May   dm->ops->getcoloring                     = NULL;
59557795646SDave May   dm->ops->creatematrix                    = NULL;
59657795646SDave May   dm->ops->createinterpolation             = NULL;
59757795646SDave May   dm->ops->getaggregates                   = NULL;
59857795646SDave May   dm->ops->getinjection                    = NULL;
59957795646SDave May   dm->ops->refine                          = NULL;
60057795646SDave May   dm->ops->coarsen                         = NULL;
60157795646SDave May   dm->ops->refinehierarchy                 = NULL;
60257795646SDave May   dm->ops->coarsenhierarchy                = NULL;
60357795646SDave May   dm->ops->globaltolocalbegin              = NULL;
60457795646SDave May   dm->ops->globaltolocalend                = NULL;
60557795646SDave May   dm->ops->localtoglobalbegin              = NULL;
60657795646SDave May   dm->ops->localtoglobalend                = NULL;
60757795646SDave May   dm->ops->destroy                         = DMDestroy_Swarm;
60857795646SDave May   dm->ops->createsubdm                     = NULL;
60957795646SDave May   dm->ops->getdimpoints                    = NULL;
61057795646SDave May   dm->ops->locatepoints                    = NULL;
61157795646SDave May 
61257795646SDave May   PetscFunctionReturn(0);
61357795646SDave May }