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