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 ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr); 488 489 /* Load a specific data type into data bucket, specifying textual name and its size in bytes */ 490 ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr); 491 { 492 DataField gfield; 493 494 ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 495 ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr); 496 } 497 swarm->db->field[swarm->db->nfields-1]->petsc_type = type; 498 499 PetscFunctionReturn(0); 500 } 501 502 /*@C 503 504 DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm 505 506 Collective on DM 507 508 Input parameters: 509 . dm - a DMSwarm 510 . fieldname - the textual name to identify this field 511 . size - the size in bytes of the user struct of each data type 512 513 Level: beginner 514 515 Notes: 516 The textual name for each registered field must be unique 517 518 . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField() 519 520 @*/ 521 #undef __FUNCT__ 522 #define __FUNCT__ "DMSwarmRegisterUserStructField" 523 PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size) 524 { 525 PetscErrorCode ierr; 526 DM_Swarm *swarm = (DM_Swarm*)dm->data; 527 528 ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr); 529 swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ; 530 531 PetscFunctionReturn(0); 532 } 533 534 /*@C 535 536 DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm 537 538 Collective on DM 539 540 Input parameters: 541 . dm - a DMSwarm 542 . fieldname - the textual name to identify this field 543 . size - the size in bytes of the user data type 544 . blocksize - the number of each data type 545 546 Level: beginner 547 548 Notes: 549 The textual name for each registered field must be unique 550 551 . seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 552 553 @*/ 554 #undef __FUNCT__ 555 #define __FUNCT__ "DMSwarmRegisterUserDatatypeField" 556 PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize) 557 { 558 DM_Swarm *swarm = (DM_Swarm*)dm->data; 559 PetscErrorCode ierr; 560 561 ierr = DataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr); 562 { 563 DataField gfield; 564 565 ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 566 ierr = DataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr); 567 } 568 swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN; 569 570 PetscFunctionReturn(0); 571 } 572 573 /*@C 574 575 DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field 576 577 Not collective 578 579 Input parameters: 580 . dm - a DMSwarm 581 . fieldname - the textual name to identify this field 582 583 Output parameters: 584 . blocksize - the number of each data type 585 . type - the data type 586 . data - pointer to raw array 587 588 Level: beginner 589 590 Notes: 591 The user must call DMSwarmRestoreField() 592 593 . seealso: DMSwarmRestoreField() 594 595 @*/ 596 #undef __FUNCT__ 597 #define __FUNCT__ "DMSwarmGetField" 598 PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 599 { 600 DM_Swarm *swarm = (DM_Swarm*)dm->data; 601 DataField gfield; 602 PetscErrorCode ierr; 603 604 if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 605 606 ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 607 ierr = DataFieldGetAccess(gfield);CHKERRQ(ierr); 608 ierr = DataFieldGetEntries(gfield,data);CHKERRQ(ierr); 609 if (blocksize) {*blocksize = gfield->bs; } 610 if (type) { *type = gfield->petsc_type; } 611 612 PetscFunctionReturn(0); 613 } 614 615 /*@C 616 617 DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field 618 619 Not collective 620 621 Input parameters: 622 . dm - a DMSwarm 623 . fieldname - the textual name to identify this field 624 625 Output parameters: 626 . blocksize - the number of each data type 627 . type - the data type 628 . data - pointer to raw array 629 630 Level: beginner 631 632 Notes: 633 The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField() 634 635 . seealso: DMSwarmGetField() 636 637 @*/ 638 #undef __FUNCT__ 639 #define __FUNCT__ "DMSwarmRestoreField" 640 PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 641 { 642 DM_Swarm *swarm = (DM_Swarm*)dm->data; 643 DataField gfield; 644 PetscErrorCode ierr; 645 646 ierr = DataBucketGetDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 647 ierr = DataFieldRestoreAccess(gfield);CHKERRQ(ierr); 648 if (data) *data = NULL; 649 650 PetscFunctionReturn(0); 651 } 652 653 /*@C 654 655 DMSwarmAddPoint - Add space for one new point in the DMSwarm 656 657 Not collective 658 659 Input parameter: 660 . dm - a DMSwarm 661 662 Level: beginner 663 664 Notes: 665 The new point will have all fields initialized to zero 666 667 . seealso: DMSwarmAddNPoints() 668 669 @*/ 670 #undef __FUNCT__ 671 #define __FUNCT__ "DMSwarmAddPoint" 672 PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm) 673 { 674 DM_Swarm *swarm = (DM_Swarm*)dm->data; 675 PetscErrorCode ierr; 676 677 if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 678 ierr = DataBucketAddPoint(swarm->db);CHKERRQ(ierr); 679 PetscFunctionReturn(0); 680 } 681 682 /*@C 683 684 DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm 685 686 Not collective 687 688 Input parameters: 689 . dm - a DMSwarm 690 . npoints - the number of new points to add 691 692 Level: beginner 693 694 Notes: 695 The new point will have all fields initialized to zero 696 697 . seealso: DMSwarmAddPoint() 698 699 @*/ 700 #undef __FUNCT__ 701 #define __FUNCT__ "DMSwarmAddNPoints" 702 PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints) 703 { 704 DM_Swarm *swarm = (DM_Swarm*)dm->data; 705 PetscErrorCode ierr; 706 PetscInt nlocal; 707 708 ierr = DataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr); 709 nlocal = nlocal + npoints; 710 ierr = DataBucketSetSizes(swarm->db,nlocal,-1);CHKERRQ(ierr); 711 PetscFunctionReturn(0); 712 } 713 714 /*@C 715 716 DMSwarmRemovePoint - Remove the last point from the DMSwarm 717 718 Not collective 719 720 Input parameter: 721 . dm - a DMSwarm 722 723 Level: beginner 724 725 . seealso: DMSwarmRemovePointAtIndex() 726 727 @*/ 728 #undef __FUNCT__ 729 #define __FUNCT__ "DMSwarmRemovePoint" 730 PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm) 731 { 732 DM_Swarm *swarm = (DM_Swarm*)dm->data; 733 PetscErrorCode ierr; 734 735 ierr = DataBucketRemovePoint(swarm->db);CHKERRQ(ierr); 736 PetscFunctionReturn(0); 737 } 738 739 /*@C 740 741 DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm 742 743 Not collective 744 745 Input parameters: 746 . dm - a DMSwarm 747 . idx - index of point to remove 748 749 Level: beginner 750 751 . seealso: DMSwarmRemovePoint() 752 753 @*/ 754 #undef __FUNCT__ 755 #define __FUNCT__ "DMSwarmRemovePointAtIndex" 756 PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx) 757 { 758 DM_Swarm *swarm = (DM_Swarm*)dm->data; 759 PetscErrorCode ierr; 760 761 ierr = DataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr); 762 PetscFunctionReturn(0); 763 } 764 765 #undef __FUNCT__ 766 #define __FUNCT__ "DMSwarmMigrate_Basic" 767 PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points) 768 { 769 PetscErrorCode ierr; 770 ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr); 771 PetscFunctionReturn(0); 772 } 773 774 PetscErrorCode DMSwarmMigrate_CellDMScatter(DM dm,PetscBool remove_sent_points); 775 PetscErrorCode DMSwarmMigrate_CellDMExact(DM dm,PetscBool remove_sent_points); 776 777 /*@C 778 779 DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks 780 781 Collective on DM 782 783 Input parameters: 784 . dm - the DMSwarm 785 . remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank 786 787 Notes: 788 The DM wil be modified to accomodate received points. 789 If remove_sent_points = PETSC_TRUE, send points will be removed from the DM 790 Different styles of migration are supported. See DMSwarmSetMigrateType() 791 792 Level: advanced 793 794 . seealso: DMSwarmSetMigrateType() 795 796 @*/ 797 #undef __FUNCT__ 798 #define __FUNCT__ "DMSwarmMigrate" 799 PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points) 800 { 801 DM_Swarm *swarm = (DM_Swarm*)dm->data; 802 PetscErrorCode ierr; 803 804 switch (swarm->migrate_type) { 805 806 case DMSWARM_MIGRATE_BASIC: 807 ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr); 808 break; 809 810 case DMSWARM_MIGRATE_DMCELLNSCATTER: 811 ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr); 812 break; 813 814 case DMSWARM_MIGRATE_DMCELLEXACT: 815 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented"); 816 //ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr); 817 break; 818 819 case DMSWARM_MIGRATE_USER: 820 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented"); 821 //ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr); 822 break; 823 824 default: 825 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown"); 826 break; 827 } 828 PetscFunctionReturn(0); 829 } 830 831 PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize); 832 833 /* 834 DMSwarmCollectViewCreate 835 836 * Applies a collection method and gathers point neighbour points into dm 837 838 Notes: 839 - Users should call DMSwarmCollectViewDestroy() after 840 they have finished computations associated with the collected points 841 */ 842 843 /*@C 844 845 DMSwarmCollectViewCreate - Applies a collection method and gathers points 846 in neighbour MPI-ranks into the DMSwarm 847 848 Collective on DM 849 850 Input parameter: 851 . dm - the DMSwarm 852 853 Notes: 854 Users should call DMSwarmCollectViewDestroy() after 855 they have finished computations associated with the collected points 856 Different collect methods are supported. See DMSwarmSetCollectType() 857 858 Level: advanced 859 860 . seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType() 861 862 @*/ 863 #undef __FUNCT__ 864 #define __FUNCT__ "DMSwarmCollectViewCreate" 865 PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm) 866 { 867 PetscErrorCode ierr; 868 DM_Swarm *swarm = (DM_Swarm*)dm->data; 869 PetscInt ng; 870 871 if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active"); 872 873 ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr); 874 switch (swarm->collect_type) { 875 876 case DMSWARM_COLLECT_BASIC: 877 ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr); 878 break; 879 880 case DMSWARM_COLLECT_DMDABOUNDINGBOX: 881 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented"); 882 //ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr); 883 break; 884 885 case DMSWARM_COLLECT_GENERAL: 886 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented"); 887 //ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr); 888 break; 889 890 default: 891 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown"); 892 break; 893 } 894 895 swarm->collect_view_active = PETSC_TRUE; 896 swarm->collect_view_reset_nlocal = ng; 897 898 PetscFunctionReturn(0); 899 } 900 901 /*@C 902 903 DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate() 904 905 Collective on DM 906 907 Input parameters: 908 . dm - the DMSwarm 909 910 Notes: 911 Users should call DMSwarmCollectViewCreate() before this function is called. 912 913 Level: advanced 914 915 . seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType() 916 917 @*/ 918 #undef __FUNCT__ 919 #define __FUNCT__ "DMSwarmCollectViewDestroy" 920 PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm) 921 { 922 PetscErrorCode ierr; 923 DM_Swarm *swarm = (DM_Swarm*)dm->data; 924 925 if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active"); 926 ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr); 927 swarm->collect_view_active = PETSC_FALSE; 928 929 PetscFunctionReturn(0); 930 } 931 932 #undef __FUNCT__ 933 #define __FUNCT__ "DMSwarmSetUpPIC" 934 PetscErrorCode DMSwarmSetUpPIC(DM dm) 935 { 936 PetscInt dim; 937 PetscErrorCode ierr; 938 939 ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 940 if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim); 941 if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim); 942 ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr); 943 PetscFunctionReturn(0); 944 } 945 946 /*@C 947 948 DMSwarmSetType - Set particular flavor of DMSwarm 949 950 Collective on DM 951 952 Input parameters: 953 . dm - the DMSwarm 954 . stype - the DMSwarm type (e.g. DMSWARM_PIC) 955 956 Level: advanced 957 958 . seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType() 959 960 @*/ 961 #undef __FUNCT__ 962 #define __FUNCT__ "DMSwarmSetType" 963 PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype) 964 { 965 DM_Swarm *swarm = (DM_Swarm*)dm->data; 966 PetscErrorCode ierr; 967 968 swarm->swarm_type = stype; 969 if (swarm->swarm_type == DMSWARM_PIC) { 970 ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr); 971 } 972 PetscFunctionReturn(0); 973 } 974 975 #undef __FUNCT__ 976 #define __FUNCT__ "DMSetup_Swarm" 977 PetscErrorCode DMSetup_Swarm(DM dm) 978 { 979 DM_Swarm *swarm = (DM_Swarm*)dm->data; 980 PetscErrorCode ierr; 981 PetscMPIInt rank; 982 PetscInt p,npoints,*rankval; 983 984 if (swarm->issetup) PetscFunctionReturn(0); 985 986 swarm->issetup = PETSC_TRUE; 987 988 if (swarm->swarm_type == DMSWARM_PIC) { 989 /* check dmcell exists */ 990 if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM"); 991 992 if (swarm->dmcell->ops->locatepointssubdomain) { 993 /* check methods exists for exact ownership identificiation */ 994 PetscPrintf(PetscObjectComm((PetscObject)dm)," DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n"); 995 swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT; 996 } else { 997 /* check methods exist for point location AND rank neighbor identification */ 998 if (swarm->dmcell->ops->locatepoints) { 999 PetscPrintf(PetscObjectComm((PetscObject)dm)," DMSWARM_PIC: Using method CellDM->LocatePoints\n"); 1000 } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined"); 1001 1002 if (swarm->dmcell->ops->getneighbors) { 1003 PetscPrintf(PetscObjectComm((PetscObject)dm)," DMSWARM_PIC: Using method CellDM->GetNeigbors\n"); 1004 } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined"); 1005 1006 swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER; 1007 } 1008 } 1009 1010 ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr); 1011 1012 /* check some fields were registered */ 1013 if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()"); 1014 1015 /* check local sizes were set */ 1016 if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()"); 1017 1018 /* initialize values in pid and rank placeholders */ 1019 /* TODO: [pid - use MPI_Scan] */ 1020 1021 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 1022 ierr = DataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr); 1023 ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr); 1024 for (p=0; p<npoints; p++) { 1025 rankval[p] = (PetscInt)rank; 1026 } 1027 ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr); 1028 1029 PetscFunctionReturn(0); 1030 } 1031 1032 #undef __FUNCT__ 1033 #define __FUNCT__ "DMDestroy_Swarm" 1034 PetscErrorCode DMDestroy_Swarm(DM dm) 1035 { 1036 DM_Swarm *swarm = (DM_Swarm*)dm->data; 1037 PetscErrorCode ierr; 1038 1039 PetscFunctionBegin; 1040 ierr = DataBucketDestroy(&swarm->db);CHKERRQ(ierr); 1041 ierr = PetscFree(swarm);CHKERRQ(ierr); 1042 PetscFunctionReturn(0); 1043 } 1044 1045 #undef __FUNCT__ 1046 #define __FUNCT__ "DMView_Swarm" 1047 PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer) 1048 { 1049 DM_Swarm *swarm = (DM_Swarm*)dm->data; 1050 PetscBool iascii,ibinary,ishdf5,isvtk; 1051 PetscErrorCode ierr; 1052 1053 PetscFunctionBegin; 1054 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1055 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1056 ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 1057 ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 1058 ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 1059 ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1060 if (iascii) { 1061 ierr = DataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr); 1062 } else if (ibinary) { 1063 SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support"); 1064 } else if (ishdf5) { 1065 #if defined(PETSC_HAVE_HDF5) 1066 SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support"); 1067 #else 1068 SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5"); 1069 #endif 1070 } else if (isvtk) { 1071 SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support"); 1072 } 1073 PetscFunctionReturn(0); 1074 } 1075 1076 /*MC 1077 1078 DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type. 1079 This implementation was designed for particle-in-cell type methods in which the underlying 1080 data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type. 1081 1082 User data can be represented by DMSwarm through a registring "fields". 1083 To register a field, the user must provide: 1084 (a) a unique name 1085 (b) the data type (or size in bytes) 1086 (c) the block size of the data 1087 1088 For example, suppose the application requires a unique id, energy, momentum and density to be stored 1089 on a set of of particles. Then the following application could be used 1090 1091 DMSwarmInitializeFieldRegister(dm) 1092 DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG); 1093 DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL); 1094 DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL); 1095 DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT); 1096 DMSwarmFinalizeFieldRegister(dm) 1097 1098 The fields represented by DMSwarm are dynamic and can be re-sized at any time. 1099 The only restriction imposed by DMSwarm is that all fields contain the same number of points 1100 1101 To support particle methods, "migration" techniques are provided. These methods migrate data 1102 between MPI-ranks. 1103 1104 DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector(). 1105 As a DMSwarm may internally define and store values of different data types, 1106 before calling DMCreate{Global/Local}Vector() the user must inform DMSwarm which 1107 fields should be used to define a Vec object via 1108 DMSwarmVectorDefineField() 1109 The specified field can can changed be changed at any time - thereby permitting vectors 1110 compatable with different fields to be created. 1111 1112 A dual representation of fields in the DMSwarm and a Vec object are permitted via 1113 DMSwarmCreateGlobalVectorFromField() 1114 Here the data defining the field in the DMSwarm is shared with a Vec. 1115 This is inherently unsafe if you alter the size of the field at any time between 1116 calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField(). 1117 If the local size of the DMSwarm does not match the localsize of the global vector 1118 when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown. 1119 1120 Level: beginner 1121 1122 .seealso: DMType, DMCreate(), DMSetType() 1123 1124 M*/ 1125 #undef __FUNCT__ 1126 #define __FUNCT__ "DMCreate_Swarm" 1127 PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm) 1128 { 1129 DM_Swarm *swarm; 1130 PetscErrorCode ierr; 1131 1132 PetscFunctionBegin; 1133 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1134 ierr = PetscNewLog(dm,&swarm);CHKERRQ(ierr); 1135 dm->data = swarm; 1136 1137 ierr = DataBucketCreate(&swarm->db);CHKERRQ(ierr); 1138 ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr); 1139 1140 swarm->vec_field_set = PETSC_FALSE; 1141 swarm->issetup = PETSC_FALSE; 1142 swarm->swarm_type = DMSWARM_BASIC; 1143 swarm->migrate_type = DMSWARM_MIGRATE_BASIC; 1144 swarm->collect_type = DMSWARM_COLLECT_BASIC; 1145 swarm->migrate_error_on_missing_point = PETSC_FALSE; 1146 1147 swarm->dmcell = NULL; 1148 swarm->collect_view_active = PETSC_FALSE; 1149 swarm->collect_view_reset_nlocal = -1; 1150 1151 dm->dim = 0; 1152 dm->ops->view = DMView_Swarm; 1153 dm->ops->load = NULL; 1154 dm->ops->setfromoptions = NULL; 1155 dm->ops->clone = NULL; 1156 dm->ops->setup = DMSetup_Swarm; 1157 dm->ops->createdefaultsection = NULL; 1158 dm->ops->createdefaultconstraints = NULL; 1159 dm->ops->createglobalvector = DMCreateGlobalVector_Swarm; 1160 dm->ops->createlocalvector = DMCreateLocalVector_Swarm; 1161 dm->ops->getlocaltoglobalmapping = NULL; 1162 dm->ops->createfieldis = NULL; 1163 dm->ops->createcoordinatedm = NULL; 1164 dm->ops->getcoloring = NULL; 1165 dm->ops->creatematrix = NULL; 1166 dm->ops->createinterpolation = NULL; 1167 dm->ops->getaggregates = NULL; 1168 dm->ops->getinjection = NULL; 1169 dm->ops->refine = NULL; 1170 dm->ops->coarsen = NULL; 1171 dm->ops->refinehierarchy = NULL; 1172 dm->ops->coarsenhierarchy = NULL; 1173 dm->ops->globaltolocalbegin = NULL; 1174 dm->ops->globaltolocalend = NULL; 1175 dm->ops->localtoglobalbegin = NULL; 1176 dm->ops->localtoglobalend = NULL; 1177 dm->ops->destroy = DMDestroy_Swarm; 1178 dm->ops->createsubdm = NULL; 1179 dm->ops->getdimpoints = NULL; 1180 dm->ops->locatepoints = NULL; 1181 1182 PetscFunctionReturn(0); 1183 }