aboutsummaryrefslogtreecommitdiff
path: root/hw5/plz.jl
blob: d4abcbda006de6c6a0d6ac72facd88c009afdd2f (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
137
138
139
140
141
142
143
144
145
146
147
148
function dynamics!(
    state,
    prev_state,
    params,
    states
)
    # Unpack the parameters
    N, modes, beta, A, dt, num_steps = params

    for i in 1:num_steps
        next_state = zeros(N)

        # update the left particle (set to rest)
        state[1] = 0

        # update the right particle (set to rest)
        state[N] = 0

        # update the middle particles
        for i in 2:N-1
            a = 2 * state[i] - prev_state[i]
            b = dt * dt * (state[i + 1] - 2 * state[i] + state[i - 1])
            c = dt * dt * beta * ((state[i + 1] - state[i])^3 + (state[i - 1] - state[i])^3)
            next_state[i] = a + b + c
        end

        push!(states, next_state)

        # update the previous state
        for i in 1:N
            prev_state[i] = state[i]
        end
        # update the current state
        for i in 1:N
            state[i] = next_state[i]
        end
    end
end

function get_initial_state(
    N,
    modes,
    beta,
    A
)
    state = zeros(N)
    amp = A * sqrt(2 / (N - 1))
    for i in 2:N-1
        state[i] = amp * sin((modes * π * (i - 1)) / (N - 1))
    end
    return state
end

function run_simulation(
    N,
    modes,
    beta,
    A,
    dt,
    num_steps
)
    states = []
    state = get_initial_state(N, 1, beta, A)
    prev_state = zeros(N)
    for i in 1:N
        prev_state[i] = state[i]
    end
    params = (N, modes, beta, A, dt, num_steps)
    dynamics!(state, prev_state, params, states)
    return states
end

# Run the simulation
N = 32 # number of masses
beta = 1.5 # cubic string spring
A = 10 # amplitude
modes = 3 # number of modes to plot
final_time = 50 # seconds
dt = .5 # seconds
num_steps = Int(final_time / dt)
params = (N, modes, beta, A, dt, num_steps)
s = run_simulation(N, modes, beta, A, dt, num_steps)
println("Final state: ", s[end])

# plot the inital positions and the final positions
using Plots
# plot(get_initial_state(N, 1, beta, A), label="Initial", marker=:circle, xlabel="Mass Number", ylabel="Displacement", title="First Three Modes")
# plot!(s[end], label="Final", marker=:circle)

# animate the s array of positions
anim = @animate for i in 1:length(s)
    plot(s[i], label="t = $(i * dt)", marker=:circle, xlabel="Mass Number", ylabel="Displacement", ylim=(-3, 3))
end
gif(anim, "plz.gif", fps = 30)

# function caluclate_energies_for_mode(states, mode)
#     total = []
#     kinetic = []
#     potential = []
#     prev_a_k = 0
#     for i in 1:length(states) - 1
#         total_energy = 0
#         kinetic_energy = 0
#         potential_energy = 0

#         sum = 0
#         for j in 1:length(states[i])
#             sum += states[i][j] * sin((mode * j * π) / (N - 1))
#         end
#         amp = A * sqrt(2 / (N - 1))
#         a_k = amp * sum

#         k = .5 * ((a_k - prev_a_k) / dt)^2
#         if i == 1
#             k = 0
#         end
#         p = (2 * sin((mode * π) / (2 * (N - 1)))^2 * a_k^2)


#         total_energy += k + p
#         kinetic_energy += k
#         potential_energy += p
#         push!(total, total_energy)
#         push!(kinetic, kinetic_energy)
#         push!(potential, potential_energy)

#         prev_a_k = a_k
#     end
#     return total, kinetic, potential
# end

# # calculate the energies for each mode from the displacements
# total_1, kinetic_1, potential_2 = caluclate_energies_for_mode(s, 1)
# total_2, kinetic_2, potential_2 = caluclate_energies_for_mode(s, 2)
# total_3, kinetic_3, potential_3 = caluclate_energies_for_mode(s, 3)

# # build a timestep space
# # timesteps = [i * dt for i in 1:num_steps - 1]
# # # plot the modes energies on the same y-axis
# plot(timesteps, total_1, label="Mode 1", xlabel="Time", ylabel="Energy of Modes", title="Energy Over Time (\$\\beta = 1.5\$)")
# plot!(timesteps, total_2, label="Mode 3")
# plot!(timesteps, total_3, label="Mode 5")

# savefig("modes-beta15.png")