Revised Code for Radioactivity Simulation With Improved Algorithm v0.02

output2I 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;
        }
    }
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s