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