/
crystal_structures.py
178 lines (139 loc) · 5.07 KB
/
crystal_structures.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
"""
pyscal module for creating crystal structures.
"""
import numpy as np
import warnings
import os
from functools import partial
from functools import update_wrapper
from pyscal.attributes import read_yaml
from pyscal.core import System
from pyscal.structure_creator import make_crystal
structures = read_yaml(os.path.join(os.path.dirname(__file__), "data/structure_data.yaml"))
elements = read_yaml(os.path.join(os.path.dirname(__file__), "data/element_data.yaml"))
#wrapper methods
def structure_creator(structure,
lattice_constant = 1.00,
repetitions = None,
ca_ratio = 1.633,
noise = 0,
element=None):
"""
Create a crystal structure and return it as a System object.
Parameters
----------
structure : {'sc', 'bcc', 'fcc', 'hcp', 'diamond', 'a15' or 'l12'}
type of the crystal structure
lattice_constant : float, optional
lattice constant of the crystal structure, default 1
repetitions : list of ints of len 3, optional
of type `[nx, ny, nz]`, repetions of the unit cell in x, y and z directions.
default `[1, 1, 1]`.
ca_ratio : float, optional
ratio of c/a for hcp structures, default 1.633
noise : float, optional
If provided add normally distributed noise with standard deviation `noise` to the atomic positions.
element : string, optional
The chemical element
Returns
-------
System: pyscal System
system will be populated with given atoms and simulation box
Examples
--------
>>> sys = structure_creator('bcc', lattice_constant=3.48, repetitions=[2,2,2])
"""
return System.from_structure(structure, lattice_constant=lattice_constant,
repetitions=repetitions, ca_ratio=ca_ratio,
noise=noise, element=element)
class Structure:
"""
A class for structure creation
Attributes
----------
element:
create elementary structures
lattice:
create structures by specifying lattice
"""
def __init__(self):
#create by element name
self.element = ElementCreator(elements)
#create by lattice name
self.lattice = LatticeCreator(structures)
#create a general structure
self.custom = general_lattice
#complete dict
self._structure_dict = structures
def structure_dict(self, structure):
return self._structure_dict[structure]
class ElementCreator:
"""
Create an elementary structure
"""
def __init__(self, element_dict):
self._element_dict = element_dict
def __dir__(self):
return list(self._element_dict.keys())
def __getattr__(self, key):
#this is the element based creater
if key in self._element_dict.keys():
structure = self._element_dict[key]['structure']
pfunc = partial(structure_creator, structure,
lattice_constant=self._element_dict[key]['lattice_constant'],
element = key)
update_wrapper(pfunc, structure_creator)
return pfunc
class LatticeCreator(ElementCreator):
"""
Create a lattice
"""
def __getattr__(self, key):
if key in self._element_dict.keys():
pfunc = partial(structure_creator, key)
update_wrapper(pfunc, structure_creator)
return pfunc
#general structure creator
def general_lattice(species, positions,
scaling_factors=[1.0, 1.0, 1.0],
lattice_constant = 1.00,
repetitions = None,
noise = 0,
element=None):
"""
Create a general lattice structure.
species: list
list of per-atom species
positions:
list of relative positions positions of reach atom (between 0-1)
scaling_fractors:
factors with which the unit cell should be scaled, for example hcp could
have [1,1.73, 1.63]. Default [1,1,1]
lattice_constant : float, optional
lattice constant of the crystal structure, default 1
repetitions : list of ints of len 3, optional
of type `[nx, ny, nz]`, repetions of the unit cell in x, y and z directions.
default `[1, 1, 1]`.
noise : float, optional
If provided add normally distributed noise with standard deviation `noise` to the atomic positions.
element : string, optional
The chemical element
"""
if not (len(species) == len(positions)):
raise ValueError("Species and positions should have same length!")
sdict = {"custom":
{"natoms": len(positions),
"species": species,
"scaling_factors": scaling_factors,
"positions": positions}
}
atoms, box = make_crystal("custom", lattice_constant=lattice_constant,
repetitions=repetitions, noise=noise, element=element,
structures=sdict)
sys = System()
sys.box = box
sys.atoms = atoms
sys.atoms._lattice = None
sys.atoms._lattice_constant = lattice_constant
sys._structure_dict = sdict["custom"]
return sys