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