root / ase / io / exciting.py @ 18
Historique | Voir | Annoter | Télécharger (3,9 ko)
1 |
"""
|
---|---|
2 |
This is the Implementation of the exciting I/O Functions
|
3 |
The functions are called with read write usunf the format "exi"
|
4 |
|
5 |
The module depends on lxml http://codespeak.net/lxml/
|
6 |
"""
|
7 |
from math import pi, cos, sin, sqrt, acos |
8 |
|
9 |
from ase.atoms import Atoms |
10 |
from ase.parallel import paropen |
11 |
from ase.units import Bohr |
12 |
|
13 |
def read_exciting(fileobj, index=-1): |
14 |
"""Reads structure from exiting xml file.
|
15 |
|
16 |
Parameters
|
17 |
----------
|
18 |
fileobj: file object
|
19 |
Filehandle from which data should be read.
|
20 |
|
21 |
Other parameters
|
22 |
----------------
|
23 |
index: integer -1
|
24 |
Not used in this implementation.
|
25 |
"""
|
26 |
from lxml import etree as ET |
27 |
#parse file into element tree
|
28 |
doc = ET.parse(fileobj) |
29 |
root = doc.getroot() |
30 |
speciesnodes = root.find('structure').getiterator('species') |
31 |
|
32 |
symbols = [] |
33 |
positions = [] |
34 |
basevects = [] |
35 |
atoms = None
|
36 |
#collect data from tree
|
37 |
for speciesnode in speciesnodes: |
38 |
symbol = speciesnode.get('speciesfile').split('.')[0] |
39 |
natoms = speciesnode.getiterator('atom')
|
40 |
for atom in natoms: |
41 |
x, y, z = atom.get('coord').split()
|
42 |
positions.append([float(x), float(y), float(z)]) |
43 |
symbols.append(symbol) |
44 |
basevectsn = doc.xpath('//basevect/text()')
|
45 |
|
46 |
for basevect in basevectsn: |
47 |
x, y, z = basevect.split() |
48 |
basevects.append([float(x) * Bohr, float(y) * Bohr, float(z) * Bohr]) |
49 |
atoms = Atoms(symbols=symbols, cell=basevects) |
50 |
atoms.set_scaled_positions(positions) |
51 |
if 'molecule' in root.find('structure').attrib.keys(): |
52 |
if root.find('structure').attrib['molecule']: |
53 |
atoms.set_pbc(False)
|
54 |
else:
|
55 |
atoms.set_pbc(True)
|
56 |
|
57 |
return atoms
|
58 |
|
59 |
def write_exciting(fileobj, images): |
60 |
"""writes exciting input structure in XML
|
61 |
|
62 |
Parameters
|
63 |
----------
|
64 |
fileobj : File object
|
65 |
Filehandle to which data should be written
|
66 |
images : Atom Object or List of Atoms objects
|
67 |
This function will write the first Atoms object to file
|
68 |
|
69 |
Returns
|
70 |
-------
|
71 |
"""
|
72 |
from lxml import etree as ET |
73 |
if isinstance(fileobj, str): |
74 |
fileobj = paropen(fileobj, 'w')
|
75 |
root = atoms2etree(images) |
76 |
fileobj.write(ET.tostring(root, method='xml',
|
77 |
pretty_print=True,
|
78 |
xml_declaration=True,
|
79 |
encoding='UTF-8'))
|
80 |
|
81 |
def atoms2etree(images): |
82 |
"""This function creates the xml DOM corresponding
|
83 |
to the structure for use in write and calculator
|
84 |
|
85 |
Parameters
|
86 |
----------
|
87 |
|
88 |
images : Atom Object or List of Atoms objects
|
89 |
This function will create a
|
90 |
|
91 |
Returns
|
92 |
-------
|
93 |
root : etree object
|
94 |
Element tree of exciting input file containing the structure
|
95 |
"""
|
96 |
from lxml import etree as ET |
97 |
if not isinstance(images, (list, tuple)): |
98 |
images = [images] |
99 |
|
100 |
root = ET.Element('input')
|
101 |
title = ET.SubElement(root, 'title')
|
102 |
title.text = ''
|
103 |
structure = ET.SubElement(root, 'structure')
|
104 |
crystal= ET.SubElement(structure, 'crystal')
|
105 |
atoms = images[0]
|
106 |
for vec in atoms.cell: |
107 |
basevect = ET.SubElement(crystal, 'basevect')
|
108 |
basevect.text = '%.14f %.14f %.14f' % tuple(vec / Bohr) |
109 |
|
110 |
species = {} |
111 |
symbols = [] |
112 |
for a, symbol in enumerate(atoms.get_chemical_symbols()): |
113 |
if symbol in species: |
114 |
species[symbol].append(a) |
115 |
else:
|
116 |
species[symbol] = [a] |
117 |
symbols.append(symbol) |
118 |
scaled = atoms.get_scaled_positions() |
119 |
for symbol in symbols: |
120 |
speciesnode = ET.SubElement(structure, 'species',
|
121 |
speciesfile='%s.xml' % symbol,
|
122 |
chemicalSymbol=symbol) |
123 |
for a in species[symbol]: |
124 |
atom = ET.SubElement(speciesnode, 'atom',
|
125 |
coord='%.14f %.14f %.14f' % tuple(scaled[a])) |
126 |
return root
|