Actual source code: ex3.c

  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";

  3: #include <petscdmplex.h>
  4: #include <petscdmswarm.h>
  5: #include <petscts.h>

  7: typedef struct {
  8:   PetscInt particlesPerCell; /* The number of partices per cell */
  9: } AppCtx;

 11: static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
 12: {
 14:   options->particlesPerCell = 1;

 16:   PetscOptionsBegin(comm, "", "CellSwarm Options", "DMSWARM");
 17:   PetscOptionsInt("-particles_per_cell", "Number of particles per cell", "ex3.c", options->particlesPerCell, &options->particlesPerCell, NULL);
 18:   PetscOptionsEnd();
 19:   return 0;
 20: }

 22: static PetscErrorCode CreateMesh(MPI_Comm comm, DM *dm, AppCtx *user)
 23: {
 25:   DMCreate(comm, dm);
 26:   DMSetType(*dm, DMPLEX);
 27:   DMSetFromOptions(*dm);
 28:   DMViewFromOptions(*dm, NULL, "-dm_view");
 29:   return 0;
 30: }

 32: static PetscErrorCode CreateParticles(DM dm, DM *sw, AppCtx *user)
 33: {
 34:   PetscInt *cellid;
 35:   PetscInt  dim, cStart, cEnd, c, Np = user->particlesPerCell, p;

 38:   DMGetDimension(dm, &dim);
 39:   DMCreate(PetscObjectComm((PetscObject)dm), sw);
 40:   DMSetType(*sw, DMSWARM);
 41:   DMSetDimension(*sw, dim);
 42:   DMSwarmSetType(*sw, DMSWARM_PIC);
 43:   DMSwarmSetCellDM(*sw, dm);
 44:   DMSwarmRegisterPetscDatatypeField(*sw, "kinematics", 2, PETSC_REAL);
 45:   DMSwarmFinalizeFieldRegister(*sw);
 46:   DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
 47:   DMSwarmSetLocalSizes(*sw, (cEnd - cStart) * Np, 0);
 48:   DMSetFromOptions(*sw);
 49:   DMSwarmGetField(*sw, DMSwarmPICField_cellid, NULL, NULL, (void **)&cellid);
 50:   for (c = cStart; c < cEnd; ++c) {
 51:     for (p = 0; p < Np; ++p) {
 52:       const PetscInt n = c * Np + p;

 54:       cellid[n] = c;
 55:     }
 56:   }
 57:   DMSwarmRestoreField(*sw, DMSwarmPICField_cellid, NULL, NULL, (void **)&cellid);
 58:   PetscObjectSetName((PetscObject)*sw, "Particles");
 59:   DMViewFromOptions(*sw, NULL, "-sw_view");
 60:   return 0;
 61: }

 63: int main(int argc, char **argv)
 64: {
 65:   DM       dm, sw, cellsw; /* Mesh and particle managers */
 66:   MPI_Comm comm;
 67:   AppCtx   user;

 70:   PetscInitialize(&argc, &argv, NULL, help);
 71:   comm = PETSC_COMM_WORLD;
 72:   ProcessOptions(comm, &user);
 73:   CreateMesh(comm, &dm, &user);
 74:   CreateParticles(dm, &sw, &user);
 75:   DMSetApplicationContext(sw, &user);
 76:   DMCreate(comm, &cellsw);
 77:   PetscObjectSetName((PetscObject)cellsw, "SubParticles");
 78:   DMSwarmGetCellSwarm(sw, 1, cellsw);
 79:   DMViewFromOptions(cellsw, NULL, "-subswarm_view");
 80:   DMSwarmRestoreCellSwarm(sw, 1, cellsw);
 81:   DMDestroy(&sw);
 82:   DMDestroy(&dm);
 83:   DMDestroy(&cellsw);
 84:   PetscFinalize();
 85:   return 0;
 86: }

 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*/