Generator thread safety fix.

This commit is contained in:
Alexander Nozik 2018-12-03 18:39:03 +03:00
parent c2ad326a77
commit 205bf19452
2 changed files with 38 additions and 34 deletions

View File

@ -1,6 +1,7 @@
package inr.numass.trapping package inr.numass.trapping
import org.apache.commons.math3.analysis.interpolation.LinearInterpolator import org.apache.commons.math3.analysis.interpolation.LinearInterpolator
import org.apache.commons.math3.random.SynchronizedRandomGenerator
import org.apache.commons.rng.UniformRandomProvider import org.apache.commons.rng.UniformRandomProvider
import org.apache.commons.rng.simple.RandomSource import org.apache.commons.rng.simple.RandomSource
import java.io.File import java.io.File
@ -40,12 +41,6 @@ class SimulationManager() {
} }
// from 0 to Pi
private fun getRandomTheta(): Double {
val x = generator.nextDouble()
return Math.acos(1 - 2 * x)
}
// fun setOutputFile(fileName: String) { // fun setOutputFile(fileName: String) {
// val outputFile = File(fileName) // val outputFile = File(fileName)
// if (!outputFile.exists()) { // if (!outputFile.exists()) {
@ -89,11 +84,11 @@ class SimulationManager() {
if (!outputDirectory.exists()) { if (!outputDirectory.exists()) {
outputDirectory.mkdirs() outputDirectory.mkdirs()
} }
val outputPath = outputDirectory.toPath().resolve("$fileName.out")
val output = PrintStream(Files.newOutputStream(outputPath, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE)) val generator = SynchronizedRandomGenerator(RandomGeneratorBridge(generator))
val simulator = Simulator(eLow, thetaTransport, thetaPinch, gasDensity, bSource, magneticField, generator)
val counter = Counter() val counter = Counter()
val simulator = Simulator(eLow, thetaTransport, thetaPinch, gasDensity, bSource, magneticField, RandomGeneratorBridge(generator))
val header = """ val header = """
E_init = $initialE; E_init = $initialE;
@ -101,27 +96,34 @@ class SimulationManager() {
theta_pinch = $thetaPinch; theta_pinch = $thetaPinch;
theta_transport = $thetaTransport; theta_transport = $thetaTransport;
density = $gasDensity; density = $gasDensity;
""".trimIndent() + comment """.trimIndent() + "\n\n" + comment
output.println(header.replace("\n", "\n# "))//adding comment symbols
System.out.printf("%nStarting simulation with initial energy %g and %d electrons.%n%n", initialE, num.toLong()) val outputPath = outputDirectory.toPath().resolve("$fileName.out")
output.printf("%s\t%s\t%s\t%s\t%s\t%s%n", "E", "theta", "theta_start", "colNum", "L", "state") PrintStream(Files.newOutputStream(outputPath, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE)).use { output ->
Stream.generate { getRandomTheta() }.limit(num.toLong()).parallel() output.println("# " + header.replace("\n", "\n# "))//adding comment symbols
.forEach { theta ->
val initZ = (generator.nextDouble() - 0.5) * Simulator.SOURCE_LENGTH System.out.printf("%nStarting simulation with initial energy %g and %d electrons.%n%n", initialE, num.toLong())
val res = simulator.simulate(initialE, theta, initZ) output.printf("%s\t%s\t%s\t%s\t%s\t%s%n", "E", "theta", "theta_start", "colNum", "L", "state")
if (reportFilter(res)) { Stream
.generate {
val theta = Math.acos(1 - 2 * generator.nextDouble())// from 0 to Pi
val z = (generator.nextDouble() - 0.5) * Simulator.SOURCE_LENGTH
simulator.simulate(initialE, theta, z).also { counter.count(it) }
}
.limit(num.toLong()).parallel()
.filter(reportFilter)
.forEach { res ->
printOne(output, res) printOne(output, res)
} }
counter.count(res) }
}
val statisticsPath = outputDirectory.toPath().resolve("$fileName.stat") val statisticsPath = outputDirectory.toPath().resolve("$fileName.stat")
val statisticOutput = PrintStream(Files.newOutputStream(statisticsPath, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE)) PrintStream(Files.newOutputStream(statisticsPath, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE)).use {
statisticOutput.println(header + "\n") it.println(header + "\n")
printStatistics(statisticOutput, simulator, counter) printStatistics(it, simulator, counter)
}
return counter return counter
} }
@ -147,6 +149,7 @@ class SimulationManager() {
private fun printOne(out: PrintStream, res: Simulator.SimulationResult) { private fun printOne(out: PrintStream, res: Simulator.SimulationResult) {
out.printf("%g\t%g\t%g\t%d\t%g\t%s%n", res.E, res.theta * 180 / Math.PI, res.initTheta * 180 / Math.PI, res.collisionNumber, res.l, res.state.toString()) out.printf("%g\t%g\t%g\t%d\t%g\t%s%n", res.E, res.theta * 180 / Math.PI, res.initTheta * 180 / Math.PI, res.collisionNumber, res.l, res.state.toString())
out.flush()
} }

View File

@ -12,24 +12,25 @@ fun main(args: Array<String>) {
// System.out.println("Press any key to start..."); // System.out.println("Press any key to start...");
// System.in.read(); // System.in.read();
val es = listOf(12000.0, 14000.0,16000.0,18000.0) val es = listOf(12000.0, 14000.0, 16000.0, 18000.0)
for(e in es) { val startTime = Instant.now()
val startTime = Instant.now() System.out.printf("Starting at %s%n%n", startTime.toString())
System.out.printf("Starting at %s%n%n", startTime.toString()) for (e in es) {
SimulationManager().apply { SimulationManager().apply {
fileName = "trap[regular]" comment = "Out of the box cross-sections"
generator = RandomSource.create(RandomSource.SPLIT_MIX_64) fileName = "trap[$e]"
generator = RandomSource.create(RandomSource.MWC_256)
setFields(0.6, 3.7, 7.2) setFields(0.6, 3.7, 7.2)
gasDensity = 1e19 gasDensity = 1e19
initialE = e initialE = e
range = 4000.0 range = 4000.0
}.simulateAll(1e6) }.simulateAll(1e6)
val finishTime = Instant.now()
System.out.printf("%nFinished at %s%n", finishTime.toString())
System.out.printf("Calculation took %s%n", Duration.between(startTime, finishTime).toString())
} }
val finishTime = Instant.now()
System.out.printf("%nFinished at %s%n", finishTime.toString())
System.out.printf("Calculation took %s%n", Duration.between(startTime, finishTime).toString())
} }