static char help[] = "Test periodic DMDA for DMSwarm point location.\n"; #include #include typedef struct { PetscInt dim; // Mesh dimension PetscInt Np; // Number of particles along each dimension } UserContext; static PetscErrorCode ProcessOptions(UserContext *options) { PetscFunctionBeginUser; options->dim = 3; options->Np = -1; PetscCall(PetscOptionsGetInt(NULL, NULL, "-dim", &options->dim, NULL)); PetscCall(PetscOptionsGetInt(NULL, NULL, "-np", &options->Np, NULL)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode CreateMesh(DM *da, UserContext *user) { PetscReal gmin[3] = {0, 0., 0.}, gmax[3] = {0, 0., 0.}; PetscFunctionBeginUser; PetscCall(DMDACreate(PETSC_COMM_WORLD, da)); PetscCall(DMSetDimension(*da, user->dim)); PetscCall(DMDASetSizes(*da, 7, 7, 7)); PetscCall(DMDASetBoundaryType(*da, DM_BOUNDARY_GHOSTED, DM_BOUNDARY_GHOSTED, DM_BOUNDARY_GHOSTED)); PetscCall(DMDASetDof(*da, 2)); PetscCall(DMDASetStencilType(*da, DMDA_STENCIL_BOX)); PetscCall(DMDASetStencilWidth(*da, 1)); PetscCall(DMDASetElementType(*da, DMDA_ELEMENT_Q1)); PetscCall(DMSetFromOptions(*da)); PetscCall(DMSetUp(*da)); PetscCall(DMDASetUniformCoordinates(*da, 0., 1., 0., 1., 0., 1.)); PetscCall(DMSetApplicationContext(*da, user)); PetscCall(DMView(*da, PETSC_VIEWER_STDOUT_WORLD)); PetscCall(DMGetBoundingBox(*da, gmin, gmax)); PetscCall(PetscPrintf(PETSC_COMM_WORLD, "min: (%g, %g, %g) max: (%g, %g, %g)\n", gmin[0], gmin[1], gmin[2], gmax[0], gmax[1], gmax[2])); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode CreateSwarm(DM mesh, DM *swarm, UserContext *user) { MPI_Comm comm; PetscMPIInt size; PetscInt dim; PetscFunctionBeginUser; PetscCall(PetscObjectGetComm((PetscObject)mesh, &comm)); PetscCallMPI(MPI_Comm_size(comm, &size)); PetscCall(DMCreate(comm, swarm)); PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*swarm, "pic_")); PetscCall(DMSetType(*swarm, DMSWARM)); PetscCall(PetscObjectSetName((PetscObject)*swarm, "ions")); PetscCall(DMGetDimension(mesh, &dim)); PetscCall(DMSetDimension(*swarm, dim)); PetscCall(DMSwarmSetType(*swarm, DMSWARM_PIC)); PetscCall(DMSwarmSetCellDM(*swarm, mesh)); PetscCall(DMSwarmInitializeFieldRegister(*swarm)); PetscCall(DMSwarmFinalizeFieldRegister(*swarm)); PetscCall(DMSwarmSetLocalSizes(*swarm, user->Np / size, 0)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode InitializeParticles(DM sw, UserContext *user) { DM da; PetscReal gmin[3], gmax[3]; PetscInt ndir[3]; PetscFunctionBeginUser; PetscCall(DMSwarmGetCellDM(sw, &da)); PetscCall(DMGetBoundingBox(da, gmin, gmax)); ndir[0] = user->Np; ndir[1] = user->Np; ndir[2] = user->Np; PetscCall(DMSwarmSetPointsUniformCoordinates(sw, gmin, gmax, ndir, INSERT_VALUES)); PetscFunctionReturn(PETSC_SUCCESS); } int main(int argc, char **args) { DM dm, sw; UserContext user; PetscFunctionBeginUser; PetscCall(PetscInitialize(&argc, &args, NULL, help)); PetscCall(ProcessOptions(&user)); PetscCall(CreateMesh(&dm, &user)); PetscCall(CreateSwarm(dm, &sw, &user)); PetscCall(InitializeParticles(sw, &user)); PetscCall(DMSwarmMigrate(sw, PETSC_TRUE)); PetscCall(DMViewFromOptions(sw, NULL, "-sw_view")); PetscCall(DMDestroy(&dm)); PetscCall(DMDestroy(&sw)); PetscCall(PetscFinalize()); return 0; } // ./dmswarm-coords -nx 8 -ny 8 -np 4 -pic_sw_view -dim 2 -periodic 0 // ./dmswarm-coords -nx 8 -ny 8 -np 4 -pic_sw_view -dim 2 -periodic 1 // ./dmswarm-coords -nx 8 -ny 8 -nz 8 -np 4 -pic_sw_view -dim 3 -periodic 0 // ./dmswarm-coords -nx 8 -ny 8 -nz 8 -np 4 -pic_sw_view -dim 3 -periodic 1 /*TEST build: requires: double !complex testset: suffix: 2d args: -dim 2 -da_grid_x 8 -da_grid_y 8 -np 4 -da_bd_all {{none periodic}} -pic_sw_view test: suffix: p1 test: suffix: p2 nsize: 2 test: suffix: p4 nsize: 4 testset: suffix: 3d args: -dim 3 -da_grid_x 8 -da_grid_y 8 -da_grid_z 8 -np 4 -da_bd_all {{none periodic}} -pic_sw_view test: suffix: p1 test: suffix: p2 nsize: 2 test: suffix: p4 nsize: 4 TEST*/