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