aboutsummaryrefslogtreecommitdiff
path: root/hw2/2-9.jl
blob: 1190c4aedf3019aaf3d74d1e71cb3f8dfd158d31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
using Plots # for plotting trajectory

# simulation parameters
Δt = 0.01 # time step
y_min = 0.0
θ_to_use = [45, 35] # in degrees
v_0 = 700.0 # in m/s

# constants
B_ref_over_m = 4.0 * 10^(-5) # in m-1, at 300K
T_ref = 300.0 # in kelvin
T_0 = 300.0 # in kelvin
g = 9.8 # in m/s^2

# isothermic parameters
y_o = 10 * 10^4 # k_BT/mg in meter

# adiabatic parameters
α = 2.5 # for air
a = 6.5 * 10^(-3) # in kelvin/meter

function adiabatic!(
    x::Vector{Float64}, y::Vector{Float64}, 
    v_y::Vector{Float64}, v_x::Vector{Float64}, 
    t::Vector{Float64}) 
    while y[end] >= y_min
        # decompose previous positions and velocities 
        x_i = x[end]
        y_i = y[end]
        v_x_i = v_x[end]
        v_y_i = v_y[end]

        # calculate new positions
        x_new = x_i + v_x_i * Δt
        y_new = y_i + v_y_i * Δt

        # calculate drag force
        v_i = sqrt(v_x_i^2 + v_y_i^2)
        F_drag = - B_ref_over_m * (T_0 / T_ref)^α *     # temperature variation
            (1 - ((a * y_i) / T_0))^α                   # density/altitude variation
        F_drag_x = F_drag * v_x_i * v_i
        F_drag_y = F_drag * v_y_i * v_i

        # calculate new velocities
        v_x_new = v_x_i + F_drag_x * Δt
        v_y_new = v_y_i + F_drag_y * Δt - g * Δt

        # store new positions and velocities
        push!(x, x_new)
        push!(y, y_new)
        push!(v_x, v_x_new)
        push!(v_y, v_y_new)
        push!(t, t[end] + Δt)
    end
end

function nodensity!(
    x::Vector{Float64}, y::Vector{Float64}, 
    v_y::Vector{Float64}, v_x::Vector{Float64}, 
    t::Vector{Float64}) 
    while y[end] >= y_min
        # decompose previous positions and velocities 
        x_i = x[end]
        y_i = y[end]
        v_x_i = v_x[end]
        v_y_i = v_y[end]

        # calculate new positions
        x_new = x_i + v_x_i * Δt
        y_new = y_i + v_y_i * Δt

        # calculate drag force
        v_i = sqrt(v_x_i^2 + v_y_i^2)
        F_drag = - B_ref_over_m         # coefficient of drag alone
        F_drag_x = F_drag * v_x_i * v_i
        F_drag_y = F_drag * v_y_i * v_i

        # calculate new velocities
        v_x_new = v_x_i + F_drag_x * Δt
        v_y_new = v_y_i + F_drag_y * Δt - g * Δt

        # store new positions and velocities
        push!(x, x_new)
        push!(y, y_new)
        push!(v_x, v_x_new)
        push!(v_y, v_y_new)
        push!(t, t[end] + Δt)
    end
end

# interpolate the last point that's underground
function interpolate!(x::Vector{Float64}, y::Vector{Float64})
    if y[end] == 0
        return # no nothing if y is perfectly on 0
    end

    # calculate x_l, the interpolated x value at y=0
    r = -y[end-1] / y[end]
    x_l = (x[end-1] + r * x[end]) / (1 + r)

    # set final values in the array to interpolated point on ground (y=0    )
    x[end] = x_l
    y[end] = 0.0
end

# setup empty plot to add to
p = plot(xlabel="x (m)", ylabel="y (m)", title="Cannon Shell Trajectory", xlim=(0, 30000), xticks=0:5000:30000, legend=:topright, lw=2)
for θ in θ_to_use
    # arrays to store the trajectory
    x = [0.0]
    y = [0.0]
    v_x = [v_0 * cosd(θ)]
    v_y = [v_0 * sind(θ)]
    t = [0.0]

    # run the simulation
    adiabatic!(x, y, v_y, v_x, t)
    interpolate!(x, y)
    plot_label = "adiabatic, θ = "
    plot!(x, y, label=plot_label, lw=2)

    # reset arrays
    x = [0.0]
    y = [0.0]
    v_x = [v_0 * cosd(θ)]
    v_y = [v_0 * sind(θ)]
    t = [0.0]

    nodensity!(x, y, v_y, v_x, t)
    interpolate!(x, y)
    plot_label = "nodensity, θ = "
    plot!(x, y, label=plot_label, lw=2, linestyle=:dash)
end

# display the plot
display(p)