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