Juliaでスキルミオンを作成

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

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

使用するライブラリ;
LinearAlgebra, GLMakie, GeometryBasics, Colors
``` julia:lib.jl
using LinearAlgebra, GLMakie,GeometryBasics,Colors
```

パラメータ
``` julia: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. スピンを配置する位置のデータを生成
1. 位置をもとにスピンの傾きを表すデータを生成
1. GLMakie.jlでプロット

##
ステップ 1. スピンを配置する位置のデータを生成
``` julia: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. 位置をもとにスピンの傾きを表すデータを生成
``` julia: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/

```julia: 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
```

実行例;
```julia : Skylmion.jl
plot_skyrmion(2.0,10.0,10,40)
```


出力画像；
![skyrmion.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3721322/fefbd551-cb2c-413c-1b51-515d1b32a223.png)


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