Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package pcd.ass01.controller;
- import java.util.ArrayList;
- import java.util.LinkedList;
- import java.util.List;
- import java.util.Optional;
- import java.util.Random;
- import java.util.concurrent.BrokenBarrierException;
- import java.util.concurrent.CyclicBarrier;
- import pcd.ass01.controller.body.BodiesWorker;
- import pcd.ass01.model.Body;
- import pcd.ass01.model.BodyPair;
- import pcd.ass01.model.Boundary;
- import pcd.ass01.model.Position;
- import pcd.ass01.model.Velocity;
- import pcd.ass01.view.SimulationViewerControllable;
- public class ConcurrentSimulator implements Simulator {
- private static final int WORKERS_MAX_NUM = Runtime.getRuntime().availableProcessors();
- private static final double DT = 0.01;
- private final int stepsNum;
- private final double bodyRadius;
- private final Random rand = new Random(System.currentTimeMillis());
- private Optional<SimulationViewerControllable> viewer = Optional.empty();
- private final Boundary bounds;
- private final List<Body> bodies = new ArrayList<>();
- private final List<BodiesWorker> workers = new ArrayList<>();
- private boolean isStopped = false;
- public ConcurrentSimulator(int bodiesNum, int stepsNum, double bodyRadius) {
- this.stepsNum = stepsNum;
- this.bodyRadius = bodyRadius;
- bounds = new Boundary(-1, -1, 1, 1);
- for (int i = 0; i < bodiesNum; i++) {
- bodies.add(spawnNewBody());
- }
- System.out.println(WORKERS_MAX_NUM);
- }
- public ConcurrentSimulator(int bodiesNum, int stepsNum, double bodyRadius, SimulationViewerControllable viewer) {
- this(bodiesNum, stepsNum, bodyRadius);
- this.viewer = Optional.of(viewer);
- this.viewer.get().setSimulator(this);
- this.isStopped = true;
- }
- private Body spawnNewBody() {
- final double x = getRandomValue(bounds.getX0(), bounds.getX1());
- final double y = getRandomValue(bounds.getY0(), bounds.getY1());
- final double deltaX = getRandomValue(-1, 1);
- final double speed = getRandomValue(0, 0.05);
- final double xVelocity = deltaX * speed;
- final double yVelocity = Math.sqrt(1 - deltaX * deltaX) * speed;
- return new Body(new Position(x, y), new Velocity(xVelocity, yVelocity), bodyRadius);
- }
- private double getRandomValue(double min, double max) {
- return min + rand.nextDouble() * (max - min);
- }
- @Override
- public void execute() {
- long start = 0L;
- final int partitionSize = (int) Math.ceil(bodies.size() / WORKERS_MAX_NUM);
- List<BodyPair> bodyCombinations = new ArrayList<>();
- for (int i = 0; i < bodies.size() - 1; i++) {
- for (int j = i + 1; j < bodies.size(); j++) {
- bodyCombinations.add(new BodyPair(bodies.get(i), bodies.get(j)));
- }
- }
- final List<List<Body>> bodyPartitions = new LinkedList<>();
- final List<List<BodyPair>> bodyPairs = new LinkedList<>();
- for (int i = 0; i < bodies.size(); i += partitionSize) {
- bodyPartitions.add(bodies.subList(i, Math.min(i + partitionSize, bodies.size())));
- }
- for (int i = 0; i < bodyCombinations.size(); i += partitionSize) {
- bodyPairs.add(bodyCombinations.subList(i, Math.min(i + partitionSize, bodyCombinations.size())));
- }
- final StateUpdater stateUpdater = new StateUpdater(DT, stepsNum + 1);
- final CyclicBarrier positionBarrier = new CyclicBarrier(bodyPartitions.size());
- final CyclicBarrier collisionBarrier = new CyclicBarrier(bodyPartitions.size() + 1, stateUpdater);
- for (final List<Body> p : bodyPartitions) {
- final BodiesWorker worker = new BodiesWorker("Worker-" + bodyPartitions.indexOf(p), p,
- bodyPairs.get(bodyPartitions.indexOf(p)), DT, bounds, positionBarrier, collisionBarrier);
- workers.add(worker);
- stateUpdater.addObserver(worker);
- worker.start();
- }
- while (stateUpdater.getCurrentIterations() < stepsNum) {
- if (isStopped) {
- try {
- synchronized (this) {
- wait();
- }
- } catch (InterruptedException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- }
- if (start == 0L) {
- start = System.currentTimeMillis();
- }
- try {
- collisionBarrier.await();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (BrokenBarrierException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- if (viewer.isPresent()) {
- viewer.get().display(bodies, stateUpdater.getCurrentVirtualTime(), stateUpdater.getCurrentIterations());
- }
- }
- viewer.get().handleFinish();
- System.out.print(System.currentTimeMillis() - start);
- }
- public void handleStart() {
- synchronized (this) {
- notify();
- isStopped = false;
- }
- }
- public void handleStop() {
- isStopped = true;
- }
- public void handleStep() {
- synchronized (this) {
- notify();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement