氯化钠 crystal

Sodium chloride crystal

我正在尝试做这个练习:

氯化钠 crystal 钠原子和氯原子排列成立方体 晶格,但原子在钠和氯之间交替,因此每个钠 被六个氯包围,每个氯又被六个钠包围。 使用两种不同的颜色创建氯化钠晶格的可视化图 代表两种原子。

我的代码是:

from vpython import *
from numpy import *

L = 5
R = 0.5
for i in range(-L,L,2):
    for j in range(-L,L,2):
        for k in range(-L,L,2):
            sphere(pos=vector(i,j,k),radius = R, color = vec(0,1,1))

for l in range(-L+1,L+1,2):
    for m in range(-L+1,L+1,2):
        for n in range(-L+1,L+1,2):
            sphere(pos=vector(l,m,n),radius = R, color = vec(1,1,0))

但我得到这个数字:

从这个角度可以看出不正确,因为有相同颜色的列。我做错了什么?

首先,所提供的代码不会生成具有预期方向的良好排列的 crystal 氯化钠晶格。

考虑每个输出的前几个数字。

>>> for i in range(-L,L,2):
...     for j in range(-L,L,2):
...         for k in range(-L,L,2):size = 5
...             print(i, j, k)
... 
-5 -5 -5
-5 -5 -3
-5 -5 -1
...
>>> for l in range(-L+1,L+1,2):
...     for m in range(-L+1,L+1,2):
...         for n in range(-L+1,L+1,2):
...             print(l, m, n)
... 
-4 -4 -4
-4 -4 -2
-4 -4 0
...

如果前一个球体将后一个球体偏移一个单位,则每个球体将有 10 个邻居,而不是 6 个。这解释了为什么球体渲染得相距很远,并且它们似乎每个都有 10 个邻居,因此被尝试的并不是一个紧密堆积的立方晶格,而是全部散开。实际上,你做错的是在你不应该的时候对晶格应用了偏移,在球体之间引入了间隙,使它在视觉上看起来不对劲。

为了正确地做到这一点,慢慢来,一次一步,迭代该层的每个单元格,一次渲染球体。让我们先从二维棋盘图案开始。

改为考虑以下内容:

from vpython import *
from numpy import *

size = 5
radius = 0.5
# predefine the colours
elements = [
    vec(0, 1, 1),
    vec(1, 1, 0),
]

z = 0  # pin z to just a single layer 
for y in range(-size, size):
    for x in range(-size, size):
        sphere(pos=vector(x, y, z), radius=radius, color=elements[(x + y) % 2])

颜色的计算方法是简单地将 x 和 y 相加,然后对结果取模 2 来确定要使用的颜色,因为奇数与偶数的总和将产生奇数(否则它们是偶数),这个数学 属性 渲染出来时将有我们的第一层。 在 Whosebug 上。

原来这个属性也适用于Z层

for z in range(-size, size):
    for y in range(-size, size):
        for x in range(-size, size):
            sphere(pos=vector(x, y, z), radius=radius, color=elements[(x + y + z) % 2])

这将产生您所期望的结果。现在如果你想一起修改半径参数和颜色,你可能想将元素指定为两个字典,可以通过 keyword argument expansion:

传入
size = 5
elements = [
    {'radius': 0.6, 'color': vec(0, 1, 0)},
    {'radius': 0.4, 'color': vec(0.6, 0.1, 1)},
]

for z in range(-size, size):
    for y in range(-size, size):
        for x in range(-size, size):
            sphere(pos=vector(x, y, z), **elements[(x + y + z) % 2])                                                                             

这将模仿 crystal structure diagram for Sodium Chloride that might be found on Wikipedia(旋转视图以更清楚地显示结果)。