1 static char help[] = "Tests for particle initialization using the KS test\n\n"; 2 3 #include <petscdmswarm.h> 4 #include <petscdmplex.h> 5 #include <petsc/private/petscfeimpl.h> 6 7 /* 8 View the KS test using 9 10 -ks_monitor draw -draw_size 500,500 -draw_pause 3 11 12 Set total number to n0 / Mp = 3e14 / 1e12 = 300 using -dm_swarm_num_particles 300 13 14 */ 15 16 #define BOLTZMANN_K 1.380649e-23 /* J/K */ 17 18 typedef struct { 19 PetscReal mass[2]; /* Electron, Sr+ Mass [kg] */ 20 PetscReal T[2]; /* Electron, Ion Temperature [K] */ 21 PetscReal v0[2]; /* Species mean velocity in 1D */ 22 } AppCtx; 23 24 PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) { 25 PetscFunctionBegin; 26 options->mass[0] = 9.10938356e-31; /* Electron Mass [kg] */ 27 options->mass[1] = 87.62 * 1.66054e-27; /* Sr+ Mass [kg] */ 28 options->T[0] = 1.; /* Electron Temperature [K] */ 29 options->T[1] = 25.; /* Sr+ Temperature [K] */ 30 options->v0[0] = PetscSqrtReal(BOLTZMANN_K * options->T[0] / options->mass[0]); /* electron mean velocity in 1D */ 31 options->v0[1] = PetscSqrtReal(BOLTZMANN_K * options->T[1] / options->mass[1]); /* ion mean velocity in 1D */ 32 33 PetscOptionsBegin(comm, "", "KS Test Options", "DMPLEX"); 34 PetscOptionsEnd(); 35 PetscFunctionReturn(0); 36 } 37 38 static PetscErrorCode CreateMesh(MPI_Comm comm, DM *dm) { 39 PetscFunctionBeginUser; 40 PetscCall(DMCreate(comm, dm)); 41 PetscCall(DMSetType(*dm, DMPLEX)); 42 PetscCall(DMSetFromOptions(*dm)); 43 PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view")); 44 PetscFunctionReturn(0); 45 } 46 47 static PetscErrorCode CreateSwarm(DM dm, AppCtx *user, DM *sw) { 48 PetscInt dim; 49 50 PetscFunctionBeginUser; 51 PetscCall(DMGetDimension(dm, &dim)); 52 PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), sw)); 53 PetscCall(DMSetType(*sw, DMSWARM)); 54 PetscCall(DMSetDimension(*sw, dim)); 55 PetscCall(DMSwarmSetType(*sw, DMSWARM_PIC)); 56 PetscCall(DMSwarmSetCellDM(*sw, dm)); 57 PetscCall(DMSwarmRegisterPetscDatatypeField(*sw, "w_q", 1, PETSC_SCALAR)); 58 PetscCall(DMSwarmRegisterPetscDatatypeField(*sw, "velocity", dim, PETSC_REAL)); 59 PetscCall(DMSwarmRegisterPetscDatatypeField(*sw, "species", 1, PETSC_INT)); 60 PetscCall(DMSwarmFinalizeFieldRegister(*sw)); 61 PetscCall(DMSwarmComputeLocalSizeFromOptions(*sw)); 62 PetscCall(DMSwarmInitializeCoordinates(*sw)); 63 PetscCall(DMSwarmInitializeVelocitiesFromOptions(*sw, user->v0)); 64 PetscCall(DMSetFromOptions(*sw)); 65 PetscCall(PetscObjectSetName((PetscObject)*sw, "Particles")); 66 PetscCall(DMViewFromOptions(*sw, NULL, "-swarm_view")); 67 PetscFunctionReturn(0); 68 } 69 70 static PetscErrorCode TestDistribution(DM sw, PetscReal confidenceLevel, AppCtx *user) { 71 Vec locv; 72 PetscProbFunc cdf; 73 PetscReal alpha; 74 PetscInt dim; 75 MPI_Comm comm; 76 77 PetscFunctionBeginUser; 78 PetscCall(PetscObjectGetComm((PetscObject)sw, &comm)); 79 PetscCall(DMGetDimension(sw, &dim)); 80 switch (dim) { 81 case 1: cdf = PetscCDFMaxwellBoltzmann1D; break; 82 case 2: cdf = PetscCDFMaxwellBoltzmann2D; break; 83 case 3: cdf = PetscCDFMaxwellBoltzmann3D; break; 84 default: SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Dimension %" PetscInt_FMT " not supported", dim); 85 } 86 PetscCall(DMSwarmCreateLocalVectorFromField(sw, "velocity", &locv)); 87 PetscCall(PetscProbComputeKSStatistic(locv, cdf, &alpha)); 88 PetscCall(DMSwarmDestroyLocalVectorFromField(sw, "velocity", &locv)); 89 if (alpha < confidenceLevel) PetscCall(PetscPrintf(comm, "The KS test accepts the null hypothesis at level %.2g\n", (double)confidenceLevel)); 90 else PetscCall(PetscPrintf(comm, "The KS test rejects the null hypothesis at level %.2g (%.2g)\n", (double)confidenceLevel, (double)alpha)); 91 PetscFunctionReturn(0); 92 } 93 94 int main(int argc, char **argv) { 95 DM dm, sw; 96 AppCtx user; 97 98 PetscFunctionBeginUser; 99 PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 100 PetscCall(ProcessOptions(PETSC_COMM_WORLD, &user)); 101 PetscCall(CreateMesh(PETSC_COMM_WORLD, &dm)); 102 PetscCall(CreateSwarm(dm, &user, &sw)); 103 PetscCall(TestDistribution(sw, 0.05, &user)); 104 PetscCall(DMDestroy(&sw)); 105 PetscCall(DMDestroy(&dm)); 106 PetscCall(PetscFinalize()); 107 return 0; 108 } 109 110 /*TEST 111 112 test: 113 suffix: 0 114 requires: ks !complex 115 args: -dm_plex_dim 1 -dm_plex_box_lower -1 -dm_plex_box_upper 1 -dm_swarm_num_particles 375 -dm_swarm_coordinate_density {{constant gaussian}} 116 117 TEST*/ 118