LoginSignup
0
1

Juliaで任意の結晶構造をプロット

Last updated at Posted at 2024-02-23

使用するライブラリ

  • LinerAlgebra : 線形代数用
  • GLMakie : Plot用
Library.jl
using LinearAlgebra, GLMakie,GeometryBasics

与えるデータ ;
unit cellに含まれる格子点の座標
基本並進ベクトルのデータ (3d)

data.jl
#unit cell内格子点のデータ
o = [0.0,0.0,0.0] #原点は必須
t1 = [0.5,0.0,0.5] #c軸に並行な点は上手くいかない
t2 = [0.2,0.1,0.0]
t3 = [0.3,0.3,0.0]


#基本並進ベクトルのデータ
a1 = [1/2,-√3/2,0.0]
b1 = [1/2,√3/2,0.0]
c1 = [0.0,0.0,1.0]

step1 : 格子点のデータを生成
与えるデータ;
unit cellの数 (xy平面内 $\geq$ 1)
Layer数 (c軸方向に並べる数 $\geq$ 1 )

Lattice.jl
#make data of lattice point
#make_lattice([lattice in unit cell], number of unit cell, [primitive vectors])
function make_lattice(cell,num_cell::Int64,Layer::Int64,primitive)
    vects = []
    dist = []
    

    #格子点プロットの大きさ
    rad = minimum(norm.(primitive))/5
    
    #Lattce data
    Lattice = []

    #線を引かない点のデータ
    rem_num = []
    for i in 0:num_cell
        for j in 0:num_cell
            for k in 0:Layer-1
                vec = i*primitive[1] + j*primitive[2] + k*primitive[3]
                if i == num_cell || j == num_cell || k == Layer-1 
                    push!(Lattice,cell[1] + vec)
                    push!(rem_num,length(Lattice))
                else
                    for n in 1:length(cell)
                        push!(Lattice,cell[n] + vec)
                        if n == 1
                            push!(rem_num,length(Lattice))
                        end
                    end
                end
            end
        end
    end

    #site number
    site = size(Lattice)[1]

    #primitive vectorと等しい距離、かつ、unit cell境界の点を記録
    edge_mat = zeros(Int64,site,site)
    for i in 1:site
        for j in 1:site
            d = Lattice[i] - Lattice[j]
            θ = zeros(length(primitive))
            for N in 1:length(primitive)
                prod = dot(d,primitive[N])/(norm(d)*norm(primitive[N]))
                if abs(prod) <= 1.0
                    θ[N] = acos(prod)
                else
                    θ[N] = 0.0
                end
            end
            
            edge = norm(d)

            cond = minimum((edge .- norm.(primitive)))<= 0.01 && abs(minimum(θ)) <= 0.01
            
            if in(i,rem_num) && in(j,rem_num) && cond
                edge_mat[i,j] = 1
            end
        end
    end

    println(length(findall(edge_mat.!= 0 )))
    println(length(rem_num))

    return Lattice,edge_mat,rad
end

#格子点間に引く線のデータ
function get_Graph_Edges3D(Lattice,edge_mat)
    #格子点間に引く線のデータ
    xyzos = []


    for i in 1:length(Lattice)
        for j in 1:length(Lattice)
            if edge_mat[i, j] != 0
                push!(xyzos, Lattice[i])
                push!(xyzos, Lattice[j])
            end
        end
    end
    return (Point3f.(xyzos))
end


#plot用の関数
function plotGraph3D(cell,num_cell::Int64,Layer::Int64,primitive)
    Lattice,edge_mat,rad = make_lattice(cell,num_cell,Layer,primitive)
    
    segm, weights = getGraphEdges3D(Lattice,edge_mat)

    #格子点のデータを meshscatter用に変換
    position_t = []
    for i in 1:length(Lattice)
        push!(position_t,tuple(Lattice[i]...))
    end
    position_t=convert(Vector{Tuple{Float64,Float64,Float64}},position_t)

    #plot
    #格子点間の線をプロット
    fig = Figure(resolution=(720, 720), dpi=600)
    ax = Axis3(fig[1,1], aspect=:data, 
        perspectiveness=0.6,
        azimuth = 0.2 * pi,elevation = 0.2 * pi)
    #azimuth, elevation : set view point
    
    linesegments!(ax,segm,show_axis=false)
    
    
    #格子点上に半径radの球をplot
    meshscatter!(ax,position_t,
            markersize = rad,show_axis=false
            )   
    hidedecorations!(ax)
    hidespines!(ax)

    
    
    fig
    
    #pngに出力
    save("Lattice.png",fig)
end

実行例

data.jl
#unit cell 内の格子点
o = [0.0,0.0,0.0]
t1 = [0.5,0.0,0.75]

#基本並進ベクトルのデータ
a1 = [1/2,-√3/2,0.0]
b1 = [1/2,√3/2,0.0]
c1 = [0.0,0.0,1.5]

#unit cell = 3
#layer = 2 
plotGraph3D([o,t1],3,2,[a1,b1,c1])

結果
Lattice.png

0
1
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
0
1