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, -7.94584e-6, 4.79379e-5, 0.0] … [0.000654648, 4.27728e-5, -9.48488e-5, 0.0]
[0.000512518, -8.30864e-6, 4.83837e-5, 0.0] [0.000661679, 4.27688e-5, -9.61747e-5, 0.0]
[0.000517534, -8.6792e-6, 4.8833e-5, 0.0] [0.000668789, 4.27554e-5, -9.75188e-5, 0.0]
[0.0005226, -9.05767e-6, 4.92856e-5, 0.0] [0.000675978, 4.27323e-5, -9.88811e-5, 0.0]
[0.000527714, -9.44418e-6, 4.97416e-5, 0.0] [0.000683247, 4.26992e-5, -0.000100262, 0.0]
[0.000532879, -9.83887e-6, 5.0201e-5, 0.0] … [0.000690597, 4.26557e-5, -0.000101662, 0.0]
[0.000538094, -1.02419e-5, 5.06637e-5, 0.0] [0.000698029, 4.26016e-5, -0.00010308, 0.0]
[0.000543359, -1.06534e-5, 5.11299e-5, 0.0] [0.000705543, 4.25364e-5, -0.000104518, 0.0]
[0.000548676, -1.10735e-5, 5.15994e-5, 0.0] [0.00071314, 4.24599e-5, -0.000105975, 0.0]
[0.000554044, -1.15023e-5, 5.20722e-5, 0.0] [0.000720821, 4.23716e-5, -0.000107452, 0.0]
⋮ ⋱
[0.000957248, -0.000203579, -0.000368145, 0.0] [0.00139727, -5.02786e-5, 0.000744218, 0.0]
[0.000949778, -0.000200731, -0.000367227, 0.0] [0.00138513, -4.58471e-5, 0.000739415, 0.0]
[0.000942356, -0.000197901, -0.000366287, 0.0] [0.00137309, -4.14925e-5, 0.0007346, 0.0]
[0.000934983, -0.000195091, -0.000365325, 0.0] [0.00136113, -3.72142e-5, 0.000729776, 0.0]
[0.000927658, -0.0001923, -0.000364342, 0.0] … [0.00134927, -3.30116e-5, 0.000724944, 0.0]
[0.000920382, -0.000189529, -0.000363338, 0.0] [0.0013375, -2.88839e-5, 0.000720104, 0.0]
[0.000913153, -0.000186778, -0.000362314, 0.0] [0.00132582, -2.48306e-5, 0.000715259, 0.0]
[0.000905973, -0.000184046, -0.00036127, 0.0] [0.00131423, -2.08508e-5, 0.000710409, 0.0]
[0.000898842, -0.000181335, -0.000360206, 0.0] [0.00130273, -1.6944e-5, 0.000705555, 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/B4lR8/src/scenes.jl:259
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.