Advertisement
Guest User

Untitled

a guest
Apr 6th, 2020
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 4.70 KB | None | 0 0
  1. package pcd.ass01.controller;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.LinkedList;
  5. import java.util.List;
  6. import java.util.Optional;
  7. import java.util.Random;
  8. import java.util.concurrent.BrokenBarrierException;
  9. import java.util.concurrent.CyclicBarrier;
  10.  
  11. import pcd.ass01.controller.body.BodiesWorker;
  12. import pcd.ass01.model.Body;
  13. import pcd.ass01.model.BodyPair;
  14. import pcd.ass01.model.Boundary;
  15. import pcd.ass01.model.Position;
  16. import pcd.ass01.model.Velocity;
  17. import pcd.ass01.view.SimulationViewerControllable;
  18.  
  19. public class ConcurrentSimulator implements Simulator {
  20.  
  21.     private static final int WORKERS_MAX_NUM = Runtime.getRuntime().availableProcessors();
  22.     private static final double DT = 0.01;
  23.     private final int stepsNum;
  24.     private final double bodyRadius;
  25.  
  26.     private final Random rand = new Random(System.currentTimeMillis());
  27.  
  28.     private Optional<SimulationViewerControllable> viewer = Optional.empty();
  29.     private final Boundary bounds;
  30.     private final List<Body> bodies = new ArrayList<>();
  31.     private final List<BodiesWorker> workers = new ArrayList<>();
  32.    
  33.     private boolean isStopped = false;
  34.  
  35.     public ConcurrentSimulator(int bodiesNum, int stepsNum, double bodyRadius) {
  36.         this.stepsNum = stepsNum;
  37.         this.bodyRadius = bodyRadius;
  38.         bounds = new Boundary(-1, -1, 1, 1);
  39.         for (int i = 0; i < bodiesNum; i++) {
  40.             bodies.add(spawnNewBody());
  41.         }
  42.         System.out.println(WORKERS_MAX_NUM);
  43.     }
  44.    
  45.     public ConcurrentSimulator(int bodiesNum, int stepsNum, double bodyRadius, SimulationViewerControllable viewer) {
  46.         this(bodiesNum, stepsNum, bodyRadius);
  47.         this.viewer = Optional.of(viewer);
  48.         this.viewer.get().setSimulator(this);
  49.         this.isStopped = true;
  50.     }
  51.  
  52.     private Body spawnNewBody() {
  53.         final double x = getRandomValue(bounds.getX0(), bounds.getX1());
  54.         final double y = getRandomValue(bounds.getY0(), bounds.getY1());
  55.         final double deltaX = getRandomValue(-1, 1);
  56.         final double speed = getRandomValue(0, 0.05);
  57.         final double xVelocity = deltaX * speed;
  58.         final double yVelocity = Math.sqrt(1 - deltaX * deltaX) * speed;
  59.         return new Body(new Position(x, y), new Velocity(xVelocity, yVelocity), bodyRadius);
  60.     }
  61.  
  62.     private double getRandomValue(double min, double max) {
  63.         return min + rand.nextDouble() * (max - min);
  64.     }
  65.  
  66.     @Override
  67.     public void execute() {
  68.         long start = 0L;
  69.         final int partitionSize = (int) Math.ceil(bodies.size() / WORKERS_MAX_NUM);
  70.        
  71.         List<BodyPair> bodyCombinations = new ArrayList<>();
  72.         for (int i = 0; i < bodies.size() - 1; i++) {
  73.             for (int j = i + 1; j < bodies.size(); j++) {
  74.                 bodyCombinations.add(new BodyPair(bodies.get(i), bodies.get(j)));
  75.             }
  76.         }
  77.        
  78.         final List<List<Body>> bodyPartitions = new LinkedList<>();
  79.         final List<List<BodyPair>> bodyPairs = new LinkedList<>();
  80.         for (int i = 0; i < bodies.size(); i += partitionSize) {
  81.             bodyPartitions.add(bodies.subList(i, Math.min(i + partitionSize, bodies.size())));
  82.         }
  83.         for (int i = 0; i < bodyCombinations.size(); i += partitionSize) {
  84.             bodyPairs.add(bodyCombinations.subList(i, Math.min(i + partitionSize, bodyCombinations.size())));
  85.         }
  86.  
  87.         final StateUpdater stateUpdater = new StateUpdater(DT, stepsNum + 1);
  88.         final CyclicBarrier positionBarrier = new CyclicBarrier(bodyPartitions.size());
  89.         final CyclicBarrier collisionBarrier = new CyclicBarrier(bodyPartitions.size() + 1, stateUpdater);
  90.  
  91.         for (final List<Body> p : bodyPartitions) {
  92.             final BodiesWorker worker = new BodiesWorker("Worker-" + bodyPartitions.indexOf(p), p,
  93.                     bodyPairs.get(bodyPartitions.indexOf(p)), DT, bounds, positionBarrier, collisionBarrier);
  94.             workers.add(worker);
  95.             stateUpdater.addObserver(worker);
  96.             worker.start();
  97.         }
  98.  
  99.         while (stateUpdater.getCurrentIterations() < stepsNum) {
  100.             if (isStopped) {
  101.                 try {
  102.                     synchronized (this) {
  103.                         wait();
  104.                     }
  105.                 } catch (InterruptedException e1) {
  106.                     // TODO Auto-generated catch block
  107.                     e1.printStackTrace();
  108.                 }
  109.             }
  110.             if (start == 0L) {
  111.                  start = System.currentTimeMillis();
  112.             }
  113.             try {
  114.                 collisionBarrier.await();
  115.             } catch (InterruptedException e) {
  116.                 // TODO Auto-generated catch block
  117.                 e.printStackTrace();
  118.             } catch (BrokenBarrierException e) {
  119.                 // TODO Auto-generated catch block
  120.                 e.printStackTrace();
  121.             }
  122.             if (viewer.isPresent()) {
  123.                 viewer.get().display(bodies, stateUpdater.getCurrentVirtualTime(), stateUpdater.getCurrentIterations());
  124.             }
  125.         }
  126.  
  127.         viewer.get().handleFinish();
  128.        
  129.         System.out.print(System.currentTimeMillis() - start);
  130.     }
  131.    
  132.     public void handleStart() {
  133.         synchronized (this) {
  134.             notify();
  135.             isStopped = false;
  136.         }
  137.     }
  138.    
  139.     public void handleStop() {
  140.         isStopped = true;
  141.     }
  142.    
  143.     public void handleStep() {
  144.         synchronized (this) {
  145.             notify();
  146.         }
  147.     }
  148.  
  149. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement