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 /*@C 18 19 DMSwarmVectorDefineField - Sets the field from which to define a Vec object 20 21 Collective on DM 22 23 Input parameters: 24 . dm - a DMSwarm 25 . fieldname - The textual name given to a registered field 26 27 Level: beginner 28 29 Notes: 30 The field with name fieldname must be defined as having a data type of PetscScalar 31 This function must be called prior to calling DMCreateLocalVector(), DMCreateGlobalVector(). 32 Mutiple calls to DMSwarmVectorDefineField() are permitted. 33 34 . seealso: DMSwarmRegisterPetscDatatypeField() 35 36 @*/ 37 #undef __FUNCT__ 38 #define __FUNCT__ "DMSwarmVectorDefineField" 39 PETSC_EXTERN PetscErrorCode DMSwarmVectorDefineField(DM dm,const char fieldname[]) 40 { 41 DM_Swarm *swarm = (DM_Swarm*)dm->data; 42 PetscErrorCode ierr; 43 PetscInt bs,n; 44 PetscScalar *array; 45 PetscDataType type; 46 47 if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 48 ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr); 49 ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr); 50 51 /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */ 52 if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL"); 53 54 PetscSNPrintf(swarm->vec_field_name,PETSC_MAX_PATH_LEN-1,"%s",fieldname); 55 swarm->vec_field_set = PETSC_TRUE; 56 swarm->vec_field_bs = bs; 57 swarm->vec_field_nlocal = n; 58 ierr = DMSwarmRestoreField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr); 59 60 PetscFunctionReturn(0); 61 } 62 63 /* requires DMSwarmDefineFieldVector has been called */ 64 #undef __FUNCT__ 65 #define __FUNCT__ "DMCreateGlobalVector_Swarm" 66 PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec) 67 { 68 DM_Swarm *swarm = (DM_Swarm*)dm->data; 69 PetscErrorCode ierr; 70 Vec x; 71 char name[PETSC_MAX_PATH_LEN]; 72 73 if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 74 if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first"); 75 if (swarm->vec_field_nlocal != swarm->db->L) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSwarm sizes have changed since last call to VectorDefineField first"); /* Stale data */ 76 77 PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name); 78 ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr); 79 ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr); 80 ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr); 81 ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr); 82 ierr = VecSetFromOptions(x);CHKERRQ(ierr); 83 *vec = x; 84 85 PetscFunctionReturn(0); 86 } 87 88 /* requires DMSwarmDefineFieldVector has been called */ 89 #undef __FUNCT__ 90 #define __FUNCT__ "DMCreateLocalVector_Swarm" 91 PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec) 92 { 93 DM_Swarm *swarm = (DM_Swarm*)dm->data; 94 PetscErrorCode ierr; 95 Vec x; 96 char name[PETSC_MAX_PATH_LEN]; 97 98 if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 99 if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first"); 100 if (swarm->vec_field_nlocal != swarm->db->L) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSwarm sizes have changed since last call to VectorDefineField first"); /* Stale data */ 101 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 /*@C 114 115 DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field 116 117 Collective on DM 118 119 Input parameters: 120 . dm - a DMSwarm 121 . fieldname - the textual name given to a registered field 122 123 Output parameters: 124 . vec - the vector 125 126 Level: beginner 127 128 . seealso: DMSwarmRegisterPetscDatatypeField() 129 130 @*/ 131 #undef __FUNCT__ 132 #define __FUNCT__ "DMSwarmCreateGlobalVectorFromField" 133 PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec) 134 { 135 DM_Swarm *swarm = (DM_Swarm*)dm->data; 136 PetscErrorCode ierr; 137 PetscInt bs,n; 138 PetscScalar *array; 139 Vec x; 140 PetscDataType type; 141 char name[PETSC_MAX_PATH_LEN]; 142 PetscMPIInt commsize; 143 144 if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 145 146 ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr); 147 ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr); 148 149 /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */ 150 if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL"); 151 152 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&commsize);CHKERRQ(ierr); 153 if (commsize == 1) { 154 ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)dm),bs,n*bs,array,&x);CHKERRQ(ierr); 155 } else { 156 ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)dm),bs,n*bs,PETSC_DETERMINE,array,&x);CHKERRQ(ierr); 157 } 158 PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmSharedField_%s",fieldname); 159 ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr); 160 161 /* Set guard */ 162 PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarm_VecFieldInPlace_%s",fieldname); 163 ierr = PetscObjectComposeFunction((PetscObject)x,name,DMSwarmDestroyGlobalVectorFromField);CHKERRQ(ierr); 164 *vec = x; 165 PetscFunctionReturn(0); 166 } 167 168 169 /*@C 170 171 DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field 172 173 Collective on DM 174 175 Input parameters: 176 . dm - a DMSwarm 177 . fieldname - the textual name given to a registered field 178 179 Output parameters: 180 . vec - the vector 181 182 Level: beginner 183 184 . seealso: DMSwarmRegisterPetscDatatypeField() 185 186 @*/ 187 #undef __FUNCT__ 188 #define __FUNCT__ "DMSwarmDestroyGlobalVectorFromField" 189 PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec) 190 { 191 DM_Swarm *swarm = (DM_Swarm*)dm->data; 192 PetscErrorCode ierr; 193 DataField gfield; 194 char name[PETSC_MAX_PATH_LEN]; 195 void (*fptr)(void); 196 PetscInt bs,nlocal; 197 198 ierr = VecGetLocalSize(*vec,&nlocal);CHKERRQ(ierr); 199 ierr = VecGetBlockSize(*vec,&bs);CHKERRQ(ierr); 200 if (nlocal/bs != swarm->db->L) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSwarm sizes have changed since vector was created - cannot ensure pointers are valid"); /* Stale data */ 201 202 /* get data field */ 203 ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 204 205 /* check vector is an inplace array */ 206 PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarm_VecFieldInPlace_%s",fieldname); 207 ierr = PetscObjectQueryFunction((PetscObject)(*vec),name,&fptr);CHKERRQ(ierr); 208 if (!fptr) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Vector being destroyed was not created from DMSwarm field(%s)",fieldname); 209 210 /* restore data field */ 211 ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr); 212 213 ierr = VecDestroy(vec);CHKERRQ(ierr); 214 215 PetscFunctionReturn(0); 216 } 217 218 #undef __FUNCT__ 219 #define __FUNCT__ "DMSwarmCreateGlobalVector" 220 PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVector(DM dm, const char fieldname[], Vec *vec) 221 { 222 DM_Swarm *swarm = (DM_Swarm *) dm->data; 223 PetscScalar *array; 224 PetscInt bs,n; 225 PetscMPIInt commsize; 226 PetscErrorCode ierr; 227 228 if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);} 229 230 ierr = DataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr); 231 ierr = DMSwarmGetField(dm,fieldname,&bs,NULL,(void**) &array);CHKERRQ(ierr); 232 ierr = DMSwarmRestoreField(dm,fieldname,&bs,NULL,(void**) &array);CHKERRQ(ierr); 233 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&commsize);CHKERRQ(ierr); 234 if (commsize == 1) { 235 ierr = VecCreateSeq(PetscObjectComm((PetscObject)dm),n*bs,vec);CHKERRQ(ierr); 236 ierr = VecSetBlockSize(*vec,bs);CHKERRQ(ierr); 237 } else { 238 ierr = VecCreateMPI(PetscObjectComm((PetscObject)dm),n*bs,PETSC_DETERMINE,vec);CHKERRQ(ierr); 239 ierr = VecSetBlockSize(*vec,bs);CHKERRQ(ierr); 240 } 241 PetscFunctionReturn(0); 242 } 243 244 /* 245 PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec) 246 { 247 PetscFunctionReturn(0); 248 } 249 250 PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec) 251 { 252 PetscFunctionReturn(0); 253 } 254 */ 255 256 257 /*@C 258 259 DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm 260 261 Collective on DM 262 263 Input parameter: 264 . dm - a DMSwarm 265 266 Level: beginner 267 268 Notes: 269 After all fields have been registered, users should call DMSwarmFinalizeFieldRegister() 270 271 . seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(), 272 DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 273 274 @*/ 275 #undef __FUNCT__ 276 #define __FUNCT__ "DMSwarmInitializeFieldRegister" 277 PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm) 278 { 279 DM_Swarm *swarm = (DM_Swarm*)dm->data; 280 PetscErrorCode ierr; 281 282 if (!swarm->field_registration_initialized) { 283 swarm->field_registration_initialized = PETSC_TRUE; 284 ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */ 285 ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */ 286 } 287 288 PetscFunctionReturn(0); 289 } 290 291 /*@C 292 293 DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm 294 295 Collective on DM 296 297 Input parameter: 298 . dm - a DMSwarm 299 300 Level: beginner 301 302 Notes: 303 After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined 304 on the DMSwarm 305 306 . seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(), 307 DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 308 309 @*/ 310 #undef __FUNCT__ 311 #define __FUNCT__ "DMSwarmFinalizeFieldRegister" 312 PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm) 313 { 314 DM_Swarm *swarm = (DM_Swarm*)dm->data; 315 PetscErrorCode ierr; 316 317 if (!swarm->field_registration_finalized) { 318 ierr = DataBucketFinalize(swarm->db);CHKERRQ(ierr); 319 } 320 swarm->field_registration_finalized = PETSC_TRUE; 321 PetscFunctionReturn(0); 322 } 323 324 /*@C 325 326 DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm 327 328 Not collective 329 330 Input parameters: 331 . dm - a DMSwarm 332 . nlocal - the length of each registered field 333 . buffer - the length of the buffer used to efficient dynamic re-sizing 334 335 Level: beginner 336 337 . seealso: DMSwarmGetLocalSize() 338 339 @*/ 340 #undef __FUNCT__ 341 #define __FUNCT__ "DMSwarmSetLocalSizes" 342 PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer) 343 { 344 DM_Swarm *swarm = (DM_Swarm*)dm->data; 345 PetscErrorCode ierr; 346 347 ierr = DataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr); 348 349 PetscFunctionReturn(0); 350 } 351 352 /*@C 353 354 DMSwarmSetCellDM - Attachs a DM to a DMSwarm 355 356 Collective on DM 357 358 Input parameters: 359 . dm - a DMSwarm 360 . dmcell - the DM to attach to the DMSwarm 361 362 Level: beginner 363 364 Notes: 365 The attached DM (dmcell) will be queried for pointlocation and 366 neighbor MPI-rank information if DMSwarmMigrate() is called 367 368 . seealso: DMSwarmGetCellDM(), DMSwarmMigrate() 369 370 @*/ 371 #undef __FUNCT__ 372 #define __FUNCT__ "DMSwarmSetCellDM" 373 PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell) 374 { 375 DM_Swarm *swarm = (DM_Swarm*)dm->data; 376 swarm->dmcell = dmcell; 377 PetscFunctionReturn(0); 378 } 379 380 /*@C 381 382 DMSwarmGetCellDM - Fetches the attached cell DM 383 384 Collective on DM 385 386 Input parameter: 387 . dm - a DMSwarm 388 389 Output parameter: 390 . dmcell - the DM which was attached to the DMSwarm 391 392 Level: beginner 393 394 Notes: 395 The attached DM (dmcell) will be queried for pointlocation and 396 neighbor MPI-rank information if DMSwarmMigrate() is called 397 398 . seealso: DMSwarmSetCellDM() 399 400 @*/ 401 #undef __FUNCT__ 402 #define __FUNCT__ "DMSwarmGetCellDM" 403 PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell) 404 { 405 DM_Swarm *swarm = (DM_Swarm*)dm->data; 406 *dmcell = swarm->dmcell; 407 PetscFunctionReturn(0); 408 } 409 410 /*@C 411 412 DMSwarmGetLocalSize - Retrives the local length of fields registered 413 414 Not collective 415 416 Input parameter: 417 . dm - a DMSwarm 418 419 Output parameter: 420 . nlocal - the length of each registered field 421 422 Level: beginner 423 424 . seealso: DMSwarmSetLocalSizes() 425 426 @*/ 427 #undef __FUNCT__ 428 #define __FUNCT__ "DMSwarmGetLocalSize" 429 PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal) 430 { 431 DM_Swarm *swarm = (DM_Swarm*)dm->data; 432 PetscErrorCode ierr; 433 434 if (nlocal) { 435 ierr = DataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr); 436 } 437 438 PetscFunctionReturn(0); 439 } 440 441 /*@C 442 443 DMSwarmGetSize - Retrives the total length of fields registered 444 445 Collective on DM 446 447 Input parameter: 448 . dm - a DMSwarm 449 450 Output parameter: 451 . n - the total length of each registered field 452 453 Level: beginner 454 455 Note: 456 This calls MPI_Allreduce upon each call (inefficient but safe) 457 458 . seealso: DMSwarmGetLocalSize() 459 460 @*/ 461 #undef __FUNCT__ 462 #define __FUNCT__ "DMSwarmGetSize" 463 PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n) 464 { 465 DM_Swarm *swarm = (DM_Swarm*)dm->data; 466 PetscErrorCode ierr; 467 PetscInt nlocal,ng; 468 469 ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr); 470 ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 471 if (n) { *n = ng; } 472 PetscFunctionReturn(0); 473 } 474 475 /*@C 476 477 DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm 478 479 Collective on DM 480 481 Input parameters: 482 . dm - a DMSwarm 483 . fieldname - the textual name to identify this field 484 . blocksize - the number of each data type 485 . type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG) 486 487 Level: beginner 488 489 Notes: 490 The textual name for each registered field must be unique 491 492 . seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 493 494 @*/ 495 #undef __FUNCT__ 496 #define __FUNCT__ "DMSwarmRegisterPetscDatatypeField" 497 PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type) 498 { 499 PetscErrorCode ierr; 500 DM_Swarm *swarm = (DM_Swarm*)dm->data; 501 size_t size; 502 503 if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first"); 504 if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first"); 505 506 if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 507 if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 508 if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 509 if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 510 if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 511 512 ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr); 513 514 /* Load a specific data type into data bucket, specifying textual name and its size in bytes */ 515 ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr); 516 { 517 DataField gfield; 518 519 ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 520 ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr); 521 } 522 swarm->db->field[swarm->db->nfields-1]->petsc_type = type; 523 524 PetscFunctionReturn(0); 525 } 526 527 /*@C 528 529 DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm 530 531 Collective on DM 532 533 Input parameters: 534 . dm - a DMSwarm 535 . fieldname - the textual name to identify this field 536 . size - the size in bytes of the user struct of each data type 537 538 Level: beginner 539 540 Notes: 541 The textual name for each registered field must be unique 542 543 . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField() 544 545 @*/ 546 #undef __FUNCT__ 547 #define __FUNCT__ "DMSwarmRegisterUserStructField" 548 PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size) 549 { 550 PetscErrorCode ierr; 551 DM_Swarm *swarm = (DM_Swarm*)dm->data; 552 553 ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr); 554 swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ; 555 556 PetscFunctionReturn(0); 557 } 558 559 /*@C 560 561 DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm 562 563 Collective on DM 564 565 Input parameters: 566 . dm - a DMSwarm 567 . fieldname - the textual name to identify this field 568 . size - the size in bytes of the user data type 569 . blocksize - the number of each data type 570 571 Level: beginner 572 573 Notes: 574 The textual name for each registered field must be unique 575 576 . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 577 578 @*/ 579 #undef __FUNCT__ 580 #define __FUNCT__ "DMSwarmRegisterUserDatatypeField" 581 PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize) 582 { 583 DM_Swarm *swarm = (DM_Swarm*)dm->data; 584 PetscErrorCode ierr; 585 586 ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr); 587 { 588 DataField gfield; 589 590 ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 591 ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr); 592 } 593 swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN; 594 595 PetscFunctionReturn(0); 596 } 597 598 /*@C 599 600 DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field 601 602 Not collective 603 604 Input parameters: 605 . dm - a DMSwarm 606 . fieldname - the textual name to identify this field 607 608 Output parameters: 609 . blocksize - the number of each data type 610 . type - the data type 611 . data - pointer to raw array 612 613 Level: beginner 614 615 Notes: 616 The user must call DMSwarmRestoreField() 617 618 . seealso: DMSwarmRestoreField() 619 620 @*/ 621 #undef __FUNCT__ 622 #define __FUNCT__ "DMSwarmGetField" 623 PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 624 { 625 DM_Swarm *swarm = (DM_Swarm*)dm->data; 626 DataField gfield; 627 PetscErrorCode ierr; 628 629 if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 630 631 ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 632 ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr); 633 ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr); 634 if (blocksize) {*blocksize = gfield->bs; } 635 if (type) { *type = gfield->petsc_type; } 636 637 PetscFunctionReturn(0); 638 } 639 640 /*@C 641 642 DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field 643 644 Not collective 645 646 Input parameters: 647 . dm - a DMSwarm 648 . fieldname - the textual name to identify this field 649 650 Output parameters: 651 . blocksize - the number of each data type 652 . type - the data type 653 . data - pointer to raw array 654 655 Level: beginner 656 657 Notes: 658 The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField() 659 660 . seealso: DMSwarmGetField() 661 662 @*/ 663 #undef __FUNCT__ 664 #define __FUNCT__ "DMSwarmRestoreField" 665 PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 666 { 667 DM_Swarm *swarm = (DM_Swarm*)dm->data; 668 DataField gfield; 669 PetscErrorCode ierr; 670 671 ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 672 ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr); 673 if (data) *data = NULL; 674 675 PetscFunctionReturn(0); 676 } 677 678 /*@C 679 680 DMSwarmAddPoint - Add space for one new point in the DMSwarm 681 682 Not collective 683 684 Input parameter: 685 . dm - a DMSwarm 686 687 Level: beginner 688 689 Notes: 690 The new point will have all fields initialized to zero 691 692 . seealso: DMSwarmAddNPoints() 693 694 @*/ 695 #undef __FUNCT__ 696 #define __FUNCT__ "DMSwarmAddPoint" 697 PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm) 698 { 699 DM_Swarm *swarm = (DM_Swarm*)dm->data; 700 PetscErrorCode ierr; 701 702 if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 703 ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr); 704 PetscFunctionReturn(0); 705 } 706 707 /*@C 708 709 DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm 710 711 Not collective 712 713 Input parameters: 714 . dm - a DMSwarm 715 . npoints - the number of new points to add 716 717 Level: beginner 718 719 Notes: 720 The new point will have all fields initialized to zero 721 722 . seealso: DMSwarmAddPoint() 723 724 @*/ 725 #undef __FUNCT__ 726 #define __FUNCT__ "DMSwarmAddNPoints" 727 PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints) 728 { 729 DM_Swarm *swarm = (DM_Swarm*)dm->data; 730 PetscErrorCode ierr; 731 PetscInt nlocal; 732 733 ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr); 734 nlocal = nlocal + npoints; 735 ierr = DataBucketSetSizes(swarm->db,nlocal,-1);CHKERRQ(ierr); 736 PetscFunctionReturn(0); 737 } 738 739 /*@C 740 741 DMSwarmRemovePoint - Remove the last point from the DMSwarm 742 743 Not collective 744 745 Input parameter: 746 . dm - a DMSwarm 747 748 Level: beginner 749 750 . seealso: DMSwarmRemovePointAtIndex() 751 752 @*/ 753 #undef __FUNCT__ 754 #define __FUNCT__ "DMSwarmRemovePoint" 755 PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm) 756 { 757 DM_Swarm *swarm = (DM_Swarm*)dm->data; 758 PetscErrorCode ierr; 759 760 ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr); 761 PetscFunctionReturn(0); 762 } 763 764 /*@C 765 766 DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm 767 768 Not collective 769 770 Input parameters: 771 . dm - a DMSwarm 772 . idx - index of point to remove 773 774 Level: beginner 775 776 . seealso: DMSwarmRemovePoint() 777 778 @*/ 779 #undef __FUNCT__ 780 #define __FUNCT__ "DMSwarmRemovePointAtIndex" 781 PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx) 782 { 783 DM_Swarm *swarm = (DM_Swarm*)dm->data; 784 PetscErrorCode ierr; 785 786 ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr); 787 PetscFunctionReturn(0); 788 } 789 790 #undef __FUNCT__ 791 #define __FUNCT__ "DMSwarmMigrate_Basic" 792 PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points) 793 { 794 PetscErrorCode ierr; 795 ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr); 796 PetscFunctionReturn(0); 797 } 798 799 PetscErrorCode DMSwarmMigrate_CellDMScatter(DM dm,PetscBool remove_sent_points); 800 PetscErrorCode DMSwarmMigrate_CellDMExact(DM dm,PetscBool remove_sent_points); 801 802 /*@C 803 804 DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks 805 806 Collective on DM 807 808 Input parameters: 809 . dm - the DMSwarm 810 . remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank 811 812 Notes: 813 The DM wil be modified to accomodate received points. 814 If remove_sent_points = PETSC_TRUE, send points will be removed from the DM 815 Different styles of migration are supported. See DMSwarmSetMigrateType() 816 817 Level: advanced 818 819 . seealso: DMSwarmSetMigrateType() 820 821 @*/ 822 #undef __FUNCT__ 823 #define __FUNCT__ "DMSwarmMigrate" 824 PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points) 825 { 826 DM_Swarm *swarm = (DM_Swarm*)dm->data; 827 PetscErrorCode ierr; 828 829 switch (swarm->migrate_type) { 830 831 case DMSWARM_MIGRATE_BASIC: 832 ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr); 833 break; 834 835 case DMSWARM_MIGRATE_DMCELLNSCATTER: 836 ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr); 837 break; 838 839 case DMSWARM_MIGRATE_DMCELLEXACT: 840 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented"); 841 //ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr); 842 break; 843 844 case DMSWARM_MIGRATE_USER: 845 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented"); 846 //ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr); 847 break; 848 849 default: 850 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown"); 851 break; 852 } 853 PetscFunctionReturn(0); 854 } 855 856 PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize); 857 858 /* 859 DMSwarmCollectViewCreate 860 861 * Applies a collection method and gathers point neighbour points into dm 862 863 Notes: 864 - Users should call DMSwarmCollectViewDestroy() after 865 they have finished computations associated with the collected points 866 */ 867 868 /*@C 869 870 DMSwarmCollectViewCreate - Applies a collection method and gathers points 871 in neighbour MPI-ranks into the DMSwarm 872 873 Collective on DM 874 875 Input parameter: 876 . dm - the DMSwarm 877 878 Notes: 879 Users should call DMSwarmCollectViewDestroy() after 880 they have finished computations associated with the collected points 881 Different collect methods are supported. See DMSwarmSetCollectType() 882 883 Level: advanced 884 885 . seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType() 886 887 @*/ 888 #undef __FUNCT__ 889 #define __FUNCT__ "DMSwarmCollectViewCreate" 890 PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm) 891 { 892 PetscErrorCode ierr; 893 DM_Swarm *swarm = (DM_Swarm*)dm->data; 894 PetscInt ng; 895 896 if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active"); 897 898 ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr); 899 switch (swarm->collect_type) { 900 901 case DMSWARM_COLLECT_BASIC: 902 ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr); 903 break; 904 905 case DMSWARM_COLLECT_DMDABOUNDINGBOX: 906 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented"); 907 //ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr); 908 break; 909 910 case DMSWARM_COLLECT_GENERAL: 911 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented"); 912 //ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr); 913 break; 914 915 default: 916 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown"); 917 break; 918 } 919 920 swarm->collect_view_active = PETSC_TRUE; 921 swarm->collect_view_reset_nlocal = ng; 922 923 PetscFunctionReturn(0); 924 } 925 926 /*@C 927 928 DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate() 929 930 Collective on DM 931 932 Input parameters: 933 . dm - the DMSwarm 934 935 Notes: 936 Users should call DMSwarmCollectViewCreate() before this function is called. 937 938 Level: advanced 939 940 . seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType() 941 942 @*/ 943 #undef __FUNCT__ 944 #define __FUNCT__ "DMSwarmCollectViewDestroy" 945 PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm) 946 { 947 PetscErrorCode ierr; 948 DM_Swarm *swarm = (DM_Swarm*)dm->data; 949 950 if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active"); 951 ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr); 952 swarm->collect_view_active = PETSC_FALSE; 953 954 PetscFunctionReturn(0); 955 } 956 957 #undef __FUNCT__ 958 #define __FUNCT__ "DMSwarmSetUpPIC" 959 PetscErrorCode DMSwarmSetUpPIC(DM dm) 960 { 961 PetscInt dim; 962 PetscErrorCode ierr; 963 964 ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 965 if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim); 966 if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim); 967 ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr); 968 PetscFunctionReturn(0); 969 } 970 971 /*@C 972 973 DMSwarmSetType - Set particular flavor of DMSwarm 974 975 Collective on DM 976 977 Input parameters: 978 . dm - the DMSwarm 979 . stype - the DMSwarm type (e.g. DMSWARM_PIC) 980 981 Level: advanced 982 983 . seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType() 984 985 @*/ 986 #undef __FUNCT__ 987 #define __FUNCT__ "DMSwarmSetType" 988 PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype) 989 { 990 DM_Swarm *swarm = (DM_Swarm*)dm->data; 991 PetscErrorCode ierr; 992 993 swarm->swarm_type = stype; 994 if (swarm->swarm_type == DMSWARM_PIC) { 995 ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr); 996 } 997 PetscFunctionReturn(0); 998 } 999 1000 #undef __FUNCT__ 1001 #define __FUNCT__ "DMSetup_Swarm" 1002 PetscErrorCode DMSetup_Swarm(DM dm) 1003 { 1004 DM_Swarm *swarm = (DM_Swarm*)dm->data; 1005 PetscErrorCode ierr; 1006 PetscMPIInt rank; 1007 PetscInt p,npoints,*rankval; 1008 1009 if (swarm->issetup) PetscFunctionReturn(0); 1010 1011 swarm->issetup = PETSC_TRUE; 1012 1013 if (swarm->swarm_type == DMSWARM_PIC) { 1014 /* check dmcell exists */ 1015 if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM"); 1016 1017 if (swarm->dmcell->ops->locatepointssubdomain) { 1018 /* check methods exists for exact ownership identificiation */ 1019 PetscPrintf(PetscObjectComm((PetscObject)dm)," DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n"); 1020 swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT; 1021 } else { 1022 /* check methods exist for point location AND rank neighbor identification */ 1023 if (swarm->dmcell->ops->locatepoints) { 1024 PetscPrintf(PetscObjectComm((PetscObject)dm)," DMSWARM_PIC: Using method CellDM->LocatePoints\n"); 1025 } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined"); 1026 1027 if (swarm->dmcell->ops->getneighbors) { 1028 PetscPrintf(PetscObjectComm((PetscObject)dm)," DMSWARM_PIC: Using method CellDM->GetNeigbors\n"); 1029 } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined"); 1030 1031 swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER; 1032 } 1033 } 1034 1035 ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr); 1036 1037 /* check some fields were registered */ 1038 if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()"); 1039 1040 /* check local sizes were set */ 1041 if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()"); 1042 1043 /* initialize values in pid and rank placeholders */ 1044 /* TODO: [pid - use MPI_Scan] */ 1045 1046 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 1047 ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr); 1048 ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr); 1049 for (p=0; p<npoints; p++) { 1050 rankval[p] = (PetscInt)rank; 1051 } 1052 ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr); 1053 1054 PetscFunctionReturn(0); 1055 } 1056 1057 #undef __FUNCT__ 1058 #define __FUNCT__ "DMDestroy_Swarm" 1059 PetscErrorCode DMDestroy_Swarm(DM dm) 1060 { 1061 DM_Swarm *swarm = (DM_Swarm*)dm->data; 1062 PetscErrorCode ierr; 1063 1064 PetscFunctionBegin; 1065 ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr); 1066 ierr = PetscFree(swarm);CHKERRQ(ierr); 1067 PetscFunctionReturn(0); 1068 } 1069 1070 #undef __FUNCT__ 1071 #define __FUNCT__ "DMSwarmView_Draw" 1072 PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer) 1073 { 1074 DM cdm; 1075 PetscDraw draw; 1076 PetscReal *coords, oldPause; 1077 PetscInt Np, p, bs; 1078 PetscErrorCode ierr; 1079 1080 PetscFunctionBegin; 1081 ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 1082 ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr); 1083 ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr); 1084 ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr); 1085 ierr = DMView(cdm, viewer);CHKERRQ(ierr); 1086 ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr); 1087 1088 ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr); 1089 ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr); 1090 for (p = 0; p < Np; ++p) { 1091 const PetscInt i = p*bs; 1092 1093 ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], 0.01, 0.01, PETSC_DRAW_BLUE);CHKERRQ(ierr); 1094 } 1095 ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr); 1096 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 1097 ierr = PetscDrawPause(draw);CHKERRQ(ierr); 1098 ierr = PetscDrawSave(draw);CHKERRQ(ierr); 1099 PetscFunctionReturn(0); 1100 } 1101 1102 #undef __FUNCT__ 1103 #define __FUNCT__ "DMView_Swarm" 1104 PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer) 1105 { 1106 DM_Swarm *swarm = (DM_Swarm*)dm->data; 1107 PetscBool iascii,ibinary,ishdf5,isvtk,isdraw; 1108 PetscErrorCode ierr; 1109 1110 PetscFunctionBegin; 1111 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1112 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1113 ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 1114 ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 1115 ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 1116 ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1117 ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 1118 if (iascii) { 1119 ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr); 1120 } else if (ibinary) { 1121 SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support"); 1122 } else if (ishdf5) { 1123 #if defined(PETSC_HAVE_HDF5) 1124 SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support"); 1125 #else 1126 SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5"); 1127 #endif 1128 } else if (isvtk) { 1129 SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support"); 1130 } else if (isdraw) { 1131 ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr); 1132 } 1133 PetscFunctionReturn(0); 1134 } 1135 1136 /*MC 1137 1138 DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type. 1139 This implementation was designed for particle-in-cell type methods in which the underlying 1140 data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type. 1141 1142 User data can be represented by DMSwarm through a registring "fields". 1143 To register a field, the user must provide: 1144 (a) a unique name 1145 (b) the data type (or size in bytes) 1146 (c) the block size of the data 1147 1148 For example, suppose the application requires a unique id, energy, momentum and density to be stored 1149 on a set of of particles. Then the following application could be used 1150 1151 DMSwarmInitializeFieldRegister(dm) 1152 DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG); 1153 DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL); 1154 DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL); 1155 DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT); 1156 DMSwarmFinalizeFieldRegister(dm) 1157 1158 The fields represented by DMSwarm are dynamic and can be re-sized at any time. 1159 The only restriction imposed by DMSwarm is that all fields contain the same number of points 1160 1161 To support particle methods, "migration" techniques are provided. These methods migrate data 1162 between MPI-ranks. 1163 1164 DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector(). 1165 As a DMSwarm may internally define and store values of different data types, 1166 before calling DMCreate{Global/Local}Vector() the user must inform DMSwarm which 1167 fields should be used to define a Vec object via 1168 DMSwarmVectorDefineField() 1169 The specified field can can changed be changed at any time - thereby permitting vectors 1170 compatable with different fields to be created. 1171 1172 A dual representation of fields in the DMSwarm and a Vec object are permitted via 1173 DMSwarmCreateGlobalVectorFromField() 1174 Here the data defining the field in the DMSwarm is shared with a Vec. 1175 This is inherently unsafe if you alter the size of the field at any time between 1176 calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField(). 1177 If the local size of the DMSwarm does not match the localsize of the global vector 1178 when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown. 1179 1180 Level: beginner 1181 1182 .seealso: DMType, DMCreate(), DMSetType() 1183 1184 M*/ 1185 #undef __FUNCT__ 1186 #define __FUNCT__ "DMCreate_Swarm" 1187 PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm) 1188 { 1189 DM_Swarm *swarm; 1190 PetscErrorCode ierr; 1191 1192 PetscFunctionBegin; 1193 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1194 ierr = PetscNewLog(dm,&swarm);CHKERRQ(ierr); 1195 dm->data = swarm; 1196 1197 ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr); 1198 ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr); 1199 1200 swarm->vec_field_set = PETSC_FALSE; 1201 swarm->issetup = PETSC_FALSE; 1202 swarm->swarm_type = DMSWARM_BASIC; 1203 swarm->migrate_type = DMSWARM_MIGRATE_BASIC; 1204 swarm->collect_type = DMSWARM_COLLECT_BASIC; 1205 swarm->migrate_error_on_missing_point = PETSC_FALSE; 1206 1207 swarm->dmcell = NULL; 1208 swarm->collect_view_active = PETSC_FALSE; 1209 swarm->collect_view_reset_nlocal = -1; 1210 1211 dm->dim = 0; 1212 dm->ops->view = DMView_Swarm; 1213 dm->ops->load = NULL; 1214 dm->ops->setfromoptions = NULL; 1215 dm->ops->clone = NULL; 1216 dm->ops->setup = DMSetup_Swarm; 1217 dm->ops->createdefaultsection = NULL; 1218 dm->ops->createdefaultconstraints = NULL; 1219 dm->ops->createglobalvector = DMCreateGlobalVector_Swarm; 1220 dm->ops->createlocalvector = DMCreateLocalVector_Swarm; 1221 dm->ops->getlocaltoglobalmapping = NULL; 1222 dm->ops->createfieldis = NULL; 1223 dm->ops->createcoordinatedm = NULL; 1224 dm->ops->getcoloring = NULL; 1225 dm->ops->creatematrix = NULL; 1226 dm->ops->createinterpolation = NULL; 1227 dm->ops->getaggregates = NULL; 1228 dm->ops->getinjection = NULL; 1229 dm->ops->refine = NULL; 1230 dm->ops->coarsen = NULL; 1231 dm->ops->refinehierarchy = NULL; 1232 dm->ops->coarsenhierarchy = NULL; 1233 dm->ops->globaltolocalbegin = NULL; 1234 dm->ops->globaltolocalend = NULL; 1235 dm->ops->localtoglobalbegin = NULL; 1236 dm->ops->localtoglobalend = NULL; 1237 dm->ops->destroy = DMDestroy_Swarm; 1238 dm->ops->createsubdm = NULL; 1239 dm->ops->getdimpoints = NULL; 1240 dm->ops->locatepoints = NULL; 1241 1242 PetscFunctionReturn(0); 1243 } 1244