root / ase / io / exciting.py @ 14
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
|