Defining a New Profile
If your profile describes a 3D density distribution, create a new file under the src/densities
directory. If only 2D quantities will be defined, create a new file under src/surface_densities
instead. Let's say I want to define a special type for the singular isothermal sphere, rather than SIS
that creates a GeneralIsothermal
instance. I could create src/sis.jl
and add include("sis.jl")
to src/densities.jl
to make sure the file is loaded. Then, in src/sis.jl
I could define a singular isothermal sphere as
"""
SingularIsothermalSphere(ρ0::Real, rs::Real)
Singular isothermal sphere profile. Fields are `ρ0,rs`.
"""
struct SingularIsothermalSphere{T<:Real} <: AbstractDensity{T}
ρ0::T
rs::T
end
You should add some info about the profile to the docstring. If you are creating a 2D surface density distribution, you should subtype AbstractSurfaceDensity
. You should then define additional constructors for your type. To allow the call signature we listed in the docstring above, define
SingularIsothermalSphere(ρ0::Real, rs::Real) = SingularIsothermalSphere(promote(ρ0, rs)...)
such that we can do
SingularIsothermalSphere(1.0, 1)
Main.SingularIsothermalSphere{Float64}(1.0, 1.0)
It is also common to define constructors that will take the total mass and scale radius as inputs and compute the characteristic density; in this example,ρ0
. See the implementation of GeneralIsothermal
for an example of how to do this.
Now you should define as many methods from the Defined Methods section as you need, starting with methods to retrieve the parameters,
params(d::SingularIsothermalSphere) = (d.ρ0, d.rs)
scale_radius(d::SingularIsothermalSphere) = d.rs
and then evaluation methods like
function ρ(d::SingularIsothermalSphere, r::Real)
ρ0, rs = params(d)
return ρ0 * (r/rs)^-2
end
We avoid accessing the fields of the types directly and use params
and scale_radius
instead so that internal fields of the types can be refactored later if necessary without having to redefine all the accompanying methods.
When you are done writing your methods, you should define methods for your type that allow for Unitful
quantities in the src/units.jl
file. You should be able to follow the examples there with little problem. You should write tests under GalaxyProfiles.jl/test
to validate the behavior of your type and methods. It is recommended that you make a new file, e.g. test/mytype_tests.jl
, then add include("mytype_tests.jl")
to the test/runtests.jl
file. You should then edit src/GalaxyProfiles.jl
to export your new type, in this example SingularIsothermalSphere
.