/* * OpenPixi - Open Particle-In-Cell (PIC) Simulator * Copyright (C) 2012 OpenPixi.org * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.openpixi.pixi.physics; import org.openpixi.pixi.physics.force.ConstantForce; import org.openpixi.pixi.physics.force.SpringForce; import org.openpixi.pixi.physics.particles.Particle; import org.openpixi.pixi.physics.particles.ParticleFull; import org.openpixi.pixi.physics.solver.EulerRichardson; import org.openpixi.pixi.physics.solver.relativistic.BorisRelativistic; import org.openpixi.pixi.physics.fields.PoissonSolverFFTPeriodic; import org.openpixi.pixi.physics.fields.EmptyPoissonSolver; import org.openpixi.pixi.physics.fields.SimpleSolver; import org.openpixi.pixi.physics.grid.ChargeConservingCIC; import java.awt.Color; import java.util.ArrayList; import java.util.Random; public class InitialConditions { /**Random angle*/ private static double phi; public static Simulation initRandomParticles(int count, double radius) { Settings stt = new Settings(); stt.setTimeStep(1); //stt.setSpeedOfLight(3); // Use maximum speed available by grid stt.setSpeedOfLight(stt.getCellWidth() / stt.getTimeStep()); stt.setSimulationWidth(100); stt.setSimulationHeight(100); stt.addForce(new ConstantForce()); stt.setParticleList( createRandomParticles(stt.getSimulationWidth(), stt.getSimulationHeight(), stt.getSpeedOfLight() / 3, count, radius)); stt.setBoundary(GeneralBoundaryType.Hardwall); //stt.setParticleSolver(new EulerRichardson()); stt.setParticleSolver(new BorisRelativistic(stt.getSpeedOfLight())); Simulation simulation = new Simulation(stt); return simulation; } public static Simulation initGravity(int count, double radius) { Settings stt = new Settings(); stt.setTimeStep(1); stt.setSpeedOfLight(3); stt.setSimulationWidth(100); stt.setSimulationHeight(100); ConstantForce cf = new ConstantForce(); cf.gy = -1; stt.addForce(cf); stt.setParticleList( createRandomParticles(stt.getSimulationWidth(), stt.getSimulationHeight(), stt.getSpeedOfLight(), count, radius)); stt.setBoundary(GeneralBoundaryType.Hardwall); stt.setParticleSolver(new EulerRichardson()); Simulation simulation = new Simulation(stt); return simulation; } public static Simulation initElectric(int count, double radius) { Settings stt = new Settings(); stt.setTimeStep(1); stt.setSpeedOfLight(3); stt.setSimulationWidth(100); stt.setSimulationHeight(100); ConstantForce cf = new ConstantForce(); cf.ey = -1; stt.addForce(cf); stt.setParticleList( createRandomParticles(stt.getSimulationWidth(), stt.getSimulationHeight(), stt.getSpeedOfLight(), count, radius)); stt.setBoundary(GeneralBoundaryType.Hardwall); stt.setParticleSolver(new EulerRichardson()); Simulation simulation = new Simulation(stt); return simulation; } public static Simulation initMagnetic(int count, double radius) { Settings stt = new Settings(); stt.setTimeStep(1); stt.setSpeedOfLight(3); stt.setSimulationWidth(100); stt.setSimulationHeight(100); ConstantForce cf = new ConstantForce(); cf.bz = -1; stt.addForce(cf); stt.setParticleList( createRandomParticles(stt.getSimulationWidth(), stt.getSimulationHeight(), stt.getSpeedOfLight(), count, radius)); stt.setBoundary(GeneralBoundaryType.Hardwall); stt.setParticleSolver(new EulerRichardson()); Simulation simulation = new Simulation(stt); return simulation; } public static Simulation initSpring(int count, double radius) { Settings stt = new Settings(); stt.setTimeStep(1); stt.setSpeedOfLight(3); stt.setSimulationWidth(100); stt.setSimulationHeight(100); stt.addForce(new ConstantForce()); stt.addForce(new SpringForce()); stt.setParticleList(new ArrayList<Particle>()); stt.setBoundary(GeneralBoundaryType.Periodic); stt.setParticleSolver(new EulerRichardson()); for (int k = 0; k < count; k++) { Particle par = new ParticleFull(); par.setX(stt.getSimulationWidth() * Math.random()); par.setY(stt.getSimulationHeight() * Math.random()); par.setRadius(15); par.setVx(10 * Math.random()); par.setVy(0); par.setMass(1); par.setCharge(.001); stt.addParticle(par); } Simulation simulation = new Simulation(stt); return simulation; } /**Creates particles on random positions with random speeds * @param width maximal x-coodrinate * @param height maximal y-coordinate * @param maxspeed maximal particle speed * @param count number of particles to be created * @param radius particle radius * @return ArrayList of Particle2D */ public static ArrayList<Particle> createRandomParticles(double width, double height, double maxspeed, int count, double radius) { ArrayList<Particle> particlelist = new ArrayList<Particle>(count); for (int k = 0; k < count; k++) { Particle p = new ParticleFull(); p.setX(width * Math.random()); p.setY(height * Math.random()); p.setRadius(radius); phi = 2 * Math.PI * Math.random(); p.setVx(maxspeed * Math.cos(phi)); p.setVy(maxspeed * Math.sin(phi)); p.setMass(1); //overall charge is 0: if (k<count/2) { p.setCharge(.01); p.setColor(Color.red); } else { p.setCharge(-.01); p.setColor(Color.blue); } particlelist.add(p); } return particlelist; } public static Simulation initPair(double charge, double radius) { Settings stt = new Settings(); stt.setTimeStep(0.1); stt.setTMax(1000); stt.setSpeedOfLight(1); stt.setRelativistic(true); /*stt.setSimulationWidth(100); stt.setSimulationHeight(100);*/ stt.setGridStep(1); stt.setGridCellsX(100); stt.setGridCellsY(100); stt.setNumOfParticles(2); stt.addForce(new ConstantForce()); stt.setBoundary(GeneralBoundaryType.Periodic); stt.setGridSolver(new SimpleSolver()); for (int k = 0; k < 2; k++) { Particle par = new ParticleFull(); par.setX(stt.getSimulationWidth() * 1/9.0*(k+4)); par.setY(stt.getSimulationHeight() * 1/2 + stt.getGridStep()*2/4); par.setRadius(radius); par.setVx(0);//par.setVx(0.1*(1-2*k)); par.setVy(0); par.setMass(1); par.setCharge(charge*(1-2*k)); if (k == 0) { par.setColor(Color.red); } else { par.setColor(Color.blue); } stt.addParticle(par); } stt.setPoissonSolver(new PoissonSolverFFTPeriodic()); stt.useGrid(true); stt.setInterpolator(new ChargeConservingCIC()); //stt.setIterations(1);//Testing purposes!!! //set to charge conserving CIC; already preset in settings Simulation simulation = new Simulation(stt); return simulation; } public static Simulation initTwoStream(double charge, double radius, int numpart) { Settings stt = new Settings(); double dnumpart = numpart; stt.setTimeStep(0.1); stt.setSpeedOfLight(1); stt.setRelativistic(true); /*stt.setSimulationWidth(100); stt.setSimulationHeight(100);*/ stt.setGridStep(1); stt.setGridCellsX(100); stt.setGridCellsY(100); stt.setNumOfParticles(2*numpart); stt.setBoundary(GeneralBoundaryType.Periodic); stt.setGridSolver(new SimpleSolver()); for (int k = 0; k < 2*numpart; k++) { Particle par = new ParticleFull(); if(k < numpart) {par.setX(stt.getSimulationWidth() * 1/dnumpart*k); par.setVx(0.1); par.setColor(Color.red); } else {par.setX(stt.getSimulationWidth() * 1/dnumpart*(k-numpart)); par.setVx(-0.1); par.setColor(Color.blue); } par.setY(stt.getSimulationHeight() * 1/2 ); par.setRadius(radius); par.setVy(0); par.setMass(1); par.setCharge(-charge); stt.addParticle(par); } stt.setPoissonSolver(new EmptyPoissonSolver()); stt.useGrid(true); Simulation simulation = new Simulation(stt); return simulation; } public static Simulation initOneTest(double charge, double radius) { Settings stt = new Settings(); stt.setTimeStep(0.1); stt.setSpeedOfLight(1); stt.setRelativistic(true); stt.setGridStep(1); stt.setGridCellsX(100); stt.setGridCellsY(100); /* ConstantForce cf = new ConstantForce(); cf.ex = -1; stt.addForce(cf); */ stt.setNumOfParticles(1); stt.setBoundary(GeneralBoundaryType.Periodic); stt.setGridSolver(new SimpleSolver()); Particle par = new ParticleFull(); par.setX(stt.getSimulationWidth() * 1/2); par.setVx(0.1); par.setY(stt.getSimulationHeight() * 1/2 ); par.setRadius(radius); par.setVy(0); par.setMass(1); par.setCharge(-charge); par.setColor(Color.red); stt.addParticle(par); stt.setPoissonSolver(new EmptyPoissonSolver()); stt.useGrid(true); Simulation simulation = new Simulation(stt); return simulation; } public static Simulation initWeibel(double charge, double radius, int numpart, int numstripes, double speed) { Settings stt = new Settings(); double dnumpart = numpart; stt.setTimeStep(0.1); stt.setSpeedOfLight(1); stt.setRelativistic(true); /*stt.setSimulationWidth(100); stt.setSimulationHeight(100);*/ stt.setGridStep(10); stt.setGridCellsX(10); stt.setGridCellsY(10); stt.setNumOfParticles(numpart); stt.setBoundary(GeneralBoundaryType.Periodic); stt.setGridSolver(new SimpleSolver()); double stripeWidth = stt.getSimulationWidth() / numstripes; if ( (numpart % numstripes) != 0 ) { System.out.println( "Error!! Number of particles and number of stripes don't fit!!"); Simulation simulation = new Simulation(stt); return simulation; } Random ranGen = new Random(); for (int i = 0; i < numstripes; i++) { for (int k = 0; k < numpart/numstripes; k++) { Particle par = new ParticleFull(); par.setY(stt.getSimulationHeight() * 1/dnumpart*numstripes*k); if ( ( (i+1) % 2 ) == 0 ) { par.setVy(speed); } else { par.setVy(-speed); } //par.setX(stt.getSimulationWidth() / numstripes * i + stripeWidth/2 + (Math.random() - 0.5)*stripeWidth ); par.setX(stt.getSimulationWidth() / numstripes * i + stripeWidth/2 + ranGen.nextGaussian()*stripeWidth*0.15 ); par.setRadius(radius); par.setVx(0); par.setCharge(-charge); par.setMass(1); stt.addParticle(par); } } stt.setPoissonSolver(new EmptyPoissonSolver()); stt.useGrid(true); Simulation simulation = new Simulation(stt); /* for (int i = 0; i < stt.getGridCellsY(); i++) { for (int k = 0; k < stt.getGridCellsX(); k++) { simulation.grid.setBz(k, i, 0.3*Math.cos( Math.PI/stt.getSimulationWidth()*numstripes*stt.getGridStep()*(k+1/2))); } } */ return simulation; } public static Simulation initWaveTest(double kx) { Settings stt = new Settings(); stt.setTimeStep(0.1); stt.setTMax(1000); stt.setSpectrumStep(100); stt.setSpeedOfLight(1); stt.setRelativistic(true); /*stt.setSimulationWidth(100); stt.setSimulationHeight(100);*/ stt.setGridStep(1); stt.setGridCellsX(100); stt.setGridCellsY(100); stt.setNumOfParticles(0); stt.setBoundary(GeneralBoundaryType.Periodic); stt.setGridSolver(new SimpleSolver()); stt.setPoissonSolver(new EmptyPoissonSolver()); stt.useGrid(true); Simulation simulation = new Simulation(stt); for (int i = 0; i < stt.getGridCellsY(); i++) { for (int k = 0; k < stt.getGridCellsX(); k++) { simulation.grid.setEy(k, i, Math.sin( kx*stt.getGridStep()*(k+1/2) )); simulation.grid.setBz(k, i, Math.sin( kx*stt.getGridStep()*(k+1/2) )); } } return simulation; } }