Ejemplo n.º 1
0
def NormPDF(x,pdf,normalized_to,*other):
    ''' Inputs: x [type=list or vector], pdf [type = function or list or vector], normalized_to [type=float or int], *other are extra parameters that are needed for the pdf fuction used
        Output: a normalized pdf [type = function or vector] '''
    cont = Normalize(x,pdf,normalized_to,*other)
    if callable(pdf) == True:
        return pdf(x,*other)*cont  
    else:
        if isinstance(pdf,type(np.vector([0]))) != True:
            pdf = np.vector(pdf)
        return pdf*cont
Ejemplo n.º 2
0
def Temp(r,time):
    ''' Inputs: Radius [m], Time [s]; Outputs: Temperature of the plasma [keV] '''
    ''' The .2 is the floor temperature that we allow the gas to be '''
    T = T_max*(1-(r/(1.0001*R0))**2)**(2/7)*math.exp(-.5*((time/BurnSigma))**2)
    if isinstance(r,type(np.vector(0))) == True:
        T = list(T)
        for i in range(len(T)):
            if T[i] < .2:            
                T[i] = .2 
        return np.vector(T)
    else:
        if T < .2:
            T = .2
        return T
Ejemplo n.º 3
0
def trapazoid_2_d(function,x_1,x_2,*other):
    I = 0
    del_x = (x_1[-1]-x_2[0])/(2*(len(x_1)-1))
    A = 2*npp.identity(len(x_1))
    A[0][0] , A[-1][-1] = 1 , 1    
    for t in x_2:
        y = function(np.vector(list(x_1)),t,*other)
        I += sum(A.dot(y))*del_x
    return I*((x_2[-1]-x_2[0])/len(x_2))
Ejemplo n.º 4
0
def CrossSection(energy, region):
    """ Energy is neutron energy in eV """
    """ Decides which atom to collide with, records it, calculates that cross section
       and returns it."""
    cross_section = list(
        np.vector(Fits(energy, region)) * Ratio[region]
    )  # this line takes into account the % of substance in the material's effect on the choice of what atom is collided with
    cross_section.append(0), cross_section.insert(0, 0)
    choice = DiscreteChoice(cross_section)
    xc = cross_section[choice + 1] * BarnToCmSquare
    return (xc, choice)
Ejemplo n.º 5
0
def CreateCDF(pdf,a,b,N,normalized_to,*other):
    ''' Generalized CDF Creation from Normalized continious PDF'''
    ''' Inputs: pdf [type = function or vector], a = beginign of domain[type = float or int], b end of domain = [type = float or int], N = [type = int], normalized_to [type = float or int], 
        *other are extra parameters that are needed for the pdf fuction used. 
        Outputs: a list containing the cdf values '''
    if callable(pdf) == True :
        x = np.vector((linspace(a,b,N))) 
        return trapazoid(x,NormPDF(x,pdf,normalized_to,*other),'Cumulative'),x ##############################
    else:
        x = linspace(a,b,len(pdf)-1) 
        return trapazoid(x,NormPDF(x,pdf,normalized_to),'Cumulative'),x    
Ejemplo n.º 6
0
def mini_data_func(position, velocity, energy, region, weighting):
    exponential = 0
    ##vector_sum = position+detector_position
    velocity_vs_detector = velocity.dot(detector_position) / velocity.norm() / detector_position.norm()
    ##velocity_difference = velocity.dot(vector_sum)/velocity.norm()/vector_sum.norm()
    # CM_needed = math.cos(velocity_difference)
    CM_needed = velocity_vs_detector  # math.cos(math.pi - velocity_vs_detector)
    #    print('Velocity_against detector:',math.acos(velocity_vs_detector)*180/math.pi)
    #    print('Center of mass:',math.acos(CM_needed)*180/math.pi)
    #
    def find_prob(region):
        Probs = []
        for choice in range(len(A[region])):
            for i in range(len(Energy_dic_atoms)):
                if A[region][choice] == Energy_dic_atoms[i]:
                    # print('Lab scatter needed:',(1 + A[region][choice]*CM_needed)/math.sqrt((A[region][choice]**2)+1+(2*A[region][choice]*CM_needed)))
                    choice_index = i
                    index_energy = min(
                        range(len(Energy_dic[choice_index])), key=lambda i: abs(Energy_dic[choice_index][i] - energy)
                    )
                    scatter_index = min(
                        range(len(Probability[choice_index][index_energy])),
                        key=lambda i: abs(Cosines[choice_index][index_energy][i] - CM_needed),
                    )
                    Probs.append(Probability[choice_index][index_energy][scatter_index])
        return Probs

    Probs = find_prob(region)

    while position.norm() < Radius[-2]:
        difference = detector_position - position
        region = Geometry(position)
        min_dis = GeometricDistance(position, difference, region)
        if min_dis <= 10e-9:
            """ this is necessary because the GeometricExpansionSphere function find the roots of a polynomial, and 
                finding roots numerically is always difficult and leads to some amount of round off errors, this check
                is to ensure that if you are almost at a boundry there is a good reason to believe that if you are not
                excactly on the boundry, then you are supposed to be on the boundry but round off errors caused you to 
                stay just below the boundry, check accounts for this."""
            position += 1e-9 * difference / difference.norm()
            region = Geometry(position)
            difference = detector_position - position
            min_dis = abs(GeometricDistance(position, difference, region))
        position += min_dis * (difference / difference.norm())
        xc = (np.vector(Fits(energy, region)) * Ratio[region]).average() * BarnToCmSquare  # Average cross section in cm

        exponential += -min_dis * (xc * NDensity[region] / 100)
    weighting *= math.exp(-exponential) * sum(Probs) / len(Probs)
    return weighting
Ejemplo n.º 7
0
fusion_list = [1,1,1]                               # Set to zero to shut off reaction [DT,DD,TT]

Ballabio = 1                                        # Set to 0 for brysk and 1 for ballabio
implosion = 1                                       # Set to 1 for implosion or 0 for static
PeakVelocity = 150E3 
M_hs = 15E-6                                        # Total mass of hot spot in grams

M_ice = 171E-6-M_hs                                 # Mass of ice in grams
CH_rho_r = 200E-3                                   # Rho*R for ablator in g/cm^2

###################################
######## Aparatus Features ########
###################################
''' DT/DT/CH/VACCUM'''
Radius = [25E-6,50E-6,50E-6+70E-6,20,30]                                               # Radius of each region in meters
Density = np.vector([M_hs/(4*math.pi*(Radius[0]*1E2)**3/3),M_ice/(4*math.pi*((Radius[1]*1E2)**3-(Radius[0]*1E2)**3)/3),CH_rho_r/(Radius[2]*1E2-Radius[1]*1E2),1E-10,1E-10]) #g/cm^3 
A = [[2,3],[2,3],[12,1],[1],[1]]                                               # Atomic mass of each substance with that region
Ratio = np.vector([[.5,.5],[.5,.5],[(1/(1+1.3)),(1.3/(1+1.3))],[1],[1]])       # Ratio of each substance that make up material     
''' DT/DT/CH/VACCUM/AL/VACCUM/AIR/W '''
#Radius = [33E-6,53E-6,53E-6+70E-6,.5E-2,.5E-2+.5E-3,11,19.98,20,30]                                               # Radius of each region in meters
#Density = np.vector([M_hs/(4*math.pi*(Radius[0]*1E2)**3/3),M_ice/(4*math.pi*((Radius[1]*1E2)**3-(Radius[0]*1E2)**3)/3),CH_rho_r/(Radius[2]*1E2-Radius[1]*1E2),1E-10,2.7,1E-10,.0012,18.3,1E-10]) #g/cm^3      
#A = [[2,3],[2,3],[12,1],[1],[27],[1],[16,14,40],[183],[1]]                                               # Atomic mass of each substance with that region
#Ratio = np.vector([[.5,.5],[.5,.5],[(1/(1+1.3)),(1.3/(1+1.3))],[1],[1],[1],[.19,.8,.01],[1],[1]])       # Ratio of each substance that make up material
''' DT/DT/CH/VACCUM/AL/VACCUM/AIR '''
#Radius = [33E-6,53E-6,53E-6+70E-6,.5E-2,.5E-2+.5E-3,11,20,30]                                               # Radius of each region in meters
#Density = np.vector([M_hs/(4*math.pi*(Radius[0]*1E2)**3/3),M_ice/(4*math.pi*((Radius[1]*1E2)**3-(Radius[0]*1E2)**3)/3),CH_rho_r/(Radius[2]*1E2-Radius[1]*1E2),1E-10,2.7,1E-10,.0012,1E-10]) #g/cm^3      
#A = [[2,3],[2,3],[12,1],[1],[27],[1],[16,14,40],[1]]                                               # Atomic mass of each substance with that region
#Ratio = np.vector([[.5,.5],[.5,.5],[(1/(1+1.3)),(1.3/(1+1.3))],[1],[1],[1],[.19,.8,.01],[1]]) 

R0 = Radius[0]                                                                                  # Edge radius of neutron production (largest radius at which a neuutron may be born)
MaxRadius = Radius[2] # Where does this implosion stop?
Ejemplo n.º 8
0
def Parallel(NeutronAttributes):
    global collisions, Stepers, Radius
    Energy, radius_now, ThetaEmission, PhiEmission, Theta_momentum, Phi_momentum, reaction = (
        NeutronAttributes[0],
        NeutronAttributes[1],
        NeutronAttributes[2],
        NeutronAttributes[3],
        NeutronAttributes[4],
        NeutronAttributes[5],
        NeutronAttributes[6],
    )
    Position = (
        np.vector([cos(ThetaEmission) * sin(PhiEmission), sin(ThetaEmission) * sin(PhiEmission), cos(PhiEmission)])
        * radius_now
    )
    BirthEnergy = Energy
    Region = (
        0
    )  # For this simulation we assume all neutrons are born in the gas (region=0), the more general case would have be == Region=Geometry(Position)
    steps, collisions_counter = 0, 0
    scatters = []
    Weights = []
    MINI_DATA = []
    Tau_counter = 0
    while Region < len(Radius) - 1:
        collision_pre = collisions_counter
        Position, Tau, Region, Energy, steps, collisions_counter, Theta_momentum, Phi_momentum, Velocity_direction, scatter_atom, Weight, Mini_Data = Transport(
            Position,
            Energy,
            Theta_momentum,
            Phi_momentum,
            Region,
            collisions_counter,
            steps,
            reaction,
            BirthEnergy,
            Tau_counter,
        )
        MINI_DATA.append(Mini_Data)
        if type(Region) == int:
            Region = Geometry(Position)
            Weights.append(Weight)
        else:
            break
        scatters.append(scatter_atom)
        if collisions_counter > collision_pre:
            collisions += 1
        Tau_counter += Tau
        Stepers += steps
    if Region != "Error":
        return MINI_DATA
    else:
        return [
            "Error",
            "Error",
            "Error",
            "Error",
            "Error",
            "Error",
            "Error",
            "Error",
            "Error",
            "Error",
            "Error",
            "Error",
        ]
Ejemplo n.º 9
0
    def mini_transport(
        position,
        energy,
        theta_momentum,
        phi_momentum,
        region,
        collision_counter,
        steps,
        velocity_direction,
        tau,
        scatter_atom,
        weighting,
        reaction,
        Tau,
    ):

        # PUT MINI DATA FUNC HERE

        global COUNT
        tag_transport = 0
        steps += 1

        if energy < 50e3 or steps > 50:
            region = "Error"
            position = np.vector([Radius[-2], 0, 0])
            return (
                position,
                0,
                region,
                energy,
                steps,
                collision_counter,
                theta_momentum,
                phi_momentum,
                velocity_direction,
                0,
                0,
                weighting,
                Tau,
            )

        velocity_direction = np.vector(
            [cos(theta_momentum) * sin(phi_momentum), sin(theta_momentum) * sin(phi_momentum), cos(phi_momentum)]
        )
        Velocity = EnergyToVelocity(energy, Mn) * velocity_direction  # vector
        weighting = mini_data_func(position, Velocity, energy, region, weighting)
        xc = (np.vector(Fits(energy, region)) * Ratio[region]).average() * BarnToCmSquare
        mean_free_path = (1 / NDensity[region] / xc) / 100  # converts cross section into mean free path in meters

        x = np.vector(linspace(0, 5 * mean_free_path, 100))
        step = Choice(BeerLaw(x, mean_free_path), x)

        geometric_distance = GeometricDistance(position, Velocity, region)

        if geometric_distance <= 10e-9:
            """ this is necessary because the GeometricExpansionSphere function find the roots of a polynomial, and 
                finding roots numerically is always difficult and leads to some amount of round off errors, this check
                is to ensure that if you are almost at a boundry there is a good reason to believe that if you are not
                excactly on the boundry, then you are supposed to be on the boundry but round off errors caused you to 
                stay just below the boundry, check accounts for this."""
            position += 1e-9 * Velocity / Velocity.norm()
            return (
                position,
                0,
                region,
                energy,
                steps,
                collision_counter,
                theta_momentum,
                phi_momentum,
                velocity_direction,
                0,
                0,
                weighting,
                Tau,
            )
        if step < geometric_distance:
            COUNT += 1
            collision_counter += 1
            position += step * Velocity / Velocity.norm()
            tau += step / Velocity.norm()
            xc, atom = CrossSection(energy, region)
            mean_free_path = (1 / NDensity[region] / xc) / 100  # converts cross section into mean free path in meters
            cos_theta_CMF, phi, energy = ScatteringAngle(energy, atom, region)
            cos_theta_lab = (1 + A[region][atom] * cos_theta_CMF) / math.sqrt(
                (A[region][atom] ** 2) + 1 + (2 * A[region][atom] * cos_theta_CMF)
            )
            theta_lab = math.acos(cos_theta_lab)
            theta_momentum += theta_lab
            phi_momentum += phi
            scatter_atom = A[region][atom]
        else:
            position += (geometric_distance) * Velocity / Velocity.norm()
            tau += geometric_distance / Velocity.norm()
            tag_transport = 1
        Tau += tau
        return (
            position,
            tau,
            region,
            energy,
            steps,
            collision_counter,
            theta_momentum,
            phi_momentum,
            velocity_direction,
            scatter_atom,
            tag_transport,
            weighting,
            Tau,
        )
Ejemplo n.º 10
0
def Transport(
    position, energy, theta_momentum, phi_momentum, region, collision_counter, steps, reaction, BirthEnergy, Tau
):
    def mini_transport(
        position,
        energy,
        theta_momentum,
        phi_momentum,
        region,
        collision_counter,
        steps,
        velocity_direction,
        tau,
        scatter_atom,
        weighting,
        reaction,
        Tau,
    ):

        # PUT MINI DATA FUNC HERE

        global COUNT
        tag_transport = 0
        steps += 1

        if energy < 50e3 or steps > 50:
            region = "Error"
            position = np.vector([Radius[-2], 0, 0])
            return (
                position,
                0,
                region,
                energy,
                steps,
                collision_counter,
                theta_momentum,
                phi_momentum,
                velocity_direction,
                0,
                0,
                weighting,
                Tau,
            )

        velocity_direction = np.vector(
            [cos(theta_momentum) * sin(phi_momentum), sin(theta_momentum) * sin(phi_momentum), cos(phi_momentum)]
        )
        Velocity = EnergyToVelocity(energy, Mn) * velocity_direction  # vector
        weighting = mini_data_func(position, Velocity, energy, region, weighting)
        xc = (np.vector(Fits(energy, region)) * Ratio[region]).average() * BarnToCmSquare
        mean_free_path = (1 / NDensity[region] / xc) / 100  # converts cross section into mean free path in meters

        x = np.vector(linspace(0, 5 * mean_free_path, 100))
        step = Choice(BeerLaw(x, mean_free_path), x)

        geometric_distance = GeometricDistance(position, Velocity, region)

        if geometric_distance <= 10e-9:
            """ this is necessary because the GeometricExpansionSphere function find the roots of a polynomial, and 
                finding roots numerically is always difficult and leads to some amount of round off errors, this check
                is to ensure that if you are almost at a boundry there is a good reason to believe that if you are not
                excactly on the boundry, then you are supposed to be on the boundry but round off errors caused you to 
                stay just below the boundry, check accounts for this."""
            position += 1e-9 * Velocity / Velocity.norm()
            return (
                position,
                0,
                region,
                energy,
                steps,
                collision_counter,
                theta_momentum,
                phi_momentum,
                velocity_direction,
                0,
                0,
                weighting,
                Tau,
            )
        if step < geometric_distance:
            COUNT += 1
            collision_counter += 1
            position += step * Velocity / Velocity.norm()
            tau += step / Velocity.norm()
            xc, atom = CrossSection(energy, region)
            mean_free_path = (1 / NDensity[region] / xc) / 100  # converts cross section into mean free path in meters
            cos_theta_CMF, phi, energy = ScatteringAngle(energy, atom, region)
            cos_theta_lab = (1 + A[region][atom] * cos_theta_CMF) / math.sqrt(
                (A[region][atom] ** 2) + 1 + (2 * A[region][atom] * cos_theta_CMF)
            )
            theta_lab = math.acos(cos_theta_lab)
            theta_momentum += theta_lab
            phi_momentum += phi
            scatter_atom = A[region][atom]
        else:
            position += (geometric_distance) * Velocity / Velocity.norm()
            tau += geometric_distance / Velocity.norm()
            tag_transport = 1
        Tau += tau
        return (
            position,
            tau,
            region,
            energy,
            steps,
            collision_counter,
            theta_momentum,
            phi_momentum,
            velocity_direction,
            scatter_atom,
            tag_transport,
            weighting,
            Tau,
        )

    global COUNT
    tau, weighting = 0, 1 / math.pi / 4
    velocity_direction = np.vector(
        [cos(theta_momentum) * sin(phi_momentum), sin(theta_momentum) * sin(phi_momentum), cos(phi_momentum)]
    )
    Velocity = EnergyToVelocity(energy, Mn) * velocity_direction  # vector
    if implosion == 1:
        implosion_velocity = interpol(position.norm(), ImplosionRadius, ImplosionVelocity)
        if steps == 0:  # implosion velocity only changes the neutron at birth (aka before any transport so steps==0)
            if position.norm() == 0:  # If its at the center
                implosion_direction = -1 * velocity_direction
            else:
                implosion_direction = -1 * position / radius
            Implosion_Velocity = implosion_velocity * implosion_direction  # Vector
            Velocity = (Velocity + Implosion_Velocity) / (
                1 + (Velocity.norm() * implosion_velocity) / 3e16
            )  # Add them relativistic
            # Velocity += Implosion_Velocity # Add them classically

            Momentum = Mn * (Velocity / 3e8) / math.sqrt(1 - (Velocity.dot(Velocity)) / (3e8) ** 2)
            energy = MomentumToEnergy(Momentum.norm(), Mn) * 1e6

    scatter_atom = 0
    if GeometricDistance(position, Velocity, region) <= 10e-9:
        """ this is necessary because the GeometricExpansionSphere function find the roots of a polynomial, and 
            finding roots numerically is always difficult and leads to some amount of round off errors, this check
            is to ensure that if you are almost at a boundry there is a good reason to believe that if you are not
            excactly on the boundry, then you are supposed to be on the boundry but round off errors caused you to 
            stay just below the boundry, check accounts for this."""
        # region += 1
        position += velocity_direction * 1e-9
    Mini_Data = []
    region = Geometry(position)
    if region == len(Radius) - 1:
        return (
            position,
            0,
            region,
            energy,
            steps,
            collision_counter,
            theta_momentum,
            phi_momentum,
            velocity_direction,
            0,
            0,
            Mini_Data,
        )
    if region == 0:
        while position.norm() <= Radius[region]:
            position, tau, region, energy, steps, collision_counter, theta_momentum, phi_momentum, velocity_direction, scatter_atom, tag_transport, weighting, Tau = mini_transport(
                position,
                energy,
                theta_momentum,
                phi_momentum,
                region,
                collision_counter,
                steps,
                velocity_direction,
                tau,
                scatter_atom,
                weighting,
                reaction,
                Tau,
            )
            # YOUR DATA WRITTEN OUT
            Mini_Data.append(
                [
                    reaction,
                    BirthEnergy / 1e6,
                    collision_counter,
                    scatter_atom,
                    energy / 1e6,
                    ((detector_position.norm() - position.norm()) / EnergyToVelocity(energy, Mn) + tau) / 1e-9,
                    weighting,
                ]
            )
            if tag_transport == 1 or region == "Error":
                break
    else:
        while position.norm() <= Radius[region] and position.norm() >= Radius[region - 1]:
            position, tau, region, energy, steps, collision_counter, theta_momentum, phi_momentum, velocity_direction, scatter_atom, tag_transport, weighting, Tau = mini_transport(
                position,
                energy,
                theta_momentum,
                phi_momentum,
                region,
                collision_counter,
                steps,
                velocity_direction,
                tau,
                scatter_atom,
                weighting,
                reaction,
                Tau,
            )
            # YOUR DATA WRITTEN OUT
            if region == len(Radius) - 1:
                Mini_Data.append(
                    [reaction, BirthEnergy / 1e6, collision_counter, scatter_atom, energy / 1e6, Tau, weighting]
                )
            else:
                Mini_Data.append(
                    [
                        reaction,
                        BirthEnergy / 1e6,
                        collision_counter,
                        scatter_atom,
                        energy / 1e6,
                        ((detector_position.norm() - position.norm()) / EnergyToVelocity(energy, Mn) + tau) / 1e-9,
                        weighting,
                    ]
                )
            if tag_transport == 1 or region == "Error":
                break
    return (
        position,
        tau,
        region,
        energy,
        steps,
        collision_counter,
        theta_momentum,
        phi_momentum,
        velocity_direction,
        scatter_atom,
        weighting,
        Mini_Data,
    )
Ejemplo n.º 11
0
def BeerLaw(x, mean_free_path):
    return 1 - (-1 * x / mean_free_path).exp()


COUNT = 0
count_list = []

MaxImplosionRadius = max(ImplosionRadius)


####################################
#### Create neutron at radius ######
####################################
Number = int(Number)  # Number of neutrons to simulate
# 1 Produced radius shells
Neutron_Radius = np.vector(linspace(0, R0, NumberShells))  # Radius to create neutrons at
Neutron_Time = np.vector(
    linspace(
        -(TotalBurnSigma / 2) * BurnSigma,
        TotalBurnSigma / 2 * BurnSigma,
        math.floor(BurnSigma * TotalBurnSigma / TimeStep),
    )
)  # Times to create neutrons at
N_tot = M_hs * N_A / (Ratio[0][0] * (MH2 - MH3) + MH3)  # Number Density of fuel


### Go To child process to integrate dN/dr/dt
subprocess.call(["python3", "Integration.py"])
### Open file the child process writes out for us
f = open("BirthLocation.txt", "r")
f = f.read().splitlines()
Ejemplo n.º 12
0
###################################################     
number_per_time ,number_per_r = [],[]
t_delta = Neutron_Time[1]-Neutron_Time[0]

''' Normalize the integral '''
Total = trapazoid_2_d(Delta_Number,Neutron_Radius,Neutron_Time,0)

def NORM(radius,time):
    return Delta_Number(radius,time,0)*Number/Total
'''Figure out how many are in each time '''

for time in Neutron_Time:
    them = trapazoid_2_d(NORM,Neutron_Radius,[time,time+t_delta])
    number_per_time.append(them)   
''' Now for that time, figure out how many are at each radius '''
Neutron_Radius = np.vector(list(Neutron_Radius))
Neutron_Time = np.vector(list(Neutron_Time))
index = 0

for number in number_per_time:
    Normeder = NormPDF(Neutron_Radius,Delta_Number,number,Neutron_Time[index],0)
    Number_In = trapazoid(Neutron_Radius,Normeder,'Discrete')
    number_per_r.append(Number_In)
    index+=1
f = open('BirthLocation.txt','w')
for i in number_per_r:
    for j in i:
        if j == i[-1]:          # If this is the last element in the row vector
            f.write('%f\n' % float(j)) # Make a new line after this element 
        else:
            f.write('%f ' % float(j))
Ejemplo n.º 13
0
def PhiPDF(x):
    ''' The neutron creation is assumed isotropic '''
    return np.vector(ones(N_theta))