int main() { Particles * p; p = create_particles(); free_particles(p); return 0; }
void particle_system::update_particlesystem() { // Emitters. { std::map<int,particle_emitter*>::iterator end = id_to_emitter.end(); for (std::map<int,particle_emitter*>::iterator it = id_to_emitter.begin(); it != end; it++) { particle_emitter* p_e = (*it).second; std::map<int,particle_type*>::iterator pt_it = pt_manager.id_to_particletype.find(p_e->particle_type_id); if (pt_it != pt_manager.id_to_particletype.end()) { particle_type* p_t = (*pt_it).second; const int number = p_e->get_step_number(); for (int i = 1; i <= number; i++) { int x, y; p_e->get_point(x, y); create_particles(x, y, p_t, 1); } } } } // Handle life and death. for (std::list<particle_instance>::iterator it = pi_list.begin(); it !=pi_list.end(); it++) { // Decrease life. //TODO: When dying due to end of life (not due to destroyers), particles may be spawned. it->life_current--; if (it->life_current <= 0) { particle_type* pt = it->pt; pt->particle_count--; if (pt->particle_count <= 0 && !pt->alive) { // Particle type is no longer used, delete it. delete pt; } it = pi_list.erase(it); } } // Move particles. { std::list<particle_instance>::iterator end = pi_list.end(); for (std::list<particle_instance>::iterator it = pi_list.begin(); it !=end; it++) { it->x += it->vx; it->y += it->vy; // TODO: Implement direction and speed change. } } }
int main(int argc, char* argv[]) { if (MPI_Init(&argc, &argv) != MPI_SUCCESS) { std::cerr << "Couldn't initialize MPI." << std::endl; abort(); } MPI_Comm comm = MPI_COMM_WORLD; int rank = 0, comm_size = 0; if (MPI_Comm_rank(comm, &rank) != MPI_SUCCESS) { std::cerr << "Couldn't obtain MPI rank." << std::endl; abort(); } if (MPI_Comm_size(comm, &comm_size) != MPI_SUCCESS) { std::cerr << "Couldn't obtain size of MPI communicator." << std::endl; abort(); } float zoltan_version; if (Zoltan_Initialize(argc, argv, &zoltan_version) != ZOLTAN_OK) { std::cerr << "Zoltan_Initialize failed." << std::endl; abort(); } constexpr size_t nr_of_values = 100, max_nr_of_cells = 512; const unsigned int neighborhood_size = 1; const std::array<bool, 3> periodic = {{true, true, true}}; dccrg::Cartesian_Geometry::Parameters geom_params; geom_params.start = {{-3, -5, -7}}; geom_params.level_0_cell_length = {{7, 5, 3}}; for (size_t nr_cells = 1; nr_cells <= max_nr_of_cells; nr_cells *= 2) { Grid grid; const std::array<uint64_t, 3> nr_of_cells{{nr_cells, 1, 1}}; if ( not grid.initialize( nr_of_cells, comm, "RANDOM", neighborhood_size, 0, periodic[0], periodic[1], periodic[2] ) ) { std::cerr << __FILE__ << ":" << __LINE__ << ": Couldn't initialize grids." << std::endl; abort(); } if (not grid.set_geometry(geom_params)) { std::cerr << __FILE__ << "(" << __LINE__ << "): " << "Couldn't set geometry of grids." << std::endl; abort(); } grid.balance_load(); grid.update_copies_of_remote_neighbors(); const auto cell_ids = grid.get_cells(); create_particles(nr_of_values, cell_ids, grid); for (const auto& cell_id: cell_ids) { auto* const cell_data = grid[cell_id]; if (cell_data == nullptr) {abort();} bulk_value_getter(*cell_data) = 0; } pamhd::particle::accumulate( cell_ids, grid, [](Cell& cell)->pamhd::particle::Particles_Internal::data_type&{ return cell[pamhd::particle::Particles_Internal()]; }, [](pamhd::particle::Particle_Internal& particle) ->pamhd::particle::Position::data_type& { return particle[pamhd::particle::Position()]; }, [](Cell&, pamhd::particle::Particle_Internal& particle) ->pamhd::particle::Mass::data_type& { return particle[pamhd::particle::Mass()]; }, bulk_value_getter, list_bulk_value_getter, list_target_getter, accumulation_list_length_getter, accumulation_list_getter ); Cell::set_transfer_all(true, pamhd::particle::Nr_Accumulated_To_Cells()); grid.update_copies_of_remote_neighbors(); Cell::set_transfer_all(false, pamhd::particle::Nr_Accumulated_To_Cells()); allocate_accumulation_lists(grid); // transfer accumulated values between processes Cell::set_transfer_all(true, Accumulated_To_Cells()); grid.update_copies_of_remote_neighbors(); Cell::set_transfer_all(false, Accumulated_To_Cells()); accumulate_from_remote_neighbors(grid); // transform accumulated mass to mass density for (const auto& cell_id: cell_ids) { const auto cell_length = grid.geometry.get_length(cell_id); const auto volume = cell_length[0] * cell_length[1] * cell_length[2]; auto* const cell_data = grid[cell_id]; if (cell_data == nullptr) { std::cerr << __FILE__ << "(" << __LINE__ << ")" << std::endl; abort(); } (*cell_data)[Mass_Density()] /= volume; } const double norm = get_norm(cell_ids, grid, comm); if (norm > 1e-10) { if (rank == 0) { std::cerr << __FILE__ << ":" << __LINE__ << ": Norm is too large: " << norm << " with " << nr_cells << " cell(s)" << std::endl; } MPI_Finalize(); return EXIT_FAILURE; } } MPI_Finalize(); return EXIT_SUCCESS; }
int main(){ /////////////////// //Initialize data// /////////////////// time_t t; int i,j,k; int amount = 1000; // Amount of particles int timesteps = 1000; // Amount of timesteps int refresh = 10; // Amount of timesteps without updating neighbour list double rc = 2.5; // Cutoff radius double rv; // Neighborlist radius double rho = 0.5; // Density double m = 1; // Mass of particles double region = pow((amount*m)/rho,1./3.); // Sidelength of region double dt = 0.005; // Timestep double kB = 1; // Boltzmannconstant double g = 0; // Guiding factor double T = 1; // Temperature double sigma = sqrt((2*kB*T*g)/m); // Whitenoise factor double sig = sqrt((kB*T)/m); // Initial velocity factor double vmax; // Maximum velocity of particles double kinetic; // Kinetic energy double positions[amount][3]; // Particle positions double velocities[amount][3]; // Particle velocities double forces[amount][3]; // Particle forces double amount_neighbors[amount]; // Amount of neighbors per particle double ****neighbor; // Neighbor List double *vel_sum; // For checking momentum conservation XiEta rnd_XiEta[amount][3]; // Array of linear independent normally distributed numbers srand((unsigned) time(&t)); // Set seed for random number generator /////////////////////////// //Setup initial positions// /////////////////////////// create_particles(positions, amount, region); initial_velocities(velocities, sig, m, amount); /////////////////////////////// //Allocate memory on the heap// /////////////////////////////// neighbor = malloc(amount*sizeof(double ***)); if (neighbor){ for (i=0; i<amount; ++i){ neighbor[i] = malloc(amount*sizeof(double **)); if (neighbor[i]){ for (j=0; j<amount; ++j){ neighbor[i][j] = malloc(3*sizeof(double *)); if (!neighbor[i][j]){ printf("\nMemory allocation error!\n"); } } } } } ////////////////// //Main algorithm// ////////////////// printf("timestep\tsum velocity\tkinetic energy per particle\n"); for (i=0; i<timesteps; i++){ if (i%refresh==0){ vmax = sqrt(max_abs(velocities, amount)); rv = rc + refresh*vmax*dt; update_neighborlist(neighbor, amount_neighbors, positions, rv, amount, region); } for (j=0; j<amount; j++){ for (k=0; k<3; k++){ rnd_XiEta[j][k] = normal_value(0,1); } } calculate_force(forces, neighbor, positions, region, amount); update_velocity(velocities, forces, dt, g, sigma, m, rnd_XiEta, amount); update_position(positions, velocities, dt, sigma, rnd_XiEta, amount); calculate_force(forces, neighbor, positions, region, amount); update_velocity(velocities, forces, dt, g, sigma, m, rnd_XiEta, amount); if (i%100==0){ vel_sum = sum_vel(velocities, amount); kinetic = kinetic_energy(velocities, m, amount); printf("%d\t\t%f\t%f\n", i, vel_sum[0]+vel_sum[1]+vel_sum[2], kinetic/amount); } } //////////////////////////// //Clear memory on the heap// //////////////////////////// for (i=0; i<amount; i++){ for (j=0; j<amount; j++){ free(neighbor[i][j]); } free(neighbor[i]); } free(neighbor); return 0; }
void particleHandler::update(){ create_particles(); update_particles(); reap_particles(); }