1 2 #define PETSCDM_DLL 3 #include <petsc/private/dmswarmimpl.h> /*I "petscdmswarm.h" I*/ 4 #include "data_bucket.h" 5 6 const char* DMSwarmTypeNames[] = { "basic", "pic", 0 }; 7 const char* DMSwarmMigrateTypeNames[] = { "basic", "dmcellnscatter", "dmcellexact", "user", 0 }; 8 const char* DMSwarmCollectTypeNames[] = { "basic", "boundingbox", "general", "user", 0 }; 9 10 const char DMSwarmField_pid[] = "DMSwarm_pid"; 11 const char DMSwarmField_rank[] = "DMSwarm_rank"; 12 const char DMSwarmPICField_coor[] = "DMSwarmPIC_coor"; 13 14 15 PetscErrorCode DMSwarmMigrate_Push_Basic(DM dm,PetscBool remove_sent_points); 16 17 18 //typedef PetscErrorCode (*swarm_project)(DM,DM,Vec) DMSwarmProjectMethod; /* swarm, geometry, result */ 19 20 //typedef enum { PROJECT_DMDA_AQ1=0, PROJECT_DMDA_P0 } DMSwarmDMDAProjectionType; 21 22 #if 0 23 24 /* Defines what the local space will be */ 25 PetscErrorCode DMSwarmSetOverlap(void) 26 { 27 28 PetscFunctionReturn(0); 29 } 30 31 32 /* coordinates */ 33 /* 34 DMGetCoordinateDM returns self 35 DMGetCoordinates and DMGetCoordinatesLocal return same thing 36 Local view could be used to define overlapping information 37 */ 38 39 #endif 40 41 #undef __FUNCT__ 42 #define __FUNCT__ "DMSwarmVectorDefineField" 43 PETSC_EXTERN PetscErrorCode DMSwarmVectorDefineField(DM dm,const char fieldname[]) 44 { 45 DM_Swarm *swarm = (DM_Swarm*)dm->data; 46 PetscErrorCode ierr; 47 PetscInt bs,n; 48 PetscScalar *array; 49 PetscDataType type; 50 51 if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 52 ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr); 53 ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr); 54 55 /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */ 56 if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL"); 57 58 PetscSNPrintf(swarm->vec_field_name,PETSC_MAX_PATH_LEN-1,"%s",fieldname); 59 swarm->vec_field_set = PETSC_TRUE; 60 swarm->vec_field_bs = bs; 61 swarm->vec_field_nlocal = n; 62 ierr = DMSwarmRestoreField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr); 63 64 PetscFunctionReturn(0); 65 } 66 67 /* requires DMSwarmDefineFieldVector has been called */ 68 #undef __FUNCT__ 69 #define __FUNCT__ "DMCreateGlobalVector_Swarm" 70 PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec) 71 { 72 DM_Swarm *swarm = (DM_Swarm*)dm->data; 73 PetscErrorCode ierr; 74 Vec x; 75 char name[PETSC_MAX_PATH_LEN]; 76 77 if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 78 if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first"); 79 PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name); 80 ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr); 81 ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr); 82 ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr); 83 ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr); 84 ierr = VecSetFromOptions(x);CHKERRQ(ierr); 85 *vec = x; 86 87 PetscFunctionReturn(0); 88 } 89 90 /* requires DMSwarmDefineFieldVector has been called */ 91 #undef __FUNCT__ 92 #define __FUNCT__ "DMCreateLocalVector_Swarm" 93 PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec) 94 { 95 DM_Swarm *swarm = (DM_Swarm*)dm->data; 96 PetscErrorCode ierr; 97 Vec x; 98 char name[PETSC_MAX_PATH_LEN]; 99 100 if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 101 if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first"); 102 PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name); 103 ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr); 104 ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr); 105 ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,swarm->db->L);CHKERRQ(ierr); 106 ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr); 107 ierr = VecSetFromOptions(x);CHKERRQ(ierr); 108 *vec = x; 109 110 PetscFunctionReturn(0); 111 } 112 113 #undef __FUNCT__ 114 #define __FUNCT__ "DMSwarmCreateGlobalVectorFromField" 115 PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec) 116 { 117 DM_Swarm *swarm = (DM_Swarm*)dm->data; 118 PetscErrorCode ierr; 119 PetscInt bs,n; 120 PetscScalar *array; 121 Vec x; 122 PetscDataType type; 123 char name[PETSC_MAX_PATH_LEN]; 124 PetscMPIInt commsize; 125 126 if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 127 ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr); 128 ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr); 129 130 /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */ 131 if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL"); 132 133 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&commsize);CHKERRQ(ierr); 134 if (commsize == 1) { 135 ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)dm),bs,n*bs,array,&x);CHKERRQ(ierr); 136 } else { 137 ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)dm),bs,n*bs,PETSC_DETERMINE,array,&x);CHKERRQ(ierr); 138 } 139 PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmSharedField_%s",fieldname); 140 ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr); 141 142 /* Set guard */ 143 PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarm_VecFieldInPlace_%s",fieldname); 144 ierr = PetscObjectComposeFunction((PetscObject)x,name,DMSwarmDestroyGlobalVectorFromField);CHKERRQ(ierr); 145 146 *vec = x; 147 PetscFunctionReturn(0); 148 } 149 150 #undef __FUNCT__ 151 #define __FUNCT__ "DMSwarmDestroyGlobalVectorFromField" 152 PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec) 153 { 154 DM_Swarm *swarm = (DM_Swarm*)dm->data; 155 PetscErrorCode ierr; 156 DataField gfield; 157 char name[PETSC_MAX_PATH_LEN]; 158 void (*fptr)(void); 159 160 /* get data field */ 161 ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 162 163 /* check vector is an inplace array */ 164 PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarm_VecFieldInPlace_%s",fieldname); 165 ierr = PetscObjectQueryFunction((PetscObject)(*vec),name,&fptr);CHKERRQ(ierr); 166 if (!fptr) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Vector being destroyed was not created from DMSwarm field(%s)",fieldname); 167 168 /* restore data field */ 169 ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr); 170 171 ierr = VecDestroy(vec);CHKERRQ(ierr); 172 173 PetscFunctionReturn(0); 174 } 175 176 /* 177 PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec) 178 { 179 PetscFunctionReturn(0); 180 } 181 182 PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec) 183 { 184 PetscFunctionReturn(0); 185 } 186 */ 187 188 #undef __FUNCT__ 189 #define __FUNCT__ "DMSwarmInitializeFieldRegister" 190 PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm) 191 { 192 DM_Swarm *swarm = (DM_Swarm*)dm->data; 193 PetscErrorCode ierr; 194 195 swarm->field_registration_initialized = PETSC_TRUE; 196 197 ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */ 198 ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */ 199 200 PetscFunctionReturn(0); 201 } 202 203 #undef __FUNCT__ 204 #define __FUNCT__ "DMSwarmFinalizeFieldRegister" 205 PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm) 206 { 207 DM_Swarm *swarm = (DM_Swarm*)dm->data; 208 PetscErrorCode ierr; 209 210 if (!swarm->field_registration_finalized) { 211 ierr = DataBucketFinalize(swarm->db);CHKERRQ(ierr); 212 } 213 swarm->field_registration_finalized = PETSC_TRUE; 214 PetscFunctionReturn(0); 215 } 216 217 #undef __FUNCT__ 218 #define __FUNCT__ "DMSwarmSetLocalSizes" 219 PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer) 220 { 221 DM_Swarm *swarm = (DM_Swarm*)dm->data; 222 PetscErrorCode ierr; 223 224 ierr = DataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr); 225 226 PetscFunctionReturn(0); 227 } 228 229 #undef __FUNCT__ 230 #define __FUNCT__ "DMSwarmSetCellDM" 231 PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell) 232 { 233 DM_Swarm *swarm = (DM_Swarm*)dm->data; 234 swarm->dmcell = dmcell; 235 PetscFunctionReturn(0); 236 } 237 238 #undef __FUNCT__ 239 #define __FUNCT__ "DMSwarmGetCellDM" 240 PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell) 241 { 242 DM_Swarm *swarm = (DM_Swarm*)dm->data; 243 *dmcell = swarm->dmcell; 244 PetscFunctionReturn(0); 245 } 246 247 #undef __FUNCT__ 248 #define __FUNCT__ "DMSwarmGetLocalSize" 249 PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal) 250 { 251 DM_Swarm *swarm = (DM_Swarm*)dm->data; 252 PetscErrorCode ierr; 253 254 if (nlocal) { 255 ierr = DataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr); 256 } 257 258 PetscFunctionReturn(0); 259 } 260 261 #undef __FUNCT__ 262 #define __FUNCT__ "DMSwarmGetSize" 263 PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n) 264 { 265 DM_Swarm *swarm = (DM_Swarm*)dm->data; 266 PetscErrorCode ierr; 267 PetscInt nlocal,ng; 268 269 ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr); 270 ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 271 if (n) { *n = ng; } 272 PetscFunctionReturn(0); 273 } 274 275 #undef __FUNCT__ 276 #define __FUNCT__ "DMSwarmRegisterPetscDatatypeField" 277 PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type) 278 { 279 PetscErrorCode ierr; 280 DM_Swarm *swarm = (DM_Swarm*)dm->data; 281 size_t size; 282 283 if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first"); 284 if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first"); 285 286 if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 287 if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 288 if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 289 if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 290 if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 291 292 switch (type) { 293 case PETSC_CHAR: 294 size = sizeof(PetscChar); 295 break; 296 case PETSC_SHORT: 297 size = sizeof(PetscShort); 298 break; 299 case PETSC_INT: 300 size = sizeof(PetscInt); 301 break; 302 case PETSC_LONG: 303 size = sizeof(Petsc64bitInt); 304 break; 305 case PETSC_FLOAT: 306 size = sizeof(PetscFloat); 307 break; 308 case PETSC_DOUBLE: 309 size = sizeof(PetscReal); 310 break; 311 312 default: 313 SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 314 break; 315 } 316 317 /* Load a specific data type into data bucket, specifying textual name and its size in bytes */ 318 ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr); 319 { 320 DataField gfield; 321 322 ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 323 ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr); 324 } 325 swarm->db->field[swarm->db->nfields-1]->petsc_type = type; 326 327 PetscFunctionReturn(0); 328 } 329 330 #undef __FUNCT__ 331 #define __FUNCT__ "DMSwarmRegisterUserStructField" 332 PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size) 333 { 334 PetscErrorCode ierr; 335 DM_Swarm *swarm = (DM_Swarm*)dm->data; 336 337 ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr); 338 swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ; 339 340 PetscFunctionReturn(0); 341 } 342 343 #undef __FUNCT__ 344 #define __FUNCT__ "DMSwarmRegisterUserDatatypeField" 345 PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize) 346 { 347 DM_Swarm *swarm = (DM_Swarm*)dm->data; 348 PetscErrorCode ierr; 349 350 ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr); 351 { 352 DataField gfield; 353 354 ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 355 ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr); 356 } 357 swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN; 358 359 PetscFunctionReturn(0); 360 } 361 362 #undef __FUNCT__ 363 #define __FUNCT__ "DMSwarmGetField" 364 PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 365 { 366 DM_Swarm *swarm = (DM_Swarm*)dm->data; 367 DataField gfield; 368 PetscErrorCode ierr; 369 370 if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 371 372 ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 373 ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr); 374 ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr); 375 if (blocksize) {*blocksize = gfield->bs; } 376 if (type) { *type = gfield->petsc_type; } 377 378 PetscFunctionReturn(0); 379 } 380 381 #undef __FUNCT__ 382 #define __FUNCT__ "DMSwarmRestoreField" 383 PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 384 { 385 DM_Swarm *swarm = (DM_Swarm*)dm->data; 386 DataField gfield; 387 PetscErrorCode ierr; 388 389 ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 390 ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr); 391 if (data) *data = NULL; 392 393 PetscFunctionReturn(0); 394 } 395 396 #undef __FUNCT__ 397 #define __FUNCT__ "DMSwarmAddPoint" 398 PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm) 399 { 400 DM_Swarm *swarm = (DM_Swarm*)dm->data; 401 PetscErrorCode ierr; 402 403 if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 404 ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr); 405 PetscFunctionReturn(0); 406 } 407 408 #undef __FUNCT__ 409 #define __FUNCT__ "DMSwarmAddNPoints" 410 PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints) 411 { 412 DM_Swarm *swarm = (DM_Swarm*)dm->data; 413 PetscErrorCode ierr; 414 PetscInt nlocal; 415 416 ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr); 417 nlocal = nlocal + npoints; 418 ierr = DataBucketSetSizes(swarm->db,nlocal,-1);CHKERRQ(ierr); 419 PetscFunctionReturn(0); 420 } 421 422 #undef __FUNCT__ 423 #define __FUNCT__ "DMSwarmRemovePoint" 424 PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm) 425 { 426 DM_Swarm *swarm = (DM_Swarm*)dm->data; 427 PetscErrorCode ierr; 428 429 ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr); 430 PetscFunctionReturn(0); 431 } 432 433 #undef __FUNCT__ 434 #define __FUNCT__ "DMSwarmRemovePointAtIndex" 435 PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx) 436 { 437 DM_Swarm *swarm = (DM_Swarm*)dm->data; 438 PetscErrorCode ierr; 439 440 ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr); 441 PetscFunctionReturn(0); 442 } 443 444 #undef __FUNCT__ 445 #define __FUNCT__ "DMSwarmMigrate_Basic" 446 PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points) 447 { 448 PetscErrorCode ierr; 449 ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr); 450 PetscFunctionReturn(0); 451 } 452 453 PetscErrorCode DMSwarmMigrate_CellDMScatter(DM dm,PetscBool remove_sent_points); 454 PetscErrorCode DMSwarmMigrate_CellDMExact(DM dm,PetscBool remove_sent_points); 455 456 #undef __FUNCT__ 457 #define __FUNCT__ "DMSwarmMigrate" 458 PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points) 459 { 460 DM_Swarm *swarm = (DM_Swarm*)dm->data; 461 PetscErrorCode ierr; 462 463 switch (swarm->migrate_type) { 464 465 case DMSWARM_MIGRATE_BASIC: 466 ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr); 467 break; 468 469 case DMSWARM_MIGRATE_DMCELLNSCATTER: 470 ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr); 471 break; 472 473 case DMSWARM_MIGRATE_DMCELLEXACT: 474 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented"); 475 //ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr); 476 break; 477 478 case DMSWARM_MIGRATE_USER: 479 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented"); 480 //ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr); 481 break; 482 483 default: 484 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown"); 485 break; 486 } 487 PetscFunctionReturn(0); 488 } 489 490 PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize); 491 492 #undef __FUNCT__ 493 #define __FUNCT__ "DMSwarmCollectViewCreate" 494 PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm) 495 { 496 PetscErrorCode ierr; 497 DM_Swarm *swarm = (DM_Swarm*)dm->data; 498 PetscInt ng; 499 500 if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active"); 501 502 ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr); 503 switch (swarm->collect_type) { 504 505 case DMSWARM_COLLECT_BASIC: 506 ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr); 507 break; 508 509 case DMSWARM_COLLECT_DMDABOUNDINGBOX: 510 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented"); 511 //ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr); 512 break; 513 514 case DMSWARM_COLLECT_GENERAL: 515 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented"); 516 //ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr); 517 break; 518 519 default: 520 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown"); 521 break; 522 } 523 524 swarm->collect_view_active = PETSC_TRUE; 525 swarm->collect_view_reset_nlocal = ng; 526 527 PetscFunctionReturn(0); 528 } 529 530 #undef __FUNCT__ 531 #define __FUNCT__ "DMSwarmCollectViewDestroy" 532 PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm) 533 { 534 PetscErrorCode ierr; 535 DM_Swarm *swarm = (DM_Swarm*)dm->data; 536 537 if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active"); 538 ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr); 539 swarm->collect_view_active = PETSC_FALSE; 540 541 PetscFunctionReturn(0); 542 } 543 544 #undef __FUNCT__ 545 #define __FUNCT__ "DMSwarmSetUpPIC" 546 PetscErrorCode DMSwarmSetUpPIC(DM dm) 547 { 548 PetscInt dim; 549 PetscErrorCode ierr; 550 551 ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 552 if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim); 553 if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim); 554 ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr); 555 PetscFunctionReturn(0); 556 } 557 558 #undef __FUNCT__ 559 #define __FUNCT__ "DMSwarmSetType" 560 PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype) 561 { 562 DM_Swarm *swarm = (DM_Swarm*)dm->data; 563 PetscErrorCode ierr; 564 565 swarm->swarm_type = stype; 566 if (swarm->swarm_type == DMSWARM_PIC) { 567 ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr); 568 } 569 PetscFunctionReturn(0); 570 } 571 572 #undef __FUNCT__ 573 #define __FUNCT__ "DMSetup_Swarm" 574 PetscErrorCode DMSetup_Swarm(DM dm) 575 { 576 DM_Swarm *swarm = (DM_Swarm*)dm->data; 577 PetscErrorCode ierr; 578 PetscMPIInt rank; 579 PetscInt p,npoints,*rankval; 580 581 if (swarm->issetup) PetscFunctionReturn(0); 582 583 swarm->issetup = PETSC_TRUE; 584 585 if (swarm->swarm_type == DMSWARM_PIC) { 586 /* check dmcell exists */ 587 if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM"); 588 589 if (swarm->dmcell->ops->locatepointssubdomain) { 590 /* check methods exists for exact ownership identificiation */ 591 PetscPrintf(PetscObjectComm((PetscObject)dm)," DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n"); 592 swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT; 593 } else { 594 /* check methods exist for point location AND rank neighbor identification */ 595 if (swarm->dmcell->ops->locatepoints) { 596 PetscPrintf(PetscObjectComm((PetscObject)dm)," DMSWARM_PIC: Using method CellDM->LocatePoints\n"); 597 } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined"); 598 599 if (swarm->dmcell->ops->getneighbors) { 600 PetscPrintf(PetscObjectComm((PetscObject)dm)," DMSWARM_PIC: Using method CellDM->GetNeigbors\n"); 601 } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined"); 602 603 swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER; 604 } 605 } 606 607 ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr); 608 609 /* check some fields were registered */ 610 if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()"); 611 612 /* check local sizes were set */ 613 if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()"); 614 615 /* initialize values in pid and rank placeholders */ 616 /* TODO: [pid - use MPI_Scan] */ 617 618 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 619 ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr); 620 ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr); 621 for (p=0; p<npoints; p++) { 622 rankval[p] = (PetscInt)rank; 623 } 624 ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr); 625 626 PetscFunctionReturn(0); 627 } 628 629 #undef __FUNCT__ 630 #define __FUNCT__ "DMDestroy_Swarm" 631 PetscErrorCode DMDestroy_Swarm(DM dm) 632 { 633 DM_Swarm *swarm = (DM_Swarm*)dm->data; 634 PetscErrorCode ierr; 635 636 PetscFunctionBegin; 637 ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr); 638 ierr = PetscFree(swarm);CHKERRQ(ierr); 639 PetscFunctionReturn(0); 640 } 641 642 #undef __FUNCT__ 643 #define __FUNCT__ "DMView_Swarm" 644 PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer) 645 { 646 DM_Swarm *swarm = (DM_Swarm*)dm->data; 647 PetscBool iascii,ibinary,ishdf5,isvtk; 648 PetscErrorCode ierr; 649 650 PetscFunctionBegin; 651 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 652 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 653 ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 654 ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 655 ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 656 ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 657 if (iascii) { 658 ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr); 659 } else if (ibinary) { 660 SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support"); 661 } else if (ishdf5) { 662 #if defined(PETSC_HAVE_HDF5) 663 SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support"); 664 #else 665 SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5"); 666 #endif 667 } else if (isvtk) { 668 SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support"); 669 } 670 PetscFunctionReturn(0); 671 } 672 673 #undef __FUNCT__ 674 #define __FUNCT__ "DMCreate_Swarm" 675 PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm) 676 { 677 DM_Swarm *swarm; 678 PetscErrorCode ierr; 679 680 PetscFunctionBegin; 681 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 682 ierr = PetscNewLog(dm,&swarm);CHKERRQ(ierr); 683 dm->data = swarm; 684 685 ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr); 686 ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr); 687 688 swarm->vec_field_set = PETSC_FALSE; 689 swarm->issetup = PETSC_FALSE; 690 swarm->swarm_type = DMSWARM_BASIC; 691 swarm->migrate_type = DMSWARM_MIGRATE_BASIC; 692 swarm->collect_type = DMSWARM_COLLECT_BASIC; 693 swarm->migrate_error_on_missing_point = PETSC_FALSE; 694 695 swarm->dmcell = NULL; 696 swarm->collect_view_active = PETSC_FALSE; 697 swarm->collect_view_reset_nlocal = -1; 698 699 dm->dim = 0; 700 dm->ops->view = DMView_Swarm; 701 dm->ops->load = NULL; 702 dm->ops->setfromoptions = NULL; 703 dm->ops->clone = NULL; 704 dm->ops->setup = DMSetup_Swarm; 705 dm->ops->createdefaultsection = NULL; 706 dm->ops->createdefaultconstraints = NULL; 707 dm->ops->createglobalvector = DMCreateGlobalVector_Swarm; 708 dm->ops->createlocalvector = DMCreateLocalVector_Swarm; 709 dm->ops->getlocaltoglobalmapping = NULL; 710 dm->ops->createfieldis = NULL; 711 dm->ops->createcoordinatedm = NULL; 712 dm->ops->getcoloring = NULL; 713 dm->ops->creatematrix = NULL; 714 dm->ops->createinterpolation = NULL; 715 dm->ops->getaggregates = NULL; 716 dm->ops->getinjection = NULL; 717 dm->ops->refine = NULL; 718 dm->ops->coarsen = NULL; 719 dm->ops->refinehierarchy = NULL; 720 dm->ops->coarsenhierarchy = NULL; 721 dm->ops->globaltolocalbegin = NULL; 722 dm->ops->globaltolocalend = NULL; 723 dm->ops->localtoglobalbegin = NULL; 724 dm->ops->localtoglobalend = NULL; 725 dm->ops->destroy = DMDestroy_Swarm; 726 dm->ops->createsubdm = NULL; 727 dm->ops->getdimpoints = NULL; 728 dm->ops->locatepoints = NULL; 729 730 PetscFunctionReturn(0); 731 }