Updatet architecture

This commit is contained in:
Alexander Nozik 2016-06-04 14:33:01 +03:00
parent 74e58fca80
commit 1f7be09fb2
6 changed files with 170 additions and 161 deletions

View File

@ -3,3 +3,7 @@
\.chg\..*$
\.rej$
\.conflict\~$
.gradle
build/
.idea/*
!gradle-wrapper.jar

View File

@ -1,5 +1,5 @@
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'idea'
apply plugin: 'application'

View File

@ -1,33 +0,0 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package inr.numass.trapping;
/**
* Класс нужен исключительно чтобы сделать простой доступ к Сишным экспортам
* @author Darksnake
*/
public class DoubleValue {
private double value;
public DoubleValue(double value) {
this.value = value;
}
/**
* @return the value
*/
public double getValue() {
return value;
}
/**
* @param value the value to set
*/
public void setValue(double value) {
this.value = value;
}
}

View File

@ -0,0 +1,123 @@
package inr.numass.trapping;
import org.apache.commons.math3.random.JDKRandomGenerator;
import org.apache.commons.math3.random.RandomGenerator;
import java.io.PrintStream;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* Created by darksnake on 04-Jun-16.
*/
public class SimulationManager {
RandomGenerator generator = new JDKRandomGenerator();
Simulator simulator = new Simulator();
private double initialE = 18000;
private PrintStream output = System.out;
private PrintStream statisticOutput = System.out;
public SimulationManager withParameters(double bSource, double bTransport, double bPinch, double initialE, double energyRange) {
this.simulator = new Simulator(bSource, bTransport, bPinch, initialE - energyRange);
this.initialE = initialE;
return this;
}
public SimulationManager withOutput(PrintStream output) {
this.output = output;
return this;
}
public SimulationManager withStatisticOutput(PrintStream statisticOutput) {
this.statisticOutput = statisticOutput;
return this;
}
/**
* Симулируем пролет num электронов.
*
* @param num
* @return
*/
public synchronized Counter simulateAll(int num) {
Counter counter = new Counter();
Predicate<Simulator.SimulationResult> reportIf = (res) -> res.state == Simulator.EndState.ACCEPTED;
System.out.printf("%nStarting sumulation with initial energy %g and %d electrons.%n%n", initialE, num);
Stream.generate(() -> getRandomTheta()).limit(num).parallel()
.forEach((theta) -> {
Simulator.SimulationResult res = simulator.simulate(initialE, theta);
if (reportIf.test(res)) {
if (output != null) {
printOne(output, res);
}
}
counter.count(res);
});
printStatistics(counter);
return counter;
}
private double getRandomTheta() {
double x = generator.nextDouble();
return Math.acos(x);
}
private void printStatistics(Counter counter) {
output.printf("The total number of events is %d.%n%n", counter.count);
output.printf("The spectrometer acceptance angle is %g.%n", simulator.thetaPinch * 180 / Math.PI);
output.printf("The transport reflection angle is %g.%n", simulator.thetaTransport * 180 / Math.PI);
output.printf("The starting energy is %g.%n", initialE);
output.printf("The lower energy boundary is %g.%n%n", simulator.Elow);
output.printf("The total number of ACCEPTED events is %d.%n", counter.accepted);
output.printf("The total number of PASS events is %d.%n", counter.pass);
output.printf("The total number of REJECTED events is %d.%n", counter.rejected);
output.printf("The total number of LOWENERGY events is %d.%n%n", counter.lowE);
}
private void printOne(PrintStream out, Simulator.SimulationResult res) {
out.printf("%g\t%g\t%g\t%d\t%s%n", res.E, res.theta * 180 / Math.PI, res.initTheta * 180 / Math.PI, res.collisionNumber, res.state.toString());
}
public static class Counter {
int accepted = 0;
int pass = 0;
int rejected = 0;
int lowE = 0;
int count = 0;
public synchronized Simulator.SimulationResult count(Simulator.SimulationResult res) {
count++;
switch (res.state) {
case ACCEPTED:
accepted++;
break;
case LOWENERGY:
lowE++;
break;
case PASS:
pass++;
break;
case REJECTED:
rejected++;
break;
case NONE:
throw new IllegalStateException();
}
return res;
}
public synchronized void reset() {
count = 0;
accepted = 0;
pass = 0;
rejected = 0;
lowE = 0;
}
}
}

View File

@ -5,9 +5,9 @@
package inr.numass.trapping;
import java.io.PrintStream;
import java.util.List;
import java.util.stream.Collectors;
import java.util.function.Predicate;
import java.util.stream.Stream;
import org.apache.commons.math3.geometry.euclidean.threed.Rotation;
import org.apache.commons.math3.geometry.euclidean.threed.SphericalCoordinates;
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
@ -18,23 +18,28 @@ import org.apache.commons.math3.util.Pair;
import org.apache.commons.math3.util.Precision;
/**
*
* @author Darksnake
*/
public class ElectronTrappingSimulator {
public class Simulator {
private RandomGenerator generator;
Scatter scatter;
double Elow = 14000d;
double thetaTransport = 24.107064 / 180 * Math.PI;
double thetaPinch = 19.481097 / 180 * Math.PI;
private Scatter scatter;
double Elow = 14000d;//default value
double thetaTransport = 24.107064 / 180 * Math.PI;// default value
double thetaPinch = 19.481097 / 180 * Math.PI;// default value
public ElectronTrappingSimulator() {
public Simulator() {
generator = new SynchronizedRandomGenerator(new MersenneTwister());
scatter = new Scatter(generator);
}
public Simulator(double Bsource, double Btransport, double Bpinch, double Elow){
this();
setFields(Bsource, Btransport, Bpinch);
setElow(Elow);
}
public static enum EndState {
ACCEPTED,//трэппинговый электрон попал в аксептанс
@ -44,7 +49,11 @@ public class ElectronTrappingSimulator {
NONE
}
public void setFields(double Bsource, double Btransport, double Bpinch) {
public final void setElow(double elow) {
Elow = elow;
}
public final void setFields(double Bsource, double Btransport, double Bpinch) {
this.thetaTransport = Math.asin(Math.sqrt(Bsource / Btransport));
this.thetaPinch = Math.asin(Math.sqrt(Bsource / Bpinch));
}
@ -55,20 +64,19 @@ public class ElectronTrappingSimulator {
* Считаем, что за один проход источника происходит в среднем существенно
* меньше одного столкновения, поэтому выход вперед или назад совершенно
* симментричны.
*
*/
public SimulaionResult simulateOne(double initEnergy, double initTheta) {
public SimulationResult simulate(double initEnergy, double initTheta) {
assert initEnergy > 0;
assert initTheta > 0 && initTheta < Math.PI / 2;
if (initTheta < this.thetaPinch) {
if (generator.nextBoolean()) {
return new SimulaionResult(EndState.PASS, initEnergy, initTheta, initTheta, 0);
return new SimulationResult(EndState.PASS, initEnergy, initTheta, initTheta, 0);
} else {
return new SimulaionResult(EndState.REJECTED, initEnergy, initTheta, initTheta, 0);
return new SimulationResult(EndState.REJECTED, initEnergy, initTheta, initTheta, 0);
}
} else if (initTheta < this.thetaTransport) {
return new SimulaionResult(EndState.REJECTED, initEnergy, initTheta, initTheta, 0);
return new SimulationResult(EndState.REJECTED, initEnergy, initTheta, initTheta, 0);
}
double E = initEnergy;
@ -80,7 +88,7 @@ public class ElectronTrappingSimulator {
while (!stopflag) {
colNum++;
Pair<Double,Double> delta;
Pair<Double, Double> delta;
//Вычисляем сечения и нормируем их на полное сечение
double sigmaIon = scatter.sigmaion(E);
@ -138,12 +146,9 @@ public class ElectronTrappingSimulator {
state = EndState.LOWENERGY;
}
}
SimulaionResult res = new SimulaionResult(state, E, theta, initTheta, colNum);
if (state == EndState.ACCEPTED) {
printOne(System.out, res);
}
return res;
SimulationResult res = new SimulationResult(state, E, theta, initTheta, colNum);
return res;
}
/**
@ -153,15 +158,15 @@ public class ElectronTrappingSimulator {
* @param dTheta
* @return
*/
double addTheta(double theta, double dTheta) {
private double addTheta(double theta, double dTheta) {
//Генерируем случайный фи
double phi = generator.nextDouble()* 2 * Math.PI;
double phi = generator.nextDouble() * 2 * Math.PI;
//Создаем начальный вектор в сферических координатах
SphericalCoordinates init = new SphericalCoordinates(1, 0, theta + dTheta);
// Задаем вращение относительно оси, перпендикулярной исходному вектору
SphericalCoordinates rotate = new SphericalCoordinates(1, 0, theta);
// поворачиваем исходный вектор на dTheta
Rotation rot = new Rotation(rotate.getCartesian(), phi);
Rotation rot = new Rotation(rotate.getCartesian(), phi, null);
Vector3D result = rot.applyTo(init.getCartesian());
@ -169,24 +174,6 @@ public class ElectronTrappingSimulator {
return Math.acos(result.getZ());
}
/**
* Симулируем пролет num электронов.
*
* @param E
* @param num
* @return
*/
public List<SimulaionResult> simulateAll(double E, int num) {
System.out.printf("%nStarting sumulation with initial energy %g and %d electrons.%n%n", E, num);
return Stream.generate(() -> getRandomTheta()).limit(num).parallel()
.map(theta -> simulateOne(E, theta))
.collect(Collectors.toList());
}
public static void printOne(PrintStream out, SimulaionResult res) {
out.printf("%g\t%g\t%g\t%d\t%s%n", res.E, res.theta * 180 / Math.PI, res.initTheta * 180 / Math.PI, res.collisionNumber, res.state.toString());
}
private double normalizeTheta(double theta) {
double res = theta;
if (theta < 0) {
@ -203,24 +190,30 @@ public class ElectronTrappingSimulator {
}
}
public double getRandomTheta() {
double x = generator.nextDouble();
return Math.acos(x);
public void resetDebugCounters(){
scatter.counter.resetAll();
}
public class SimulaionResult {
public void printDebugCounters(){
scatter.counter.print(System.out);
}
public SimulaionResult(EndState state, double E, double theta, double initTheta, int collisionNumber) {
public static class SimulationResult {
public SimulationResult(EndState state, double E, double theta, double initTheta, int collisionNumber) {
this.state = state;
this.E = E;
this.theta = theta;
this.initTheta = initTheta;
this.collisionNumber = collisionNumber;
}
public EndState state;
public double E;
public double initTheta;
public double theta;
public int collisionNumber;
}
}

View File

@ -1,91 +1,13 @@
package inr.numass.trapping;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.List;
/**
* Hello world!
*
*/
public class Trapping {
public static void main(String[] args) throws FileNotFoundException {
PrintStream out = null;
if ((args.length > 0) && (args[0] != null)) {
File file = new File(args[0]);
out = new PrintStream(file);
} else {
}
double E = 18000d;
System.out.println();
ElectronTrappingSimulator simulator = new ElectronTrappingSimulator();
simulator.setFields(0.6, 3.6, 7.2);
int accepted = 0;
int pass = 0;
int rejected = 0;
int lowE = 0;
simulator.scatter.counter.resetAll();
List<ElectronTrappingSimulator.SimulaionResult> results = simulator.simulateAll(E, (int) 1e6);
simulator.scatter.counter.print(System.out);
System.out.printf("%nSimulation complete.%n%n");
for (ElectronTrappingSimulator.SimulaionResult res : results) {
switch (res.state) {
case ACCEPTED:
// ElectronTrappingSimulator.printOne(System.out, res);
if (out != null) {
ElectronTrappingSimulator.printOne(out, res);
}
accepted++;
break;
case LOWENERGY:
lowE++;
break;
case PASS:
pass++;
break;
case REJECTED:
rejected++;
break;
case NONE:
throw new IllegalStateException();
}
}
System.out.printf("%nThe total number of events is %d.%n%n", results.size());
System.out.printf("The spectrometer acceptance angle is %g.%n", simulator.thetaPinch * 180 / Math.PI);
System.out.printf("The transport reflection angle is %g.%n", simulator.thetaTransport * 180 / Math.PI);
System.out.printf("The starting energy is %g.%n", E);
System.out.printf("The lower energy boundary is %g.%n%n", simulator.Elow);
System.out.printf("The total number of ACCEPTED events is %d.%n", accepted);
System.out.printf("The total number of PASS events is %d.%n", pass);
System.out.printf("The total number of REJECTED events is %d.%n", rejected);
System.out.printf("The total number of LOWENERGY events is %d.%n%n", lowE);
if (out != null) {
out.println();
out.printf("The total number of events is %d.%n%n", results.size());
out.printf("The spectrometer acceptance angle is %g.%n", simulator.thetaPinch * 180 / Math.PI);
out.printf("The transport reflection angle is %g.%n", simulator.thetaTransport * 180 / Math.PI);
out.printf("The starting energy is %g.%n", E);
out.printf("The lower energy boundary is %g.%n%n", simulator.Elow);
out.printf("The total number of ACCEPTED events is %d.%n", accepted);
out.printf("The total number of PASS events is %d.%n", pass);
out.printf("The total number of REJECTED events is %d.%n", rejected);
out.printf("The total number of LOWENERGY events is %d.%n%n", lowE);
out.close();
}
// new SimulationManager().withParameters(0.6, 3.7, 7.2, 18000d, 4000).simulateAll((int) 1e6);
new SimulationManager().withParameters(0.6, 3.7, 4.84, 14000d, 4000).simulateAll((int) 1e6);
}
}