1 static char help[] = "Example usage of extracting single cells with their associated fields from a swarm and putting it in a new swarm object\n"; 2 3 #include <petscdmplex.h> 4 #include <petscdmswarm.h> 5 #include <petscts.h> 6 7 typedef struct { 8 PetscInt particlesPerCell; /* The number of partices per cell */ 9 } AppCtx; 10 11 static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 12 { 13 PetscErrorCode ierr; 14 15 PetscFunctionBeginUser; 16 options->particlesPerCell = 1; 17 18 ierr = PetscOptionsBegin(comm, "", "CellSwarm Options", "DMSWARM");CHKERRQ(ierr); 19 CHKERRQ(PetscOptionsInt("-particles_per_cell", "Number of particles per cell", "ex3.c", options->particlesPerCell, &options->particlesPerCell, NULL)); 20 ierr = PetscOptionsEnd();CHKERRQ(ierr); 21 PetscFunctionReturn(0); 22 } 23 24 static PetscErrorCode CreateMesh(MPI_Comm comm, DM *dm, AppCtx *user) 25 { 26 PetscFunctionBeginUser; 27 CHKERRQ(DMCreate(comm, dm)); 28 CHKERRQ(DMSetType(*dm, DMPLEX)); 29 CHKERRQ(DMSetFromOptions(*dm)); 30 CHKERRQ(DMViewFromOptions(*dm, NULL, "-dm_view")); 31 PetscFunctionReturn(0); 32 } 33 34 static PetscErrorCode CreateParticles(DM dm, DM *sw, AppCtx *user) 35 { 36 PetscInt *cellid; 37 PetscInt dim, cStart, cEnd, c, Np = user->particlesPerCell, p; 38 39 PetscFunctionBeginUser; 40 CHKERRQ(DMGetDimension(dm, &dim)); 41 CHKERRQ(DMCreate(PetscObjectComm((PetscObject) dm), sw)); 42 CHKERRQ(DMSetType(*sw, DMSWARM)); 43 CHKERRQ(DMSetDimension(*sw, dim)); 44 CHKERRQ(DMSwarmSetType(*sw, DMSWARM_PIC)); 45 CHKERRQ(DMSwarmSetCellDM(*sw, dm)); 46 CHKERRQ(DMSwarmRegisterPetscDatatypeField(*sw, "kinematics", 2, PETSC_REAL)); 47 CHKERRQ(DMSwarmFinalizeFieldRegister(*sw)); 48 CHKERRQ(DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd)); 49 CHKERRQ(DMSwarmSetLocalSizes(*sw, (cEnd - cStart) * Np, 0)); 50 CHKERRQ(DMSetFromOptions(*sw)); 51 CHKERRQ(DMSwarmGetField(*sw, DMSwarmPICField_cellid, NULL, NULL, (void **) &cellid)); 52 for (c = cStart; c < cEnd; ++c) { 53 for (p = 0; p < Np; ++p) { 54 const PetscInt n = c*Np + p; 55 56 cellid[n] = c; 57 } 58 } 59 CHKERRQ(DMSwarmRestoreField(*sw, DMSwarmPICField_cellid, NULL, NULL, (void **) &cellid)); 60 CHKERRQ(PetscObjectSetName((PetscObject) *sw, "Particles")); 61 CHKERRQ(DMViewFromOptions(*sw, NULL, "-sw_view")); 62 PetscFunctionReturn(0); 63 } 64 65 int main(int argc,char **argv) 66 { 67 DM dm, sw, cellsw; /* Mesh and particle managers */ 68 MPI_Comm comm; 69 AppCtx user; 70 71 CHKERRQ(PetscInitialize(&argc, &argv, NULL, help)); 72 comm = PETSC_COMM_WORLD; 73 CHKERRQ(ProcessOptions(comm, &user)); 74 CHKERRQ(CreateMesh(comm, &dm, &user)); 75 CHKERRQ(CreateParticles(dm, &sw, &user)); 76 CHKERRQ(DMSetApplicationContext(sw, &user)); 77 CHKERRQ(DMCreate(comm, &cellsw)); 78 CHKERRQ(DMSwarmGetCellSwarm(sw, 1, cellsw)); 79 CHKERRQ(DMViewFromOptions(cellsw, NULL, "-subswarm_view")); 80 CHKERRQ(DMSwarmRestoreCellSwarm(sw, 1, cellsw)); 81 CHKERRQ(DMDestroy(&sw)); 82 CHKERRQ(DMDestroy(&dm)); 83 CHKERRQ(DMDestroy(&cellsw)); 84 CHKERRQ(PetscFinalize()); 85 return 0; 86 } 87 88 /*TEST 89 build: 90 requires: triangle !single !complex 91 test: 92 suffix: 1 93 args: -particles_per_cell 2 -dm_plex_box_faces 2,1 -dm_view -sw_view -subswarm_view 94 TEST*/ 95