Creating a Custom Dual Cone Model
We will define a custom model for low luminosity active galactic nuclei (LLAGN). A detailed description of the model can be found in this reference. We will show the emission of the n=0 (direct) and n=1 (indirect) photons as they are emitted from the source, at a fixed inclination angle from the black hole's spin axis.
First, we will import Krang and specify the spacetime. We will use a Kerr black hole of 0.94 spin.
using Krang
metric = Krang.Kerr(0.94);Let's create a camera with a resolution of 400x400 pixels viewed by an asymptotic observer at an inclination angle of
θo = 17 * π / 180;
ρmax = 10.0;
camera = Krang.IntensityCamera(metric, θo, -ρmax, ρmax, -ρmax, ρmax, 400);We will need to create Mesh objects to render the scene. First, we will create the material for the mesh. Our material will be the ElectronSynchrotronPowerLawPolarization material with the following parameters.
χ = -1.7;
ι = 0.58;
βv = 0.87;
σ = 0.73;
η1 = 2.64;
η2 = π - η1;These will be used to define the magnetic field and fluid velocity.
magfield1 = Krang.SVector(sin(ι) * cos(η1), sin(ι) * sin(η1), cos(ι));
magfield2 = Krang.SVector(sin(ι) * cos(η2), sin(ι) * sin(η2), cos(ι));
vel = Krang.SVector(βv, (π / 2), χ);
R = 4.0;
p1 = 1.0;
p2 = 4.0;Finally, we define the materials for each of the cones
material1 = Krang.ElectronSynchrotronPowerLawPolarization(
magfield1...,
vel...,
σ,
R,
p1,
p2,
(0, 1),
);
material2 = Krang.ElectronSynchrotronPowerLawPolarization(
magfield2...,
vel...,
σ,
R,
p1,
p2,
(0, 1),
);Next we will define the geometries of each mesh. We will use a ConeGeometry with an opening angle of
θs = (75 * π / 180);
geometry1 = Krang.ConeGeometry(θs)
geometry2 = Krang.ConeGeometry(π - θs)Krang.ConeGeometry{Float64, Nothing}(1.832595714594046, nothing)We will create two meshes, one for each geometry anc create a scene with both meshes.
mesh1 = Krang.Mesh(geometry1, material1)
mesh2 = Krang.Mesh(geometry2, material2)Krang.Mesh{Krang.ConeGeometry{Float64, Nothing}, Krang.ElectronSynchrotronPowerLawPolarization{2, Float64}}(Krang.ConeGeometry{Float64, Nothing}(1.832595714594046, nothing), Krang.ElectronSynchrotronPowerLawPolarization{2, Float64}([0.48051719214341965, 0.2635023023646423, 0.8364626499151869], [0.87, 1.5707963267948966, -1.7], 0.73, 4.0, 1.0, 4.0, (0, 1)))Finally, we will render the scene with the camera
scene = Krang.Scene((mesh1, mesh2))
stokesvals = render(camera, scene)400×400 Matrix{PolarizedTypes.StokesParams{Float64}}:
[0.000507551, -1.6557e-5, 3.96302e-5, 0.0] … [0.000654648, 4.66722e-5, -7.31546e-5, 0.0]
[0.000512518, -1.69595e-5, 3.99841e-5, 0.0] [0.000661679, 4.68268e-5, -7.42712e-5, 0.0]
[0.000517534, -1.73695e-5, 4.03405e-5, 0.0] [0.000668789, 4.69755e-5, -7.54045e-5, 0.0]
[0.0005226, -1.77871e-5, 4.06994e-5, 0.0] [0.000675978, 4.71181e-5, -7.65549e-5, 0.0]
[0.000527714, -1.82124e-5, 4.10609e-5, 0.0] [0.000683247, 4.72542e-5, -7.77226e-5, 0.0]
[0.000532879, -1.86456e-5, 4.14249e-5, 0.0] … [0.000690597, 4.73836e-5, -7.89077e-5, 0.0]
[0.000538094, -1.90868e-5, 4.17914e-5, 0.0] [0.000698029, 4.7506e-5, -8.01106e-5, 0.0]
[0.000543359, -1.95361e-5, 4.21604e-5, 0.0] [0.000705543, 4.76211e-5, -8.13314e-5, 0.0]
[0.000548676, -1.99936e-5, 4.2532e-5, 0.0] [0.00071314, 4.77288e-5, -8.25703e-5, 0.0]
[0.000554044, -2.04596e-5, 4.2906e-5, 0.0] [0.000720821, 4.78285e-5, -8.38276e-5, 0.0]
⋮ ⋱
[0.000957248, -0.000197415, -0.000363053, 0.0] [0.00139727, -5.74436e-5, 0.000712072, 0.0]
[0.000949778, -0.000194633, -0.000362109, 0.0] [0.00138513, -5.30909e-5, 0.000707627, 0.0]
[0.000942356, -0.000191868, -0.000361143, 0.0] [0.00137309, -4.88118e-5, 0.000703167, 0.0]
[0.000934983, -0.000189124, -0.000360157, 0.0] [0.00136113, -4.46059e-5, 0.000698695, 0.0]
[0.000927658, -0.000186398, -0.00035915, 0.0] … [0.00134927, -4.04724e-5, 0.000694211, 0.0]
[0.000920382, -0.000183692, -0.000358124, 0.0] [0.0013375, -3.64108e-5, 0.000689717, 0.0]
[0.000913153, -0.000181005, -0.000357078, 0.0] [0.00132582, -3.24206e-5, 0.000685213, 0.0]
[0.000905973, -0.000178339, -0.000356013, 0.0] [0.00131423, -2.8501e-5, 0.000680702, 0.0]
[0.000898842, -0.000175692, -0.00035493, 0.0] [0.00130273, -2.46515e-5, 0.000676184, 0.0]We will import CairoMakie for plotting the results.
import CairoMakie as CMk
curr_theme = CMk.Theme(
Axis = (
xticksvisible = false,
xticklabelsvisible = false,
yticksvisible = false,
yticklabelsvisible = false,
),
)
CMk.set_theme!(merge!(curr_theme, CMk.theme_latexfonts()))
fig = CMk.Figure(resolution = (700, 700));
ax1 = CMk.Axis(fig[1, 1], aspect = 1, title = "I")
ax2 = CMk.Axis(fig[1, 3], aspect = 1, title = "Q")
ax3 = CMk.Axis(fig[2, 1], aspect = 1, title = "U")
ax4 = CMk.Axis(fig[2, 3], aspect = 1, title = "V")
colormaps = [:afmhot, :redsblues, :redsblues, :redsblues]
hms =
zip(
[ax1, ax2, ax3, ax4],
[
getproperty.(stokesvals, :I),
getproperty.(stokesvals, :Q),
getproperty.(stokesvals, :U),
getproperty.(stokesvals, :V),
],
colormaps,
) .|> x -> CMk.heatmap!(x[1], x[2], colormap = x[3], rasterize = true)
CMk.Colorbar(fig[1, 2], hms[1], labelsize = 20)
CMk.Colorbar(fig[1, 4], hms[2], labelsize = 20)
CMk.Colorbar(fig[2, 2], hms[3], labelsize = 20)
CMk.Colorbar(fig[2, 4], hms[4], labelsize = 20)
fig
CMk.save("polarization_example.png", fig)┌ Warning: Found `resolution` in the theme when creating a `Scene`. The `resolution` keyword for `Scene`s and `Figure`s has been deprecated. Use `Figure(; size = ...` or `Scene(; size = ...)` instead, which better reflects that this is a unitless size and not a pixel resolution. The key could also come from `set_theme!` calls or related theming functions.
└ @ Makie ~/.julia/packages/Makie/dVJIx/src/scenes.jl:264
You can also save the rendered image as a fits file for further analysis.
using Comrade
grid = imagepixels(μas2rad(120), μas2rad(120), 400, 400)
Comrade.save_fits(joinpath((@__DIR__), "polarized_models.fits"), IntensityMap(stokesvals,grid))This page was generated using Literate.jl.