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 }