package org.openpixi.pixi.physics.solver; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.openpixi.pixi.physics.force.ConstantForce; import org.openpixi.pixi.physics.particles.Particle; import org.openpixi.pixi.physics.particles.ParticleFull; /** * Unit test for Solver. */ public class SolverTest extends TestCase { boolean VERBOSE = false; protected Solver solver; //double ACCURACY_LIMIT = 1.e-16; double ACCURACY_LIMIT = 1.e-13; void assertAlmostEquals(String text, double x, double y, double limit) { if (Math.abs(x - y) / Math.abs(x + y) > limit) { assertTrue(text + " expected:<" + x + "> but was:<" + y + ">", false); } } /** * Create the test case * * @param testName * name of the test case */ public SolverTest(String testName) { super(testName); solver = new Euler(); } /** * @return the suite of tests being tested */ public static Test suite() { return new TestSuite(SolverTest.class); } /** * Test if prepare and complete return to the same initial conditions */ public void testPrepareComplete() { Particle p = new ParticleFull(); ConstantForce f = new ConstantForce(); double step = 1.0; f.ex = 1.234; f.ey = 3.456; f.bz = 7.890; f.gx = 2.468; f.gy = 3.579; f.drag = 5.432; p.setX(23.456); p.setY(35.689); p.setRadius(13.579); p.setVx(12.345); p.setVy(76.543); p.setMass(7.654); p.setCharge(5.432); Particle pcopy = p.copy(); solver.prepare(p, f, step); solver.complete(p, f, step); assertAlmostEquals("x", pcopy.getX(), p.getX(), ACCURACY_LIMIT); assertAlmostEquals("y", pcopy.getY(), p.getY(), ACCURACY_LIMIT); assertAlmostEquals("vx", pcopy.getVx(), p.getVx(), ACCURACY_LIMIT); assertAlmostEquals("vy", pcopy.getVy(), p.getVy(), ACCURACY_LIMIT); for (int i=0; i<1000; i++) { solver.prepare(p, f, step); solver.complete(p, f, step); } assertAlmostEquals("x", pcopy.getX(), p.getX(), ACCURACY_LIMIT); assertAlmostEquals("y", pcopy.getY(), p.getY(), ACCURACY_LIMIT); assertAlmostEquals("vx", pcopy.getVx(), p.getVx(), ACCURACY_LIMIT); assertAlmostEquals("vy", pcopy.getVy(), p.getVy(), ACCURACY_LIMIT); } /** * Test if solver solves similar to Euler */ public void testCompareWithEuler() { Particle p = new ParticleFull(); ConstantForce f = new ConstantForce(); double step = 0.00001d; Solver solver2 = new Euler(); f.ex = 1.234; f.ey = 3.456; f.bz = 7.890; f.gx = 2.468; f.gy = 3.579; f.drag = 5.432; p.setX(23.456); p.setY(35.689); p.setRadius(13.579); p.setVx(12.345); p.setVy(76.543); p.setMass(7.654); p.setCharge(5.432); Particle pcopy = p.copy(); Particle p2 = p.copy(); solver.prepare(p, f, step); solver2.prepare(p2, f, step); for (int i=0; i<100; i++) { solver.step(p, f, step); solver2.step(p2, f, step); } solver.complete(p, f, step); solver2.complete(p2, f, step); if (VERBOSE) { System.out.println("" + this.getClass().getSimpleName()); System.out.println("x: " + pcopy.getX() + " -> " + p2.getX() + " vs. " + p.getX()); System.out.println("y: " + pcopy.getY() + " -> " + p2.getY() + " vs. " + p.getY()); } double accuracy = 0.001d; assertAlmostEquals("x", p2.getX(), p.getX(), accuracy); assertAlmostEquals("y", p2.getY(), p.getY(), accuracy); assertAlmostEquals("vx", p2.getVx(), p.getVx(), accuracy); assertAlmostEquals("vy", p2.getVy(), p.getVy(), accuracy); } }