2012-03-13 45 views
3

实际上,问题在于我试图获取单元格中原子位置的列表并构建相应的超级单元格,给定输入次数以重复细胞在每个方向。更新3D数组时出现意外的行为

这导致循环结构:

#Create Every Unit Cell in SuperCell 
aNum=2 
bNum=2 
cNum=2 
atomPos = copy.deepcopy(atomPositions) 
for l in range(len(atomPos)): 
    index=0 
    for i in range(cNum): 
     for j in range(bNum): 
      for k in range(aNum): 
       for _ in range(numEachAtom[l]): 
        atomPositions[l][index][0] = atomPos[l][index][0] + 1*k 
        atomPositions[l][index][1] = atomPos[l][index][1] + 1*j 
        atomPositions[l][index][2] = atomPos[l][index][2] + 1*i 
        print atomPositions[0][0] 
        index += 1 

atomPositions是3D阵列,使得: atomPositions[atomtype=l][atom=index][atomposition=0] = [x,y,z]和打印语句是用于诊断目的。

问题是,从print语句看来,atomPositions[0][0]的变化比原子类型更频繁,而且索引似乎正确更新,我简直不明白这一点。

为什么atomPositions[0][0]的更改频率比l

最初我遇到了修改正在迭代的列表的问题,因此在开始时深度复制。任何意见将不胜感激!

P.S.这是我第一次问一个问题,我在Python一个完整的初学者,所以请随时对我缺乏格式化/清晰度/风格等发表意见

编辑: 年初的一个例子输出为numEachAtom=[4,6]

[0.17611251675504244, 0.17611251675504244, 0.17611251675504244] 
[0.17611251675504244, 0.17611251675504244, 0.17611251675504244] 
[0.17611251675504244, 0.17611251675504244, 0.17611251675504244] 
[0.17611251675504244, 0.17611251675504244, 0.17611251675504244] 
[1.1761125167550424, 0.17611251675504244, 0.17611251675504244] 
[1.1761125167550424, 0.17611251675504244, 0.17611251675504244] 
[1.1761125167550424, 0.17611251675504244, 0.17611251675504244] 
[1.1761125167550424, 0.17611251675504244, 0.17611251675504244] 
[0.17611251675504244, 1.1761125167550424, 0.17611251675504244] 
[0.17611251675504244, 1.1761125167550424, 0.17611251675504244] 
[0.17611251675504244, 1.1761125167550424, 0.17611251675504244] 

编辑:如何atomPositions被初始化:

#Separate out positions of different atom types 
atomPositions = [] 
counter=0 
for i,atomN in enumerate(numEachAtom):   
    atomPositions.append(origAtomPositions[counter:counter+atomN]) 
    counter += atomN 

编辑:依赖等

import sys 
import scipy as sp 
from scipy import * 
import copy 

编辑: atomPositions [0]初始化为

[[ 0.17611252 0.17611252 0.17611252] 
[ 0.32388748 0.32388748 0.32388748] 
[ 0.42611252 0.42611252 0.42611252] 
[ 0.07388748 0.07388748 0.07388748] 
[ 0.17611252 0.17611252 0.17611252] 
[ 0.32388748 0.32388748 0.32388748] 
[ 0.42611252 0.42611252 0.42611252] 
[ 0.07388748 0.07388748 0.07388748] 
[ 0.17611252 0.17611252 0.17611252] 
[ 0.32388748 0.32388748 0.32388748] 
[ 0.42611252 0.42611252 0.42611252] 
[ 0.07388748 0.07388748 0.07388748] 
[ 0.17611252 0.17611252 0.17611252] 
[ 0.32388748 0.32388748 0.32388748] 
[ 0.42611252 0.42611252 0.42611252] 
[ 0.07388748 0.07388748 0.07388748] 
[ 0.17611252 0.17611252 0.17611252] 
[ 0.32388748 0.32388748 0.32388748] 
[ 0.42611252 0.42611252 0.42611252] 
[ 0.07388748 0.07388748 0.07388748] 
[ 0.17611252 0.17611252 0.17611252] 
[ 0.32388748 0.32388748 0.32388748] 
[ 0.42611252 0.42611252 0.42611252] 
[ 0.07388748 0.07388748 0.07388748] 
[ 0.17611252 0.17611252 0.17611252] 
[ 0.32388748 0.32388748 0.32388748] 
[ 0.42611252 0.42611252 0.42611252] 
[ 0.07388748 0.07388748 0.07388748] 
[ 0.17611252 0.17611252 0.17611252] 
[ 0.32388748 0.32388748 0.32388748] 
[ 0.42611252 0.42611252 0.42611252] 
[ 0.07388748 0.07388748 0.07388748]] 
+1

嘿,这是一个很好的问题!提供一个简短的输出示例可能会有所帮助,以便人们可以以具体的方式查看您的问题。 – Marcin 2012-03-13 10:59:07

+1

如何初始化'atomPositions'? – sth 2012-03-13 10:59:42

+1

你能否为列表的内容提供一个工作示例? – 2012-03-13 11:01:36

回答

1

它看起来非常像你有一个地方乘以你的输入列表。由于这是一个嵌套列表,它不会做你想要的。

+0

我不能相信我没有看到这个,但我发现了罪魁祸首。尽管如此,我发现这种行为非常不直观。谢谢大家花时间在此。 '#expand for Extra Atom for i in range(len(atomPositions)): atomPositions [i] * = aNumber * bNumber * cNumber' – TCTopCat 2012-03-14 00:02:41

+0

我认为必须在发布的代码之外发生任何事情,因为它不会产生任何东西你报告的行为。 – neil 2012-03-14 14:38:03

0

atomPositions[0][0]将改变几次,那是你for _ in range(numEachAtom[l])做什么。

这是什么回路?你不能只写

#Create Every Unit Cell in SuperCell 
aNum=2 
bNum=2 
cNum=2 
atomPos = copy.deepcopy(atomPositions) 
for l in range(len(atomPos)): 
    index=0 
    for i in range(cNum): 
     for j in range(bNum): 
      for k in range(aNum): 
       atomPositions[l][index][0] = atomPos[l][index][0] + numEachAtom[l]*k 
       atomPositions[l][index][1] = atomPos[l][index][1] + numEachAtom[l]*j 
       atomPositions[l][index][2] = atomPos[l][index][2] + numEachAtom[l]*i 
       print atomPositions[0][0] 

编辑:op只是更新他的代码,他在循环中插入索引,所以这没有意义了。

1

我在这里同时使用了itertoolsnumpy这两个非常有用的库,您应该熟悉这些库。问题:

取一个单位单元格中的原子位置列表,并构造一个相应的超级单元格,给定每个方向重复单元格的次数。

下面以任何维度的一般方式回答。为了说明的目的,我使用了二维数组,但如果您将其传递给三维数组,它将很好地工作。您在帖子中使用的四元环被替换为所有可能的单元格方向上的单个循环,其中product。把它拿开,并与它一起玩,看看它是如何工作的。

from numpy import * 
from itertools import product 

# Pass in the points, plus a vector that indicates the repeats in each direction 
def supercell(R, v): 
    v = array(v) + 1 
    n,d = R.shape 

    # Construct the copy directions 
    CV = list(product(*map(range,v))) 
    R2 = zeros((len(CV)*n,d)) 

    for i,cell in enumerate(CV): 
     R2[i*n:(i+1)*n,:] = cell+R 
    return R2 

# Construct some random points within a unit cell to work with 
N,dimension = 100, 2 
# Contrain them so you can see the supercell 
R = random.random((N,dimension))*.6 + .5 

R2 = supercell(R,[2,3]) 

# Plot the results 
from pylab import * 
scatter(*zip(*R2),color='b') 
scatter(*zip(*R),color='r') 
show() 

enter image description here

在你的榜样,在每个正方向的2副本,矢量CV会是什么样子:

[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 1, 0), (0, 1, 1), (0, 1, 2), (0, 2, 0), (0, 2, 1), (0, 2, 2), (1, 0, 0), (1, 0, 1), (1, 0, 2), (1, 1, 0), (1, 1, 1), (1, 1, 2), (1, 2, 0), (1, 2, 1), (1, 2, 2), (2, 0, 0), (2, 0, 1), (2, 0, 2), (2, 1, 0), (2, 1, 1), (2, 1, 2), (2, 2, 0), (2, 2, 1), (2, 2, 2)] 

这是product功能的魔力。

+0

非常感谢,这应该是非常有用的。我以后肯定会玩这个游戏。如果你有任何想法,我会很感激任何关于为什么在问题中发布的代码行为如此奇怪的评论? – TCTopCat 2012-03-13 14:27:25

+0

@TCTopCat我第一次尝试,但我不明白为什么你需要三个单独的索引。我看到从最内层开始:(x,y,z)分界,然后是原子的索引。最外层的索引是没有意义的。在上面的例子中,我的超级单元的形状是'(N,3)',其中'N'是新的原子数。你的例子有'(x,N,3)'。什么是'x'? – Hooked 2012-03-13 14:37:44

+0

atomicPositions的第一个索引指的是原子的类型。它有点复杂,但为了我的输入文件的目的(称为[VASP](http://www.vasp.at/)的密度泛函理论模拟包),我需要进行这种分离以确保新原子位置被写入相同元素的组中的文件。 – TCTopCat 2012-03-13 14:54:30

相关问题