카테고리 없음

NaCl의 결정구조를 그려보자

송규 2023. 7. 3. 11:18

이온 결합 물질은 양이온과 음이온이 3차원적으로 결합하여 규칙적인 배열을 갖습니다. 

 

결정이란? 원자, 이온, 분자 등의 입자들이 규칙적으로 배열된 것으로, 이온들이 규칙적으로 배열된 것을 이온 결정이라고 합니다.

 

결정구조로는 단순 입방 구조, 체심 입방 구조, 면심 입방 구조가 있습니다.

 

출처: 하이탑 화학 1 (2권)

 

이중에서 제가 이번에 구현해본 결정인 염화나트륨(NaCl)의 구조는 Na+와 Cl-가 각각 정육면체의 꼭짓점과 각 면심에 위치하는 면심 입방 구조를 가지고 있습니다. 

출처: https://prezi.com/spmzelych0rg/presentation/

이러한 면심 입방 구조를 나타내기 위해서 정보시간에 배운 내용인 matplotlib과 파이썬을 이용해보았습니다.

 

matplotlib으로 3차원에 구를 나타내기 위해서는 x좌표, y좌표, z좌표를 순서대로 입력해주어야 했는데, 이를 모두 입력하기에는 입력해야 하는 값들이 너무 길어질거 같아 반복문과 if문으로 x,y,z에 대한 배열에 들어가는 값을 얻도록 코드를 짜보았습니다.

#include <stdio.h>

int main()
{
   
   int x; // x좌표에 들어갈 값에 대한 코드 
   scanf("%d", &x);
   
   for(int j=0; j<x; j++)
   {
      for(int i=0; i<3; i++) // x좌표를 3칸 안에 지정한다. 
      {
         if(j%3==0)
            printf("20 ");
         else if(j%3==1)
            printf("10 ");
         else if(j%3==2)
            printf("0 ");
         
      }
   }


int y,n; // y좌표에 들어갈 값에 대한 코드 
   scanf("%d", &y);
   
   
   for(int j=0; j<y; j++)
   {
      for(int i=0; i<3; i++) // y좌표를 3칸 안에 지정한다. 
      {
         if(i%3==0)
            printf("20 ");
         else if(i%3==1)
            printf("10 ");
         else if(i%3==2)
            printf("0 ");   
      }
   }

int z; // z좌표에 들어갈 값에 대한 코드 
   scanf("%d", &z);
   
   for(int j=0; j<z/3; j++)
   {
      for(int i=0; i<9; i++)// z좌표를 3칸 안에 지정한다. 
      {
         if(j%3==0)
            printf("20 ");
         else if(j%3==1)
            printf("10 ");
         else if(j%3==2)
            printf("0 ");
         
      }
   }
   
}

 이 코드를 실행시키면 다음과 같은 결과를 얻습니다.

9는 입력받을 좌표의 숫자이고 첫줄부터 순서대로 x,y,z좌표에 대입할 값들입니다.

 

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

plt.rc('font', family='NanumGothic')


xs = np.array([]) #xs라는 배열을 x축에서의 좌표를 갖는 배열로 지정하였습니다.
ys = np.array([]) #ys라는 배열을 y축에서의 좌표를 갖는 배열로 지정하였습니다.
zs = np.array([]) #zs라는 배열을 z축에서의 좌표를 갖는 배열로 지정하였습니다.

def val1(j):  #위에서 C언어로 만들었던 반복문
    if j%3 == 0: 
        return 1
    elif j%3 == 1:
        return 0 
    elif j%3 == 2:
        return -1
    
def val2(j): #위에서 C언어로 만들었던 반복문
    if int(j/9) == 0:
        return 1
    elif int(j/9) == 1:
        return 0
    elif int(j/9) == 2:
        return -1

for i in range(9): #xs라는 배열에 만들어낸 값을 대입하는 코드
    for j in range(3): 
        xs = np.append(xs, val1(i))

for i in range(9): #ys라는 배열에 만들어낸 값을 대입하는 코드
    for j in range(3):
        ys = np.append(ys, val1(j))

for i in range(27): #zs라는 배열에 만들어낸 값을 대입하는 코드
    zs = np.append(zs, val2(i))

radius = np.array([])

for i in range(27): #x,y,z좌표의 값들을 기반으로 원을 그려넣어주는 코드
    if i%2 == 1:
        radius = np.append(radius, 1)
    else:
        radius = np.append(radius, 2)

radius = radius*1000 #원의 크기

color = []

for i in range(27): #Na+와 Cl-이 가지는 원의 색깔을 다르게 대입하는 코드
    if i%2 == 1: 
        color.append('y')
    else:
        color.append('g')

fig = plt.figure(figsize=(6, 6))  #그래프 크기
ax = fig.add_subplot(111, projection='3d') # 3차원에 그리겠다
ax.scatter(xs, ys, zs, c=color, marker='o', s=radius, alpha = 0.7) # x,y,z좌표를 입력받고 색깔과 투명도를 입력받는 코드
ax.set_title("NaCl") # 그래프 이름

plt.show() # 그래프 그리기

위에서 만들었던 코드를 파이썬으로 바꿔서 그대로 대입해줬고, Na+와 Cl-가 갖는 색깔이 다르도록 초록색과 노란색으로 지정하였습니다. 배열에 x,y,z좌표 값들을 차례대로 받아서 그래프를 그릴때 배열을 입력시켜 차례대로 구현하였습니다.

 

위의 코드로 뽑아낸 결과입니다.

 

Na+와 Cl-가 적절히 구분되는것 같고 입체적인 그래프를 2차원으로 보니 위치관계가 명확하지는 않게 보이기는 하는것 같지만 그래도 면심입방구조를 명확하게 알려줄 수 있는것 같습니다.