I revised the algorithm that the program uses to calculate event times to more closely fit the exponential decay function. As can be seen in the chart of the new simulated output above, the original program was off by a factor exceeding 100 for the average energy output in the first 20 minutes. The change in the code did slow the calculations significantly, but correcting this source of error near the beginning and end of each half-life was crucial so that peak radiation levels can be accounted for.
Here is the revised Event.java code:
package Radioactivity; public class Event { // An Event calculates and contains one radiative event /* Variable and Function Nomenclature prescripts: * pv = private * pu = public * pvs = private static * pus = public static * pvsf = private static final * pusf = public static final */ private double pvTime = 0.0; //calculated time of the event referenced from arbitrary start point in seconds private double pvEnergy = 0.0; //user supplied event energy in MeV private String pvType; //user supplied event type (alpha, beta, gamma, neutron) private double pvHalfLife =0.0; //user supplied event half-life in seconds private int pvMaxHalfLives = 20; private double pvTimeOffset = 0.0; //user supplied offset time in seconds //pvDetailedTest is a predefined seive to reduce error in the time calculation private int pvDetailedTest[] = { 1077,2143,3197,4240, 5271,6292,7301,8300, 9287,10265,11231,12187, 13133,14069,14995,15910, 16816,17712,18599,19475, 20343,21201,22050,22889, 23720,24542,25355,26159, 26954,27741,28519,29289, 30051,30805,31550,32287, 33017,33738,34452,35158, 35856,36547,37231,37907, 38576,39238,39892,40540, 41180,41814,42441,43061, 43674,44281,44881,45475, 46062,46643,47218,47786, 48349,48905,49456,50000}; public Event(double halfLife, double energy, String type) { if (energy > 0) { pvEnergy = energy; } else { System.out.println("(Event) construction failed because (Event) input (energy) must be a positive number and greater than zero"); } pvType = type; if (halfLife > 0) { pvHalfLife = halfLife; } else { System.out.println("(Event) construction failed because input (halflife) must be a positive number and greater than zero"); } if (pvHalfLife > 0) { pvTime = pvCalcTime(); } else { System.out.println("(Event) construction failed because (pvTime) cannot be calculated without a defined (halflife)"); } pvMaxHalfLives = 20; pvTimeOffset = 0.0; } public Event(double halfLife, double energy, String type,double timeOffset) { if (timeOffset > 0) { pvTimeOffset = timeOffset; } else { System.out.println("(Event) construction failed because (timeOffset) input must be a positive number and greater than zero"); } if (energy > 0) { pvEnergy = energy; } else { System.out.println("(Event) construction failed because (Event) input (energy) must be a positive number and greater than zero"); } pvType = type; if (halfLife > 0) { pvHalfLife = halfLife; } else { System.out.println("(Event) construction failed because input (halflife) must be a positive number and greater than zero"); } if (pvHalfLife > 0) { pvTime = pvCalcTime(); } else { System.out.println("(Event) construction failed because (pvTime) cannot be calculated without a defined (halflife)"); } pvMaxHalfLives = 20; } public Event(double halfLife, double energy, String type, int maxHalfLives) { if (energy > 0) { pvEnergy = energy; } else { System.out.println("(Event) construction failed because (Event) input (energy) must be a positive number and greater than zero"); } pvType = type; if (halfLife > 0) { pvHalfLife = halfLife; } else { System.out.println("(Event) construction failed because input (halflife) must be a positive number and greater than zero"); } if (maxHalfLives > 0) { pvMaxHalfLives = maxHalfLives; } else { System.out.println("Using default (pvMaxHalfLives) of 20 because the (maxHalfLives) supplied to the constructor was not a positive number and greater than zero"); pvMaxHalfLives = 20; } if (pvHalfLife > 0) { pvTime = pvCalcTime(); } else { System.out.println("(Event) construction failed because (pvTime) cannot be calculated without a defined (halflife)"); } pvTimeOffset = 0.0; } public Event(double halfLife, double energy, String type,double timeOffset, int maxHalfLives) { if (timeOffset > 0) { pvTimeOffset = timeOffset; } else { System.out.println("(Event) construction failed because (timeOffset) input must be a positive number and greater than zero"); } if (energy > 0) { pvEnergy = energy; } else { System.out.println("(Event) construction failed because (Event) input (energy) must be a positive number and greater than zero"); } pvType = type; if (halfLife > 0) { pvHalfLife = halfLife; } else { System.out.println("(Event) construction failed because input (halflife) must be a positive number and greater than zero"); } if (maxHalfLives > 0) { pvMaxHalfLives = maxHalfLives; } else { System.out.println("Using default (pvMaxHalfLives) of 20 because the (maxHalfLives) supplied to the constructor was not a positive number and greater than zero"); pvMaxHalfLives = 20; } if (pvHalfLife > 0) { pvTime = pvCalcTime(); } else { System.out.println("(Event) construction failed because (pvTime) cannot be calculated without a defined (halflife)"); } } private double pvCalcTime() { double seed1 = Math.random(); double seed2 = Math.random(); double seed3 = Math.random(); double weightedLife = Math.pow(2,pvMaxHalfLives); double testWeightedLife = seed1 * weightedLife; double testDetailedLife = seed2 * 50000; double t = 0; int x = 0; while (t == 0) { if (x == (pvMaxHalfLives-1)) { for (int y = 0; y<64;y++) { if (testDetailedLife <= pvDetailedTest[y]){ t = (x+y/64+seed3/64)*pvHalfLife; } } } else if (testWeightedLife <= weightedLife*(1+(x*2))/Math.pow(2,x+1)){ for (int y = 0; y<64;y++) { if (testDetailedLife <= pvDetailedTest[y]){ t = (x+y/64+seed3/64)*pvHalfLife; } } } x+=1; } return (t+pvTimeOffset); } public double puGetTime() { if (pvTime > 0) { return pvTime; } else { System.out.println("(puGetTime) failed because this (Event) does not have a calculated (pvTime)"); return 0; } } public double puGetHalfLife() { if (pvHalfLife > 0) { return pvHalfLife; } else { System.out.println("(puGetHalfLife) failed because this (Event) does not have a proper (pvHalflife) assigned"); return 0; } } public String puGetType() { return pvType; } public double puGetEnergy() { if (pvEnergy > 0) { return pvEnergy; } else { System.out.println("(puGetEnergy) failed because this (Event) does not have a proper (pvEnergy) assigned"); return 0; } } public void puSetHalfLife(double halflife) { if (halflife > 0) { pvHalfLife = halflife; } else { System.out.println("(puSetHalfLife) failed because the (halflife) provided is not greater than zero"); pvHalfLife = 0; } } public void puSetHalfLife(double halflife, int maxhalflives) { if (halflife > 0) { pvHalfLife = halflife; if (maxhalflives > 0) { pvMaxHalfLives = maxhalflives; pvTime = pvCalcTime(); } else { System.out.println("(puSetHalfLife) failed because the (maxhalflives) provided is not greater than zero"); pvMaxHalfLives = 0; pvTime = 0.0; } } else { System.out.println("(puSetHalfLife) failed because the (halflife) provided is not greater than zero"); pvHalfLife = 0; } } public void puSetType(String newtype) { pvType = newtype; } public void puSetEnergy(double energy) { if (energy > 0) { pvEnergy = energy; } else { System.out.println("(puSetEnergy) failed because the (energy) provided is not greater than zero"); pvEnergy = 0; } } }