problem12
12. Canon ball 2. A cannon ball \(m\) is launched at angle \(\theta\) and speed \(v_0\). It is acted on by gravity \(g\) and a quadratic drag with magnitude \(\|cv^2\|\).
- Find a numerical solution using \(\theta = \pi/4\), \(v_0 = 1\) m/s, \(g = 1\) m/s\(^2\), \(m = 1\) kg.
- Numerically calculate (by integrating \(\dot{W} = P\) along with the state variables) the work done by the drag force. Compare this with the change of the total energy. Make a plot showing that the difference between the two goes to zero as the integration gets more and more accurate.
(a) Find a numerical solution using \(\theta = \pi/4\), \(v_0 = 1\) m/s, \(g = 1\) m/s\(^2\), \(m = 1\) kg.
Taking also \(c=1\). The solution comes out to be:
function analytical_sol(t)
= p.mass, p.gravity, p.viscosity
m, g, c
= zeros((4,))
u 1] = vx0 * (-c/m) * (exp((-c/m)*(t-t0)) - 1)
u[2] = ((vy0+(m*g/c))*(-c/m)*(exp((-c/m)*(t-t0)) - 1)) + ((-m*g/c)*(t-t0))
u[3] = (vx0) * (exp((-c/m)*(t-t0)))
u[4] = ((vy0) + (m*g/c)) * exp((-c/m)*(t-t0)) - (m*g/c)
u[
return u
end
(b) Numerically calculate (by integrating \(\dot{W} = P\) along with the state variables) the work done by the drag force. Compare this with the change of the total energy. Make a plot showing that the difference between the two goes to zero as the integration gets more and more accurate.
I take this oppurtunity to implement the ‘slither’ for trajectory similarity, that was introduced in problem03:
module BallisticDrag
import DifferentialEquations
import LinearAlgebra
import GLMakie
@kwdef struct Parameters
::Float64
m::Float64
g::Float64
cend
function myode!(du, u, p, t)
= u[1:2]
r = u[3:4]
v = v / LinearAlgebra.norm(v)
vcap
= [0;1]
j = (p.m*p.g)*(-j)
gravity = abs(p.c*LinearAlgebra.dot(v, v))*(-vcap)
drag = gravity+drag
F = F / p.m
a
= LinearAlgebra.dot(drag, v)
drag_power
1:2] = v
du[3:4] = a
du[5] = drag_power
du[end
= Parameters((global m=1), (global g=1), (global c=1))
p = (0.0, (global tend=10.0))
tspan = [0.0;0.0;10.0;10.0;0.0]
u0 = DifferentialEquations.ODEProblem(myode!, u0, tspan, p)
odeprob
function tae_diff(tolerance)
= (DifferentialEquations.solve(odeprob; abstol=tolerance, reltol=tolerance))
sol = length(sol.t)
tpoints
= reduce(hcat, sol.u)'
sol
= sol[:, 5]
work = work[2:end] .- work[1:end-1]
work_change
= sol[:, 3:4]
v = (1/2)*(m)*([LinearAlgebra.dot(v[i, :], v[i, :]) for i in 1:size(v, 1)])
kinetic = sol[:, 2]
y = (m*g)*y
potential = kinetic .+ potential
total = total[2:end] .- total[1:end-1]
change
return sum(abs.(change .- work_change)) # / tpoints
end
# Plot (energy - workdone) TAE (total absolute error) with increasing accuracies
= -range(6, 12)
powers = 10.0.^powers
tolerances = tae_diff.(tolerances)
tae_energy_change
= GLMakie.Figure()
fig = GLMakie.Axis(fig[1,1], title="log(Tolerance) vs Total Energy Change minus Drag Work Done")
ax lines!(ax, powers, tae_energy_change)
GLMakie.save("tolerances_vs_total_energy_change_minus_drag_work_done.png", fig)
GLMakie.display(fig)
GLMakie.
end # module BallisticDrag
This produces the following graph:
This concludes my attempt of problem12.