Last active
November 9, 2023 00:31
-
-
Save dlakelan/d3722e621495666803dc9aafd60a956a to your computer and use it in GitHub Desktop.
Galactic rotation curve Newton's calc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using HCubature, LinearAlgebra, StatsPlots, QuadGK, StaticArrays | |
# Define a function that describes the density | |
# as a function of the radial distance from the center of the galaxy. This is a | |
# dimensionless quantity (mass/area) / (mass/area at zero distance) | |
# r is a dimensionless distance, radius as a fraction of the galactic scale radius | |
function rho(x) | |
exp(-sqrt(x[1]^2+x[2]^2)-5.0*abs(x[3])) | |
end | |
## given a test particle at position r which is a vector [a,b] | |
## (I use [r,0.0] when I call the function below) | |
## return a function f(x) which when given another point x as a vector | |
## in the galaxy computes the vector | |
## force that the point x exerts on the test particle at r. | |
## Note that we ignore all mass within radius around .01 of the test particle, otherwise we have | |
## a singularity of "self gravitation" at zero distance. | |
function integrand(r,eps) | |
function f(x) | |
n = norm(x-r) | |
#(1.0-exp(-(n/eps)^2))* # no self gravity | |
(n > eps)* | |
rho(x)*(x-r)/n^3 # cubed because (r-x)/norm(r-x) is the direction 1/norm(r-x)^2 is magnitude | |
end | |
f | |
end | |
## hcubature is a function which when given a function and an N dimensional "box" | |
## (by the coordinates of two opposite corners of the box) computes the integral over the entire | |
## box of the integrand times differential volume in N dimensions. This is a test call | |
hcubature(integrand(SVector(1.0,0.0,0.0),.005),[-100.0,-100.0,-1.0],[100.0,100.0,1.0]; maxevals=100_000,rtol=.00125) | |
function rho2(x) | |
r = norm(x) | |
return 1.0/(1.0+r) #*(r < 10.0) | |
end | |
function integrand2(r,eps) | |
function f(x) | |
n = norm(x-r) | |
(n > eps)* # no self gravity | |
rho2(x)*(x-r)/n^3 # cubed because (r-x)/norm(r-x) is the direction 1/norm(r-x)^2 is magnitude | |
end | |
f | |
end | |
hcubature(integrand2(SVector(1.2,0.0,0.0),.1),[-2.0,-2.0,-.10],[2.0,2.0,.10]; maxevals=100_000,rtol=.00125) | |
# try out some radii, from 0.1 to 10 galactic scale lengths | |
rvals = collect(0.1:0.1:13.0) | |
# calculate the accelerations experienced by test particle at location r for each r in rvals | |
accels = map(r -> hcubature(integrand([r,0.0,0.0],.02),[-100.0,-100.0,-5.0],[100.0,100.0,5.0]; maxevals=1_000_000,rtol=0.000125),rvals) | |
## calculate the mass of the disk inside the radius R for each R in rvals using quadgk | |
## Since this is a calculation over a disk, it's easier to perform along a radius rather than hcubature | |
## over a circular region | |
accels2 = map(r -> hcubature(integrand2(SVector(r,0.0,0.0),.002),[-20.0,-20.0,-.20],[20.0,20.0,.20],maxevals=1_000_000,rtol=.000125),rvals) | |
masses = map(R->quadgk(r -> rho([0.0,r,0.0])*2*pi*r,0,R)[1],rvals) | |
## plots of the various quantities | |
plot(rvals,[sqrt(rvals[i]*norm(accels[i][1])) for i in eachindex(rvals)]; | |
title= "Velocity vs Radius", xlab="Radius (fraction of avg galactic radius)", ylab="Velocity (dimensionless)") |> display | |
plot(rvals,[sqrt(rvals[i]*norm(accels2[i][1])) for i in eachindex(rvals)]; | |
title= "Velocity vs Radius", xlab="Radius (fraction of avg galactic radius)", ylab="Velocity (dimensionless)") |> display | |
plot(rvals,masses; title="Masses at Radius R",xlab="R",ylab="Mass") |>display | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment