LoginSignup
3
3

Juliaでスキルミオンを作成

Last updated at Posted at 2024-02-23

SkyrmionをJuliaで作成するコード
最も基本的なコードなので、これを応用して色々遊べそうです

中心から離れるほどスピンの数が増えるように設定しています

使用するライブラリ;
LinearAlgebra, GLMakie, GeometryBasics, Colors

lib.jl
using LinearAlgebra, GLMakie,GeometryBasics,Colors

パラメータ

Params.jl
struct Param
    r_min::Float64 # position of spins next origin
    r_max::Float64 # position of spins the most distant from origin
    num_radius::Int64 # number of spins aligned in radius direction
    num_angle::Int64 # maximum number of spins aligned in angular direction
end

ステップ

  1. スピンを配置する位置のデータを生成
  2. 位置をもとにスピンの傾きを表すデータを生成
  3. GLMakie.jlでプロット

ステップ 1. スピンを配置する位置のデータを生成

positioin.jl
function get_position(P::Param)
    #動径方向のデータ
    r = range(P.r_min,P.r_max,length=P.num_radius)

    #円周方向に配置するスピンの数密度
    ρ = 2.0*pi*P.r_max/P.num_angle

    #3Dベクトルデータ[x,y,0.0]を得る
    #スピンの方向が3Dのため、位置も3Dにする必要がある
    position = Vector{Float64}[]
    
    #原点を挿入
    push!(position,Float64[0.0,0.0,0.0])
    
    for i in 1:P.num_radius
        n_θ = round(Int64,2.0*pi*r[i]/ρ)
        θ = range(0.0,2*pi,length=n_θ)
        for j in 1:n_θ
            x = r[i]*cos(θ[j])
            y = r[i]*sin(θ[j])
            push!(position,Float64[x,y,0.0])
        end
    end

    return position
end

ステップ 2. 位置をもとにスピンの傾きを表すデータを生成

get_angle.jl
function create_angle_spins(pos_data)

    #位置データの原点からの距離を r∈[0,1] に規格化
    r = norm.(pos_data)
    r_norm = r./maximum(r)

    #angle_z ∈[0,π]
    angle_z = pi.*r_norm

    #スピンのz軸からの角度
    w = cos.(angle_z)

    #スピンの面内成分
    r_inplane = sin.(angle_z)

    #スピンの方向 (3Dベクトル)
    direction = Vector{Float64}[]

    #スピンの色を調整するためのデータ
    w_data = Float64[]
    
    for i in 1:length(r)
        θ = angle(pos_data[i][1] + im*pos_data[i][2])
        u = r_inplane[i]*cos(θ)
        v = r_inplane[i]*sin(θ)

        push!(direction,Float64[u,v,w[i]])
        push!(w_data,r_norm[i])
    end
    
    return direction,w_data
end

ステップ3. GLMakieでプロット
原点からの距離に応じて色が変わるようにする

カラーデータ : https://docs.makie.org/stable/explanations/colors/

Plot_Skylmion.jl
function plot_skyrmion(r_min,r_max,num_radius,num_angle)

    P = Param(r_min,r_max,num_radius,num_angle)

    pos = get_position(P)
    dir,colors = create_angle_spins(pos)

    #arrowsに適した形式に変換
    position = [Point3f(i) for i in pos]
    direction = [Point3f(i) for i in dir] 

    fig = Figure(resolution=(720, 720), dpi=600)
    ax = Axis3(fig[1,1], aspect=:data, perspectiveness=0.6)

    #スピンの数密度に応じて丁度良い大きさに矢印をスケール
    dence = (P.r_max-P.r_min)/P.num_radius
    scale_arrow = dence*0.6
    s_a = Vec3f0(scale_arrow,scale_arrow,scale_arrow) 

    #距離に応じて色を変更
    cl = HSV.(colors*240, 50, 50)
    
    arrows!(ax, position, direction,          # axes, positions, directions
            linecolor=cl,
            arrowcolor=cl, 
            quality=32,                          # Sets the quaity of the arrow.
            arrowsize=s_a,   # Scales the size of the arrow head. 
            linewidth=dence*0.2, 
            align=:center,)                      # Sets how arrows are positioned.

    # vanish the back ground
    hidedecorations!(ax)
    hidespines!(ax)
    fig

    #save("skyrmion.png",fig)
end

実行例;

Skylmion.jl
plot_skyrmion(2.0,10.0,10,40)

出力画像;
skyrmion.png

Github : https://github.com/KokiMizuno531/Skyrmion.jl

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3