1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 """This module contains functions for simple structure manipulation.
16 """
17
18 __id__ = "$Id: supercell_mod.py 3032 2009-04-08 19:15:37Z juhas $"
19
20
21 import numpy
22 from diffpy.Structure import Structure, Atom
23
24
26 """Perform supercell expansion for a structure.
27
28 New lattice parameters are multiplied and fractional coordinates
29 divided by corresponding multiplier. New atoms are grouped with
30 their source in the original cell.
31
32 S -- an instance of Structure from diffpy.Structure.
33 mno -- sequence of 3 integers for cell multipliers along
34 the a, b and c axes.
35
36 Return a new expanded structure instance.
37 Raise TypeError when S is not Structure instance.
38 Raise ValueError for invalid mno argument.
39 """
40
41 if len(mno) != 3:
42 emsg = "Argument mno must contain 3 numbers."
43 raise ValueError, emsg
44 elif min(mno) < 1:
45 emsg = "Multipliers must be greater or equal 1"
46 raise ValueError, emsg
47 if not isinstance(S, Structure):
48 emsg = "The first argument must be a Structure instance."
49 raise TypeError, emsg
50
51
52 mno = (int(mno[0]), int(mno[1]), int(mno[2]))
53
54
55 newS = Structure(S)
56 if mno == (1, 1, 1):
57 return newS
58
59
60 ijklist = [(i,j,k)
61 for i in range(mno[0])
62 for j in range(mno[1])
63 for k in range(mno[2])]
64
65 mnofloats = numpy.array(mno, dtype=float)
66
67
68 newAtoms = []
69 for a in S:
70 for ijk in ijklist:
71 adup = Atom(a)
72 adup.xyz = (a.xyz + ijk)/mnofloats
73 newAtoms.append(adup)
74
75 newS.__setslice__(0, len(newS), newAtoms, copy=False)
76
77
78 newS.lattice.setLatPar(
79 a=mno[0]*S.lattice.a,
80 b=mno[1]*S.lattice.b,
81 c=mno[2]*S.lattice.c )
82 return newS
83
84
85