Example #1
0
  /**
   * \brief Pulling : The movement of agents by a shrinking biofilm. Move calculated and added to
   * the agents movement vector.
   *
   * <p>The movement of agents by a shrinking biofilm. Move calculated and added to the agents
   * movement vector.
   *
   * @param aNeighbor Reference to the potentially shoving neighbour
   * @param isMutual Whether movement is shared between two agents or applied only to this one
   * @param gain Double noting change in position
   * @return Boolean stating whether pulling is detected (true) or not (false)
   */
  public boolean addSpringMovement(LocatedAgent aNeighbor, boolean isMutual, double gain) {
    double d, distance, delta;

    if (aNeighbor == this) return false;

    // Build the escape vector and find the distance between you and your
    // neighbourhood
    d = computeDifferenceVector(_location, aNeighbor._location);

    _diff.normalizeVector();

    distance = getShoveRadius() + aNeighbor.getShoveRadius();
    distance += getSpeciesParam().shoveLimit;

    delta = d - distance;
    double lMax = _totalRadius;

    if (delta > 0) gain *= Math.exp(-delta * 5 / (lMax));
    if (delta > lMax) gain = 0;

    /* Apply shoving _________________________________________________ */

    if (isMutual) {
      _diff.times(-0.5 * delta * gain);
      this._movement.add(_diff);
      aNeighbor._movement.subtract(_diff);
    } else {
      _diff.times(-delta * gain);
      this._movement.add(_diff);
    }

    return (_movement.norm() > _radius * gain);
  }
Example #2
0
 /**
  * \brief Select random coordinates for the new agent within a restricted birth area
  *
  * <p>Select random coordinates for the new agent within a restricted birth area. This restricted
  * area is set within the protocol file, and defined as a ContinuousVector by the method
  * defineSquareArea
  *
  * @param cc ContinuousVector that will hold the coordinates of this agent
  * @param area Area within which these coordinates should be restricted
  */
 public void shuffleCoordinates(ContinuousVector cc, ContinuousVector[] area) {
   do {
     cc.x = ExtraMath.getUniRandDbl(area[0].x, area[1].x);
     cc.y = ExtraMath.getUniRandDbl(area[0].y, area[1].y);
     cc.z = ExtraMath.getUniRandDbl(area[0].z, area[1].z);
   } while (domain.testCrossedBoundary(cc) != null);
 }
Example #3
0
  /**
   * \brief Mutual shoving : The movement by shoving of an agent is calculated based on the cell
   * overlap and added to the agents movement vector.
   *
   * <p>Mutual shoving : The movement by shoving of an agent is calculated based on the cell overlap
   * and added to the agents movement vector. Both agents are moved of half the overlapping distance
   * in opposite directions.
   *
   * @param aNeighbour Reference to the potentially shoving neighbour
   * @param isMutual Whether movement is shared between two agents or applied only to this one
   * @param gain Double noting change in position
   * @return Boolean stating whether shoving is detected (true) or not (false)
   */
  public boolean addPushMovement(LocatedAgent aNeighbour, boolean isMutual, double gain) {
    double d, distance;

    if (aNeighbour == this) return false;

    // Build the escape vector and find the distance between you and your
    // neighbourhood
    d = computeDifferenceVector(_location, aNeighbour._location);

    _diff.normalizeVector();

    // Compute effective cell-cell distance
    distance = getShoveRadius() + aNeighbour.getShoveRadius();
    distance += getSpeciesParam().shoveLimit;
    distance = d - distance;

    /* Apply shoving _________________________________________________ */

    // Compute shoving distance for the current agent
    if (distance <= 0) {
      if (isMutual) {
        _diff.times(gain * 0.5 * Math.abs(distance));
        this._movement.add(_diff);
        aNeighbour._movement.subtract(_diff);
      } else {
        _diff.times(Math.abs(gain * distance));
        this._movement.add(_diff);
      }
      return true;
    } else {
      return false;
    }
  }
Example #4
0
  /**
   * \brief Set the movement vector that states where to put a newly-created particle
   *
   * <p>Set the movement vector that states where to put a newly-created particle
   *
   * @param distance Distance between the this agent and the new agent
   */
  public void setDivisionDirection(double distance) {
    double phi, theta;

    phi = 2 * Math.PI * ExtraMath.getUniRandDbl();
    theta = 2 * Math.PI * ExtraMath.getUniRandDbl();

    _divisionDirection.x = distance * Math.sin(phi) * Math.cos(theta);
    _divisionDirection.y = distance * Math.sin(phi) * Math.sin(theta);
    _divisionDirection.z = (_agentGrid.is3D ? distance * Math.cos(phi) : 0);
  }
Example #5
0
  /**
   * \brief For self-attachment scenarios, calculates the new position of the agent based on XY and
   * XZ angles and a distance to move
   *
   * <p>For self-attachment scenarios, calculates the new position of the agent based on XY and XZ
   * angles and a distance to move. No return value as the global swimmingAgentPosition is altered.
   * The angles XY and XZ are also global parameters as these can also be altered by other methods
   * in the swimming agent position checks
   *
   * @param distanceAgentMoves Distance that the agent is to move
   */
  public void calculateNewAgentPosition(Double distanceAgentMoves) {
    // Now calculate where this angle would place the agent.
    swimMovement.set(
        Math.cos(angleOfMovingAgentXY) * Math.cos(angleOfMovingAgentXZ),
        Math.sin(angleOfMovingAgentXY),
        Math.sin(angleOfMovingAgentXZ));

    swimMovement.times(distanceAgentMoves);

    swimmingAgentPosition.add(swimMovement);
  }
Example #6
0
  /**
   * \brief Computes the shortest distance between this agent and another, stored as
   * ContinuousVectors. This may be around the cyclic boundary
   *
   * <p>Computes the distance between this agent and another, stored as ContinuousVectors. This may
   * be around the cyclic boundary
   *
   * @param me ContinuousVector stating first agent location
   * @param him ContinuousVector stating other agent location
   * @return the shortest movement vector to go from a to b, take into account the cyclic boundary
   * @see addOverlapMovement
   * @see addPullMovement works in 2 and 3D
   */
  public double computeDifferenceVector(ContinuousVector me, ContinuousVector him) {
    double gridLength;

    _diff.x = me.x - him.x;
    // check periodicity in X
    gridLength = _species.domain.length_X;
    if (Math.abs(_diff.x) > .5 * gridLength) _diff.x -= Math.signum(_diff.x) * gridLength;

    _diff.y = me.y - him.y;
    // check periodicity in Y
    gridLength = _species.domain.length_Y;

    if (Math.abs(_diff.y) > .5 * gridLength) _diff.y -= Math.signum(_diff.y) * gridLength;

    if (_agentGrid.is3D) {
      _diff.z = me.z - him.z;
      // check periodicity in Z
      gridLength = _species.domain.length_Z;
      if (Math.abs(_diff.z) > .5 * gridLength) _diff.z -= Math.signum(_diff.z) * gridLength;

    } else {
      _diff.z = 0;
    }
    double d = Math.sqrt(_diff.x * _diff.x + _diff.y * _diff.y + _diff.z * _diff.z);

    if (d == 0) {
      d = 1e-2 * _radius;
      _diff.alea(_agentGrid.is3D);
    }

    return d;
  }
Example #7
0
  /**
   * \brief With the agent move calculated, apply this movement, taking care to respect boundary
   * conditions
   *
   * <p>With the agent move calculated, apply this movement, taking care to respect boundary
   * conditions
   */
  public double move() {
    if (!_movement.isValid()) {
      LogFile.writeLog("Incorrect movement coordinates");
      _movement.reset();
    }

    if (!_agentGrid.is3D && _movement.z != 0) {
      _movement.z = 0;
      _movement.reset();
      LogFile.writeLog("Try to move in z direction !");
    }

    // No movement planned, finish here
    if (_movement.isZero()) return 0;

    // Test the boundaries
    checkBoundaries();

    // Now apply the movement
    _location.set(_newLoc);
    _agentGrid.registerMove(this);

    double delta = _movement.norm();
    _movement.reset();

    return delta / _totalRadius;
  }
  /**
   * examines solute grid to determine where to move based on attraction/repulsion to/from a solute
   */
  private void chemotax() {

    // 1) get the gradient--this will be the direction the particle
    // should move in or away from

    ContinuousVector direction = chemotaxSolute.getGradient2DNoZ(_location);

    if (repellent) {
      direction.turnAround();
    }

    // 2) scale the gradient set the scaled gradient as _movement
    _movement = this.getScaledMove(_location, direction, distEachRun);
  }
Example #9
0
 /**
  * \brief For self-attach scenarios, corrects 2D coordinates that have crossed the left of right
  * boundary (x0z and xNz)
  *
  * <p>For self-attach scenarios, corrects 2D coordinates that have crossed the left of right
  * boundary (x0z and xNz). The coordinate is either placed on the opposite side for cyclic
  * boundaries, or bounces off the boundary at the required angle
  *
  * @param boundaryCrossed The boundary that has been detected to have been crossed
  * @param distanceMoving The distance that the cell is moving in this step of its repositioning
  */
 public void correctCrossedLeftRightBoundaries(AllBC boundaryCrossed) {
   // Cell has passed through the boundary on the left or right hand side
   // If is cyclic, the point is deemed to reappear at the opposite side
   if (boundaryCrossed instanceof BoundaryCyclic) {
     // This will be inside the grid at the amount that the move would
     // have taken the point outside of the grid.
     swimmingAgentPosition.y = swimmingAgentPosition.y % domain.length_Y;
   } else {
     // Can simply take the correct value of the new Y coordinate and
     // reflect it the correct side of the boundary.
     swimmingAgentPosition.y = -swimmingAgentPosition.y % domain.length_Y;
     // Now we need to change the angle to note the change of direction.
     angleOfMovingAgentXY = 2 * Math.PI - angleOfMovingAgentXY;
   }
 }
Example #10
0
  /**
   * \brief With it determined that cell division will occur, create a new agent from the existing
   * one
   *
   * <p>With it determined that cell division will occur, create a new agent from the existing one
   *
   * @throws CloneNotSupportedException Thrown if the agent cannot be cloned
   */
  public void makeKid() throws CloneNotSupportedException {

    // Create the new instance
    LocatedAgent baby = (LocatedAgent) sendNewAgent();
    // Note that mutateAgent() does nothing yet
    baby.mutateAgent();

    this._myDivRadius = getDivRadius();
    baby._myDivRadius = getDivRadius();
    baby._myDeathRadius = getDeathRadius();

    // Update the lineage
    recordGenealogy(baby);

    // Share mass of all compounds between two daughter cells and compute
    // new size
    divideCompounds(baby, getBabyMassFrac());
    // sonia:chemostat
    if (Simulator.isChemostat) {
      // upon division the daughter cells remain with the coordinates of their progenitor

    } else {
      // Compute movement to apply to both cells
      setDivisionDirection(getInteractDistance(baby) / 2);

      // move both daughter cells
      baby._movement.subtract(_divisionDirection);
      _movement.add(_divisionDirection);
    }
    // Now register the agent inside the guilds and the agent grid
    baby.registerBirth();
    baby._netVolumeRate = 0;
  }
Example #11
0
  /**
   * \brief Create a new agent in a specified position
   *
   * <p>Create a new agent in a specified position
   *
   * @param position Vector stating where this agent should be located
   */
  public void createNewAgent(ContinuousVector position) {
    try {
      // Get a clone of the progenitor
      LocatedAgent baby = (LocatedAgent) sendNewAgent();
      baby.giveName();

      // randomize its mass
      baby.mutatePop();

      baby.updateSize();

      this._myDivRadius = getDivRadius();
      baby._myDivRadius = getDivRadius();
      baby._myDeathRadius = getDeathRadius();

      // Just to avoid to be in the carrier
      position.x += this._totalRadius;

      baby.setLocation(position);

      baby.registerBirth();

    } catch (CloneNotSupportedException e) {
      utils.LogFile.writeLog("Error met in LocAgent:createNewAgent()");
    }
  }
Example #12
0
  /**
   * \brief Used by the move method to determine if an agents move crosses any of the domain's
   * boundaries
   *
   * <p>Used by the move method to determine if an agents move crosses any of the domain's
   * boundaries
   */
  public void checkBoundaries() {
    // Search a boundary which will be crossed
    _newLoc.set(_location);
    _newLoc.add(_movement);
    AllBC aBoundary = getDomain().testCrossedBoundary(_newLoc);
    int nDim = (_agentGrid.is3D ? 3 : 2);
    boolean test = (aBoundary != null);
    int counter = 0;

    // Test all boundaries and apply corrections according to crossed
    // boundaries
    while (test) {
      counter++;
      aBoundary.applyBoundary(this, _newLoc);
      aBoundary = getDomain().testCrossedBoundary(_newLoc);

      test = (aBoundary != null) | (counter > nDim);
      if (counter > nDim) System.out.println("LocatedAgent.move() : problem!");
    }
  }
Example #13
0
  /**
   * \brief Create an agent using information in a previous state or initialisation file
   *
   * <p>Create an agent using information in a previous state or initialisation file
   *
   * @param aSim The simulation object used to simulate the conditions specified in the protocol
   *     file
   * @param singleAgentData Data from the result or initialisation file that is used to recreate
   *     this agent
   */
  public void initFromResultFile(Simulator aSim, String[] singleAgentData) {
    // this routine will read data from the end of the singleAgentData array
    // and then pass the remaining values onto the super class

    // Chemostat "if" added by Sonia 27.10.09
    // Rearranged by Rob 10.01.11

    // find the position to start at by using length and number of values read
    int nValsRead = 5;
    int iDataStart = singleAgentData.length - nValsRead;

    if (Simulator.isChemostat) {

      // Rob: this is necessary for the case when biofilm agents in one simulation
      // are transferred into a chemostat for the next.
      _location.set(0, 0, 0);

    } else {

      double newAgentX, newAgentY, newAgentZ;
      newAgentX = Double.parseDouble(singleAgentData[iDataStart]);
      newAgentY = Double.parseDouble(singleAgentData[iDataStart + 1]);
      newAgentZ = Double.parseDouble(singleAgentData[iDataStart + 2]);
      _location.set(newAgentX, newAgentY, newAgentZ);
    }

    // agent size
    _radius = Double.parseDouble(singleAgentData[iDataStart + 3]);
    _totalRadius = Double.parseDouble(singleAgentData[iDataStart + 4]);

    _myDivRadius = getDivRadius();
    _myDeathRadius = getDeathRadius();

    // now go up the hierarchy with the rest of the data
    String[] remainingSingleAgentData = new String[iDataStart];
    for (int i = 0; i < iDataStart; i++) remainingSingleAgentData[i] = singleAgentData[i];

    super.initFromResultFile(aSim, remainingSingleAgentData);
  }
Example #14
0
  /**
   * \brief Determine if a swimming agent has left the boundary layer and returned to the bulk
   *
   * <p>For self attachment, an agent starts at the top of the boundary layer and swims in a random
   * direction until it attaches somewhere. If however it returns to the bulk, we assume this cell
   * does not return. This method checks the move to determine if the cell is moving in a trajectory
   * that has returned it to the bulk
   *
   * @return Boolean stating whether the cell has returned to the bulk
   */
  public boolean isNewCoordAboveBoundaryLayer() {
    // Get the top of the bulk - note we may need to correct here. The
    // method that calls this calculates new positions. However this is run
    // before it is determined whether any boundaries have been crossed (as
    // it would be silly to check all boundaries when there is a high
    // chance, especially at the start, that the cell may return into the
    // bulk. Thus, a high Y or Z value may be sent in here, which when
    // referenced to the boundary layer array, will cause an error. So if
    // the Y or Z values are higher than the size of the grid, we will use
    // the size of the grid as the array reference
    if (swimmingAgentPosition.y > domain.length_Y) swimmingAgentPosition.y = domain.length_Y - 1;

    if (swimmingAgentPosition.z > domain.length_Z) swimmingAgentPosition.z = domain.length_Z - 1;
    // System.out.println("Checking if "+swimmingAgentPosition.toString()+" above boundary layer");
    // Now calculate the top of the boundary layer at the y, z coordinate.
    int j = (int) (swimmingAgentPosition.y / domain._resolution);
    int k = (int) (swimmingAgentPosition.z / domain._resolution);
    double boundaryAtThisPoint = domain._topOfBoundaryLayer[j + 1][k + 1];
    boundaryAtThisPoint *= domain._resolution;
    // System.out.println("..."+(swimmingAgentPosition.x > boundaryAtThisPoint));
    // Check if we are above it
    return (swimmingAgentPosition.x > boundaryAtThisPoint);
  }
Example #15
0
  /**
   * \brief Set the location of this agent to the supplied continuous vector
   *
   * <p>Set the location of this agent to the supplied continuous vector
   *
   * @param cc Location which this agent should be assigned to
   */
  public void setLocation(ContinuousVector cc) {

    // sonia:chemostat
    // set the location of the newborns to zero

    if (Simulator.isChemostat) {
      cc.set(0, 0, 0);
      _location.x = cc.x;
      _location.y = cc.y;
      _location.z = cc.z;

    } else {
      _location.x = cc.x;
      _location.y = cc.y;
      _location.z = cc.z;
    }
  }
Example #16
0
  /**
   * \brief For self-attachment scenarios, initialises agents on the boundary layer rather than
   * substrarum, and models their swim to the surface or biofilm
   *
   * <p>For self-attachment scenarios, the agents are initialised at the top of the boundary layer
   * rather than on the substratum. These agents then perform a 'run and tumble' motion until they
   * either attach to the substratum or forming biofilm. This method captures this behaviour for
   * cells that are created for a time step. Once this swimming action has been performed, the agent
   * is created at its final position. Note that input of agents onto the boundary layer is decided
   * by a parameter set in the protocol file, cellAttachmentFrequency, measured in hours. The number
   * of cells is adjusted to suit the global time step that is being used. Also note that this
   * injection of cells can be for a set period (specified in the protocol file as parameter
   * cellInjectionPeriod), or can be stopped and started (modelling a 'settling' period) using
   * parameters cellInjectionOffPeriod and cellInjectionStopHour. This is explained in detail in the
   * tutorial for version 1.2 of iDynoMiCS.
   *
   * @param spRoot The Species markup from the protocol file for one particular species being
   *     initialised
   * @param numberAttachedInjectedAgents The number of agents of this type that need to be created
   *     in this global timestep
   */
  public void createBoundaryLayerPop(XMLParser spRoot, int numberAttachedInjectedAgents) {
    LogFile.writeLog(
        "\t\tAttempting to create "
            + numberAttachedInjectedAgents
            + " agents of "
            + speciesName
            + " in the boundary layer");
    // Create all the required agents

    // Note that this continues UNTIL THE DESIRED NUMBER OF CELLS HAVE ATTACHED SOMEWHERE
    // Just out of interest, I've decided to keep a count of how many cells are required for this to
    // happen
    int totalNumberOfInjectedAgents = 0;
    int agentsReturnedToBulk = 0;
    int requiredNumAttachedAgents = numberAttachedInjectedAgents;

    // Temporary DiscreteVector to make finding the boundary layer tidier.
    DiscreteVector dV = new DiscreteVector();

    while (numberAttachedInjectedAgents > 0) {
      totalNumberOfInjectedAgents++;

      if (_progenitor instanceof LocatedAgent) {
        swimmingAgentPosition.reset();

        // Now to choose coordinates for this particular agent
        while (true) {
          // This cell needs to take a random location in the Z and Y
          // directions. The X will come from the position of the
          // boundary layer on those axes. Generate these randomly.
          swimmingAgentPosition.y = ExtraMath.getUniRandDbl() * domain.length_Y;
          if (domain.is3D) {
            swimmingAgentPosition.z = ExtraMath.getUniRandDbl() * domain.length_Z;
          }
          // Now to work out the X coordinate. This is based on where
          // the top of the boundary layer is when this agent is
          // created. The top of the boundary layer is calculated in
          // Domain at each step. Now the resolution differs (this is
          // in nI x nJ x nK rather than microns - so this will need
          // to be converted accordingly. Method to calculate this:
          // - get the value from the top of the boundary layer
          // - reduce by 1 (such that the micron value will be the
          // 						 top of the layer)
          // - multiply by resolution of this domain.
          dV.set(swimmingAgentPosition, domain._resolution);
          if (!domain.is3D) dV.k = 1;
          swimmingAgentPosition.x = domain._topOfBoundaryLayer[dV.j][dV.k] - 1.0;

          swimmingAgentPosition.x *= domain._resolution;
          // Check this is ok.
          // System.out.println("Trying starting position "+dV.toString()+" =>
          // "+this.swimmingAgentPosition.toString());
          if (domain.testCrossedBoundary(swimmingAgentPosition) == null) break;
        }

        // Now we can do the run and tumble motion of these cells

        int cellRunResult = performRunAndTumble(spRoot);

        // If increment the relevant counters, as these may be useful
        switch (cellRunResult) {
          case 1: // Successfully Attached
            numberAttachedInjectedAgents--;
            // Create the agent at these coordinates
            ((LocatedAgent) _progenitor).createNewAgent(this.swimmingAgentPosition);
            // System.out.println("Cell "+swimmingAgentPosition.toString()+" attached");
            break;
          case 2:
            // System.out.println("Cell at "+swimmingAgentPosition.toString()+" returned to bulk");
            agentsReturnedToBulk++;
            break;
        }
      } else {
        // If this isn't a located species, just create a new agent.
        _progenitor.createNewAgent();
      }
    }
    // Write the stats to the log file incase of interest
    LogFile.writeLog(
        requiredNumAttachedAgents
            + " agents of species "
            + speciesName
            + " for self-attachment successfully created");
    LogFile.writeLog(
        totalNumberOfInjectedAgents + " agents of species " + speciesName + " attempted to attach");
    LogFile.writeLog(
        agentsReturnedToBulk + " agents of species " + speciesName + " returned to the bulk");
  }
Example #17
0
  /**
   * \brief For self-attachment scenarios, determines whether a swimming agents move has taken it
   * across a boundary, correcting the coordinate accordingly
   *
   * <p>For self-attachment scenarios, the agents are swimming through the domain, and we need to
   * ensure that they perform the correct behaviour when the boundary is met. This method checks
   * whether an agents move has taken it over the boundary and applies the relevant correction
   * (either a bounce off the boundary or a reappearance on the other side). If the cell has hit the
   * surface, the cell is deemed to have adhered to that surface and a relevant x coordinate
   * generated to note that this is the case. The top of the domain is dealt with differently, as
   * this is checked by the call to isNewCoordAboveBoundaryLayer, which determines if the agent has
   * moved out of the boundary layer. If this is the case we assume this cell to have returned to
   * the bulk and do no further action with that cell. An integer is returned noting the fate of
   * this move - a 0 if the move is ok (after adjustment if required), a 1 if the agent has met the
   * substratum and attached, and a 2 if the cell has returned to the bulk
   *
   * @param distanceMoving Distance the agent is moving (in microns) in this move
   * @return Integer noting the fate of this move (0 move ok (after adjustment if required), 1 if
   *     attached to surface, 2 if returned to bulk
   */
  public int agentMoveBorderCheck() {
    // Simplest test to do first is to check if any boundaries have been crossed
    AllBC boundaryCrossed = domain.testCrossedBoundary(swimmingAgentPosition);

    // First is a simple test - has the cell returned to the bulk
    // If this is the case, we can just forget this and have another go
    // The cell will only have the capability to return to the bulk if the angle has it moving
    // upwards or directly across
    // (i.e 0-90 and 270-360 degrees)
    if (isNewCoordAboveBoundaryLayer()) {
      // The cell has returned into the bulk, and thus this try is over.
      // Return 2 so the process starts with a new cell.
      return 2;
    } else {
      // Now to see if the move takes the point outside any of the boundaries
      if (boundaryCrossed == null) {
        // No borders crossed, not back in the bulk.
        return 0;
      } else {
        String boundaryCrossedName = boundaryCrossed.getSideName();

        if (boundaryCrossedName.equals("y0z")) {
          // Detected that the move has crossed the substratum, thus
          // the cell has hit the biofilm. A return of 1 indicates
          // that this is the case.
          // Hit the biofilm, so set the species coordinates as required.

          // We may have hit the biofilm but the Y and Z coordinates
          // in this generated move may still be negative (as they
          // may have gone over another boundary). So before we set
          // the final x, we should check Y and Z.
          // So firstly, set the X position onto the surface
          swimmingAgentPosition.x = ExtraMath.getUniRandDbl();

          // Now set the final X position.
          // Do a new check on the boundary crossed.
          boundaryCrossed = domain.testCrossedBoundarySelfAttach(swimmingAgentPosition);

          if (boundaryCrossed != null) {
            boundaryCrossedName = boundaryCrossed.getSideName();
            if (boundaryCrossedName.equals("xNz") || boundaryCrossedName.equals("x0z"))
              correctCrossedLeftRightBoundaries(boundaryCrossed);
            else correctCrossedFrontBackBoundaries(boundaryCrossed);
          }
          return 1;
        } else if (boundaryCrossedName.equals("xNz") || boundaryCrossedName.equals("x0z")) {
          correctCrossedLeftRightBoundaries(boundaryCrossed);
          return 0;
        }
        // Deal with 3D boundary too
        else if (boundaryCrossedName.equals("x0y") || boundaryCrossedName.equals("xNy")) {
          correctCrossedFrontBackBoundaries(boundaryCrossed);
          return 0;
        } else {
          // This needs to be here so the function returns something.
          // However this deals with the top boundary (yNz) and this
          // has already been dealt with by the crossed bulk method.
          // So it is highly doubtful we will ever end up here.
          return 0;
        }
      }
    }
  }
Example #18
0
 /**
  * \brief Determine if an agent has a move to perform
  *
  * <p>Determine if an agent has a move to perform
  *
  * @return Boolean noting whether the agent has a move to perform
  */
 public boolean isMoving() {
   return (_movement.norm() > _totalRadius / 10);
 }