/**
   * prepare method for bringing the velocity in the desired half step
   *
   * @param p before the update: v(t); after the update: v(t-dt/2)
   */
  public void prepare(Particle2D p, Force f, double dt) {
    // a(t) = F(v(t), x(t)) / m
    p.ax = f.getForceX(p) / p.mass;
    p.ay = f.getForceY(p) / p.mass;

    // v(t - dt / 2) = v(t) - a(t)*dt / 2
    p.vx -= p.ax * dt / 2;
    p.vy -= p.ay * dt / 2;
  }
  /** Reflect a particle off the boundaries. */
  public void check(Particle2D particle, Force f, Solver s, double step) {

    // if the particle hits the walls
    if (particle.x < xmin) {
      particle.x += xmax - xmin;
    } else if (particle.x > xmax) {
      particle.x -= xmax - xmin;
    }
    if (particle.y < ymin) {
      particle.y += ymax - ymin;
    } else if (particle.y > ymax) {
      particle.y -= ymax - ymin;
    }
  }
  /**
   * Boris algorithm for implementing the electric and magnetic field. The damping is implemented
   * with an linear error O(dt). Warning: the velocity is stored half a time step before of the
   * position.
   *
   * @param p before the update: x(t), v(t-dt/2); after the update: x(t+dt), v(t+dt/2)
   */
  public void step(Particle2D p, Force f, double step) {

    // remember for complete()
    // a(t) = F(v(t), x(t)) / m
    p.ax = f.getForceX(p) / p.mass;
    p.ay = f.getForceY(p) / p.mass;

    double vxminus = p.vx + f.getPositionComponentofForceX(p) * step / (2.0 * p.mass);
    double vxplus;
    double vxprime;

    double vyminus = p.vy + f.getPositionComponentofForceY(p) * step / (2.0 * p.mass);
    double vyplus;
    double vyprime;

    double t_z = p.charge * f.getBz(p) * step / (2.0 * p.mass); // t vector

    double s_z = 2 * t_z / (1 + t_z * t_z); // s vector

    vxprime = vxminus + vyminus * t_z;
    vyprime = vyminus - vxminus * t_z;

    vxplus = vxminus + vyprime * s_z;
    vyplus = vyminus - vxprime * s_z;

    p.vx =
        vxplus
            + f.getPositionComponentofForceX(p) * step / (2.0 * p.mass)
            + f.getTangentVelocityComponentOfForceX(p) * step / p.mass;
    p.vy =
        vyplus
            + f.getPositionComponentofForceY(p) * step / (2.0 * p.mass)
            + f.getTangentVelocityComponentOfForceY(p) * step / p.mass;

    p.x += p.vx * step;
    p.y += p.vy * step;
  }
 /**
  * complete method for bringing the velocity in the desired half step
  *
  * @param p before the update: v(t-dt/2); after the update: v(t)
  */
 public void complete(Particle2D p, Force f, double dt) {
   // v(t) = v(t - dt / 2) + a(t)*dt / 2
   p.vx += p.ax * dt / 2;
   p.vy += p.ay * dt / 2;
 }