/** * 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; }