Updatet architecture
This commit is contained in:
parent
74e58fca80
commit
1f7be09fb2
@ -3,3 +3,7 @@
|
|||||||
\.chg\..*$
|
\.chg\..*$
|
||||||
\.rej$
|
\.rej$
|
||||||
\.conflict\~$
|
\.conflict\~$
|
||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
.idea/*
|
||||||
|
!gradle-wrapper.jar
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
apply plugin: 'maven'
|
apply plugin: 'idea'
|
||||||
apply plugin: 'application'
|
apply plugin: 'application'
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
123
src/main/java/inr/numass/trapping/SimulationManager.java
Normal file
123
src/main/java/inr/numass/trapping/SimulationManager.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -5,9 +5,9 @@
|
|||||||
package inr.numass.trapping;
|
package inr.numass.trapping;
|
||||||
|
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.util.List;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.apache.commons.math3.geometry.euclidean.threed.Rotation;
|
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.SphericalCoordinates;
|
||||||
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
|
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;
|
import org.apache.commons.math3.util.Precision;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Darksnake
|
* @author Darksnake
|
||||||
*/
|
*/
|
||||||
public class ElectronTrappingSimulator {
|
public class Simulator {
|
||||||
|
|
||||||
private RandomGenerator generator;
|
private RandomGenerator generator;
|
||||||
Scatter scatter;
|
private Scatter scatter;
|
||||||
double Elow = 14000d;
|
double Elow = 14000d;//default value
|
||||||
double thetaTransport = 24.107064 / 180 * Math.PI;
|
double thetaTransport = 24.107064 / 180 * Math.PI;// default value
|
||||||
double thetaPinch = 19.481097 / 180 * Math.PI;
|
double thetaPinch = 19.481097 / 180 * Math.PI;// default value
|
||||||
|
|
||||||
|
|
||||||
public ElectronTrappingSimulator() {
|
public Simulator() {
|
||||||
generator = new SynchronizedRandomGenerator(new MersenneTwister());
|
generator = new SynchronizedRandomGenerator(new MersenneTwister());
|
||||||
scatter = new Scatter(generator);
|
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 {
|
public static enum EndState {
|
||||||
|
|
||||||
ACCEPTED,//трэппинговый электрон попал в аксептанс
|
ACCEPTED,//трэппинговый электрон попал в аксептанс
|
||||||
@ -44,7 +49,11 @@ public class ElectronTrappingSimulator {
|
|||||||
NONE
|
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.thetaTransport = Math.asin(Math.sqrt(Bsource / Btransport));
|
||||||
this.thetaPinch = Math.asin(Math.sqrt(Bsource / Bpinch));
|
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 initEnergy > 0;
|
||||||
assert initTheta > 0 && initTheta < Math.PI / 2;
|
assert initTheta > 0 && initTheta < Math.PI / 2;
|
||||||
|
|
||||||
if (initTheta < this.thetaPinch) {
|
if (initTheta < this.thetaPinch) {
|
||||||
if (generator.nextBoolean()) {
|
if (generator.nextBoolean()) {
|
||||||
return new SimulaionResult(EndState.PASS, initEnergy, initTheta, initTheta, 0);
|
return new SimulationResult(EndState.PASS, initEnergy, initTheta, initTheta, 0);
|
||||||
} else {
|
} else {
|
||||||
return new SimulaionResult(EndState.REJECTED, initEnergy, initTheta, initTheta, 0);
|
return new SimulationResult(EndState.REJECTED, initEnergy, initTheta, initTheta, 0);
|
||||||
}
|
}
|
||||||
} else if (initTheta < this.thetaTransport) {
|
} 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;
|
double E = initEnergy;
|
||||||
@ -138,12 +146,9 @@ public class ElectronTrappingSimulator {
|
|||||||
state = EndState.LOWENERGY;
|
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,7 +158,7 @@ public class ElectronTrappingSimulator {
|
|||||||
* @param dTheta
|
* @param dTheta
|
||||||
* @return
|
* @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;
|
||||||
//Создаем начальный вектор в сферических координатах
|
//Создаем начальный вектор в сферических координатах
|
||||||
@ -161,7 +166,7 @@ public class ElectronTrappingSimulator {
|
|||||||
// Задаем вращение относительно оси, перпендикулярной исходному вектору
|
// Задаем вращение относительно оси, перпендикулярной исходному вектору
|
||||||
SphericalCoordinates rotate = new SphericalCoordinates(1, 0, theta);
|
SphericalCoordinates rotate = new SphericalCoordinates(1, 0, theta);
|
||||||
// поворачиваем исходный вектор на dTheta
|
// поворачиваем исходный вектор на dTheta
|
||||||
Rotation rot = new Rotation(rotate.getCartesian(), phi);
|
Rotation rot = new Rotation(rotate.getCartesian(), phi, null);
|
||||||
|
|
||||||
Vector3D result = rot.applyTo(init.getCartesian());
|
Vector3D result = rot.applyTo(init.getCartesian());
|
||||||
|
|
||||||
@ -169,24 +174,6 @@ public class ElectronTrappingSimulator {
|
|||||||
return Math.acos(result.getZ());
|
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) {
|
private double normalizeTheta(double theta) {
|
||||||
double res = theta;
|
double res = theta;
|
||||||
if (theta < 0) {
|
if (theta < 0) {
|
||||||
@ -203,24 +190,30 @@ public class ElectronTrappingSimulator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getRandomTheta() {
|
public void resetDebugCounters(){
|
||||||
double x = generator.nextDouble();
|
scatter.counter.resetAll();
|
||||||
return Math.acos(x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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.state = state;
|
||||||
this.E = E;
|
this.E = E;
|
||||||
this.theta = theta;
|
this.theta = theta;
|
||||||
this.initTheta = initTheta;
|
this.initTheta = initTheta;
|
||||||
this.collisionNumber = collisionNumber;
|
this.collisionNumber = collisionNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EndState state;
|
public EndState state;
|
||||||
public double E;
|
public double E;
|
||||||
public double initTheta;
|
public double initTheta;
|
||||||
public double theta;
|
public double theta;
|
||||||
public int collisionNumber;
|
public int collisionNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,91 +1,13 @@
|
|||||||
package inr.numass.trapping;
|
package inr.numass.trapping;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hello world!
|
* Hello world!
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class Trapping {
|
public class Trapping {
|
||||||
|
|
||||||
public static void main(String[] args) throws FileNotFoundException {
|
public static void main(String[] args) throws FileNotFoundException {
|
||||||
PrintStream out = null;
|
// new SimulationManager().withParameters(0.6, 3.7, 7.2, 18000d, 4000).simulateAll((int) 1e6);
|
||||||
if ((args.length > 0) && (args[0] != null)) {
|
new SimulationManager().withParameters(0.6, 3.7, 4.84, 14000d, 4000).simulateAll((int) 1e6);
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user