Package org.openpixi.pixi.distributed

Source Code of org.openpixi.pixi.distributed.Worker$ProblemHandler

package org.openpixi.pixi.distributed;

import org.openpixi.pixi.distributed.grid.DistributedGridFactory;
import org.openpixi.pixi.distributed.grid.DistributedInterpolation;
import org.openpixi.pixi.distributed.ibis.IbisRegistry;
import org.openpixi.pixi.distributed.ibis.WorkerToMaster;
import org.openpixi.pixi.distributed.movement.boundary.DistributedParticleBoundaries;
import org.openpixi.pixi.distributed.util.BooleanLock;
import org.openpixi.pixi.distributed.util.IncomingProblemHandler;
import org.openpixi.pixi.physics.particles.Particle;
import org.openpixi.pixi.physics.Settings;
import org.openpixi.pixi.physics.Simulation;
import org.openpixi.pixi.physics.grid.Cell;
import org.openpixi.pixi.physics.grid.Grid;
import org.openpixi.pixi.physics.grid.Interpolation;
import org.openpixi.pixi.physics.movement.boundary.ParticleBoundaries;
import org.openpixi.pixi.physics.util.ClassCopier;
import org.openpixi.pixi.physics.util.DoubleBox;
import org.openpixi.pixi.physics.util.IntBox;

import java.io.IOException;
import java.util.List;

/**
* Receives the problem, calculates the problem, sends back results.
*/
public class Worker {

  private WorkerToMaster communicator;

  /* Local and global settings differ only in settings connected to simulation size. */
  private Settings localSettings;
  private Settings globalSettings;

  /** ID of this worker. */
  private int workerID;

  private Simulation simulation;

  private SharedDataManager sharedDataManager;

  /* Received problem */
  private IntBox[] partitions;
  private List<Particle> particles;
  private Cell[][] cells;

  private BooleanLock recvProblemLock = new BooleanLock();


  public Worker(IbisRegistry registry, Settings settings) {
    this.globalSettings = settings;
    try {
      communicator = new WorkerToMaster(registry, new ProblemHandler());
    } catch (Exception e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }
    workerID = registry.convertIbisIDToWorkerID(registry.getIbis().identifier());
  }


  public void step() {
    simulation.step();
  }


  public void receiveProblem() {
      recvProblemLock.waitForTrue();
      recvProblemLock.reset();
      createSimulation();
  }


  public void sendResults() {
    Cell[][] finalCells = getFinalCells(simulation.grid);

    // The results can come in arbitrary order; thus,
    // we have to send also the id of the node which is sending the result.
    try {
      communicator.sendResults(
          workerID,
          simulation.particles,
          finalCells);
    } catch (IOException e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }
  }


  /**
   * If the local simulation is at the edge of global simulation,
   * we also need to include the extra cells to the master
   * (because of hardwall boundaries).
   */
  private Cell[][] getFinalCells(Grid grid) {
    IntBox mypart = partitions[workerID];

    int xstart = 0;
    int ystart = 0;
    int xend = mypart.xsize() - 1;
    int yend = mypart.ysize() - 1;
    if (mypart.xmin() == 0) {
      xstart -= Grid.EXTRA_CELLS_BEFORE_GRID;
    }
    if (mypart.xmax() == globalSettings.getGridCellsX() - 1) {
      xend += Grid.EXTRA_CELLS_AFTER_GRID;
    }
    if (mypart.ymin() == 0) {
      ystart -= Grid.EXTRA_CELLS_BEFORE_GRID;
    }
    if (mypart.ymax() == globalSettings.getGridCellsY() - 1) {
      yend += Grid.EXTRA_CELLS_AFTER_GRID;
    }

    Cell[][] finalCells = new Cell[xend - xstart + 1][yend - ystart + 1];
    for (int x = xstart; x <= xend ; ++x) {
      for (int y = ystart; y <= yend; ++y) {
        finalCells[x - xstart][y - ystart] = grid.getCell(x,y);
      }
    }
    return  finalCells;
  }


  private void createSimulation() {
    createLocalSettings();

    sharedDataManager =  createSharedDataManager();
    ParticleBoundaries particleBoundaries = createParticleBoundaries(sharedDataManager);
    sharedDataManager.setParticleBoundaries(particleBoundaries);

    Grid grid = createGrid(sharedDataManager);
    Interpolation interpolation = createInterpolationIterator(sharedDataManager);
    sharedDataManager.setGrid(grid);

    sharedDataManager.initializeCommunication();

    this.simulation = new Simulation(
        localSettings, grid, particles,
        particleBoundaries, interpolation);
  }


  /**
   * Some settings (e.g. simulation width and height) pertain to the global simulation
   * and are incorrect for the local simulation.
   * Thus, we need to correct them, so that they correspond to the local simulation.
   */
  private void createLocalSettings() {
    IntBox mypart = partitions[workerID];

    double cellWidth = globalSettings.getCellWidth();
    double cellHeight = globalSettings.getCellHeight();

    localSettings = ClassCopier.copy(globalSettings);

    localSettings.setGridCellsX(mypart.xsize());
    localSettings.setGridCellsY(mypart.ysize());
    localSettings.setSimulationWidth(cellWidth * mypart.xsize());
    localSettings.setSimulationHeight(cellHeight * mypart.ysize());
  }


  private Interpolation createInterpolationIterator(SharedDataManager sharedDataManager) {
    DoubleBox zoneOfLocalInfluence = new DoubleBox(
        (Grid.INTERPOLATION_RADIUS - 1) * localSettings.getCellWidth(),
        localSettings.getSimulationWidth() -
            Grid.INTERPOLATION_RADIUS * localSettings.getCellWidth(),
        (Grid.INTERPOLATION_RADIUS - 1) * localSettings.getCellHeight(),
        localSettings.getSimulationHeight() -
            Grid.INTERPOLATION_RADIUS * localSettings.getCellHeight());
    return new DistributedInterpolation(
        localSettings.getInterpolator(),
        sharedDataManager, zoneOfLocalInfluence, localSettings.getParticleIterator());
  }


  private SharedDataManager createSharedDataManager() {
    IntBox simulationAreaInCellDimensions = new IntBox(
        0, globalSettings.getGridCellsX() - 1, 0, globalSettings.getGridCellsY() - 1);
    return new SharedDataManager(
        workerID,
        partitions,
        simulationAreaInCellDimensions,
        localSettings.getBoundaryType(),
        communicator.getRegistry());
  }


  private Grid createGrid(SharedDataManager sharedDataManager) {
    DistributedGridFactory gridFactory = new DistributedGridFactory(
        localSettings, partitions[workerID],
        cells, sharedDataManager);
    return gridFactory.create();
  }


  private ParticleBoundaries createParticleBoundaries(SharedDataManager sharedDataManager) {
    DoubleBox simulationAreaInParticleDimensions = new DoubleBox(
        0, localSettings.getSimulationWidth(), 0, localSettings.getSimulationHeight());
    DoubleBox innerSimulationArea = new DoubleBox(
        0, localSettings.getSimulationWidth() - localSettings.getCellWidth(),
        0, localSettings.getSimulationHeight() - localSettings.getCellHeight());
    return new DistributedParticleBoundaries(
        simulationAreaInParticleDimensions, innerSimulationArea,
        localSettings.getParticleBoundary(), sharedDataManager);
  }


  public void close() {
    communicator.close();
    sharedDataManager.close();
  }


  private class ProblemHandler implements IncomingProblemHandler {
    public void handle(IntBox[] partitions, List<Particle> particles, Cell[][] cells) {
      Worker.this.partitions = partitions;
      Worker.this.particles = particles;
      Worker.this.cells = cells;
      recvProblemLock.setToTrue();
    }
  }
}
TOP

Related Classes of org.openpixi.pixi.distributed.Worker$ProblemHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.