package org.openpixi.pixi.physics.fields;
import edu.emory.mathcs.jtransforms.fft.DoubleFFT_2D;
import junit.framework.TestCase;
import org.openpixi.pixi.physics.Settings;
import org.openpixi.pixi.physics.Simulation;
import org.openpixi.pixi.physics.grid.ChargeConservingCIC;
import org.openpixi.pixi.physics.grid.Grid;
public class PoissonSolverTest extends TestCase {
private double ACCURACY_LIMIT = 1.e-5;
private Simulation s;
private Grid g;
private PoissonSolver poisolver;
/**Tests whether the Poisson Euation is solved correctly for
* different charge distributions by comparing the output of
* the PoissonSolver to the analytic result.
*/
public PoissonSolverTest(String testName){
super(testName);
Settings stt = new Settings();
stt.setSimulationWidth(10);
stt.setSimulationHeight(10);
stt.setGridSolver(new SimpleSolver());
stt.setInterpolator(new ChargeConservingCIC());
this.s = new Simulation(stt);
this.g = s.grid;
this.g.resetCurrent();
this.poisolver = new PoissonSolverFFTPeriodic();
}
public void testPointchargeDistribution() {
//saves charge distribution in g.rho, includes specific test
//for this charge distribution
ChargeDistribution charged = new PointChargeDistributionCenter(g.getNumCellsX(), g.getNumCellsY());
//solves poisson equation
poisolver.solve(g);
//compares with analytic result
// TODO: Test does not work:
// charged.test();
}
private interface ChargeDistribution {
/**Tests PoisonSolver and the analytic results*/
void test();
}
private class PointChargeDistributionCenter implements ChargeDistribution {
int indexX;
int indexY;
PointChargeDistributionCenter (int numCellsX, int numCellsY) {
int indexX = numCellsX/2;
int indexY = numCellsY/2;
g.setRho(indexX, indexY, 1);
}
public void test() {
assertEquals(g.getPhi(indexX, indexY)/(g.getCellWidth()), g.getPhi(indexX+1, indexY), ACCURACY_LIMIT);
}
}
public void testFFT() {
DoubleFFT_2D fft = new DoubleFFT_2D(10,10);
double[][] field = new double[10][20];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 20; j++) {
field[i][j] = 0;
}
}
fft.complexForward(field);
}
void assertAlmostEquals(String text, double x, double y, double limit) {
if ((Math.abs(x - y) / Math.abs(x + y) > limit)
|| (Double.isNaN(x) != Double.isNaN(y))
|| (Double.isInfinite(x) != Double.isInfinite(y))) {
assertTrue(text + " expected:<" + x + "> but was:<" + y + ">", false);
}
}
}