root / ase / io / xsf.py @ 14
Historique | Voir | Annoter | Télécharger (4,27 ko)
| 1 | 1 | tkerber | import numpy as np |
|---|---|---|---|
| 2 | 1 | tkerber | |
| 3 | 1 | tkerber | from ase.atoms import Atoms |
| 4 | 1 | tkerber | from ase.units import Hartree |
| 5 | 1 | tkerber | from ase.parallel import paropen |
| 6 | 1 | tkerber | from ase.calculators.singlepoint import SinglePointCalculator |
| 7 | 1 | tkerber | |
| 8 | 1 | tkerber | |
| 9 | 1 | tkerber | def write_xsf(fileobj, images, data=None): |
| 10 | 1 | tkerber | if isinstance(fileobj, str): |
| 11 | 1 | tkerber | fileobj = paropen(fileobj, 'w')
|
| 12 | 1 | tkerber | |
| 13 | 1 | tkerber | if not isinstance(images, (list, tuple)): |
| 14 | 1 | tkerber | images = [images] |
| 15 | 1 | tkerber | |
| 16 | 1 | tkerber | fileobj.write('ANIMSTEPS %d\n' % len(images)) |
| 17 | 1 | tkerber | |
| 18 | 1 | tkerber | numbers = images[0].get_atomic_numbers()
|
| 19 | 1 | tkerber | |
| 20 | 1 | tkerber | pbc = images[0].get_pbc()
|
| 21 | 1 | tkerber | if pbc[2]: |
| 22 | 1 | tkerber | fileobj.write('CRYSTAL\n')
|
| 23 | 1 | tkerber | elif pbc[1]: |
| 24 | 1 | tkerber | fileobj.write('SLAB\n')
|
| 25 | 1 | tkerber | elif pbc[0]: |
| 26 | 1 | tkerber | fileobj.write('POLYMER\n')
|
| 27 | 1 | tkerber | else:
|
| 28 | 1 | tkerber | fileobj.write('MOLECULE\n')
|
| 29 | 1 | tkerber | |
| 30 | 1 | tkerber | for n, atoms in enumerate(images): |
| 31 | 1 | tkerber | if pbc.any():
|
| 32 | 1 | tkerber | fileobj.write('PRIMVEC %d\n' % (n + 1)) |
| 33 | 1 | tkerber | cell = atoms.get_cell() |
| 34 | 1 | tkerber | for i in range(3): |
| 35 | 1 | tkerber | fileobj.write(' %.14f %.14f %.14f\n' % tuple(cell[i])) |
| 36 | 1 | tkerber | |
| 37 | 1 | tkerber | fileobj.write('PRIMCOORD %d\n' % (n + 1)) |
| 38 | 1 | tkerber | |
| 39 | 1 | tkerber | # Get the forces if it's not too expensive:
|
| 40 | 1 | tkerber | calc = atoms.get_calculator() |
| 41 | 1 | tkerber | if (calc is not None and |
| 42 | 1 | tkerber | (hasattr(calc, 'calculation_required') and |
| 43 | 1 | tkerber | not calc.calculation_required(atoms,
|
| 44 | 1 | tkerber | ['energy', 'forces', 'stress']))): |
| 45 | 1 | tkerber | forces = atoms.get_forces() |
| 46 | 1 | tkerber | else:
|
| 47 | 1 | tkerber | forces = None
|
| 48 | 1 | tkerber | |
| 49 | 1 | tkerber | pos = atoms.get_positions() |
| 50 | 1 | tkerber | |
| 51 | 1 | tkerber | fileobj.write(' %d 1\n' % len(pos)) |
| 52 | 1 | tkerber | for a in range(len(pos)): |
| 53 | 1 | tkerber | fileobj.write(' %2d' % numbers[a])
|
| 54 | 1 | tkerber | fileobj.write(' %20.14f %20.14f %20.14f' % tuple(pos[a])) |
| 55 | 1 | tkerber | if forces is None: |
| 56 | 1 | tkerber | fileobj.write('\n')
|
| 57 | 1 | tkerber | else:
|
| 58 | 1 | tkerber | fileobj.write(' %20.14f %20.14f %20.14f\n' % tuple(forces[a])) |
| 59 | 1 | tkerber | |
| 60 | 1 | tkerber | if data is None: |
| 61 | 1 | tkerber | return
|
| 62 | 1 | tkerber | |
| 63 | 1 | tkerber | fileobj.write('BEGIN_BLOCK_DATAGRID_3D\n')
|
| 64 | 1 | tkerber | fileobj.write(' data\n')
|
| 65 | 1 | tkerber | fileobj.write(' BEGIN_DATAGRID_3Dgrid#1\n')
|
| 66 | 1 | tkerber | |
| 67 | 1 | tkerber | data = np.asarray(data) |
| 68 | 1 | tkerber | if data.dtype == complex: |
| 69 | 1 | tkerber | data = np.abs(data) |
| 70 | 1 | tkerber | |
| 71 | 1 | tkerber | shape = data.shape |
| 72 | 1 | tkerber | fileobj.write(' %d %d %d\n' % shape)
|
| 73 | 1 | tkerber | |
| 74 | 1 | tkerber | cell = atoms.get_cell() |
| 75 | 1 | tkerber | origin = np.zeros(3)
|
| 76 | 1 | tkerber | for i in range(3): |
| 77 | 1 | tkerber | if not pbc[i]: |
| 78 | 1 | tkerber | origin += cell[i] / shape[i] |
| 79 | 1 | tkerber | fileobj.write(' %f %f %f\n' % tuple(origin)) |
| 80 | 1 | tkerber | |
| 81 | 1 | tkerber | for i in range(3): |
| 82 | 1 | tkerber | fileobj.write(' %f %f %f\n' %
|
| 83 | 1 | tkerber | tuple(cell[i] * (shape[i] + 1) / shape[i])) |
| 84 | 1 | tkerber | |
| 85 | 1 | tkerber | for x in range(shape[2]): |
| 86 | 1 | tkerber | for y in range(shape[1]): |
| 87 | 1 | tkerber | fileobj.write(' ')
|
| 88 | 1 | tkerber | fileobj.write(' '.join(['%f' % d for d in data[x, y]])) |
| 89 | 1 | tkerber | fileobj.write('\n')
|
| 90 | 1 | tkerber | fileobj.write('\n')
|
| 91 | 1 | tkerber | |
| 92 | 1 | tkerber | fileobj.write(' END_DATAGRID_3D\n')
|
| 93 | 1 | tkerber | fileobj.write('END_BLOCK_DATAGRID_3D\n')
|
| 94 | 1 | tkerber | |
| 95 | 1 | tkerber | |
| 96 | 1 | tkerber | def read_xsf(fileobj, index=-1): |
| 97 | 1 | tkerber | if isinstance(fileobj, str): |
| 98 | 1 | tkerber | fileobj = open(fileobj)
|
| 99 | 1 | tkerber | |
| 100 | 1 | tkerber | readline = fileobj.readline |
| 101 | 1 | tkerber | line = readline() |
| 102 | 1 | tkerber | |
| 103 | 1 | tkerber | if line.startswith('ANIMSTEPS'): |
| 104 | 1 | tkerber | nimages = int(line.split()[1]) |
| 105 | 1 | tkerber | line = readline() |
| 106 | 1 | tkerber | else:
|
| 107 | 1 | tkerber | nimages = 1
|
| 108 | 1 | tkerber | |
| 109 | 1 | tkerber | if line.startswith('CRYSTAL'): |
| 110 | 1 | tkerber | pbc = True
|
| 111 | 1 | tkerber | elif line.startswith('SLAB'): |
| 112 | 1 | tkerber | pbc = (True, True, Flase) |
| 113 | 1 | tkerber | elif line.startswith('POLYMER'): |
| 114 | 1 | tkerber | pbc = (True, False, Flase) |
| 115 | 1 | tkerber | else:
|
| 116 | 1 | tkerber | pbc = False
|
| 117 | 1 | tkerber | |
| 118 | 1 | tkerber | images = [] |
| 119 | 1 | tkerber | for n in range(nimages): |
| 120 | 1 | tkerber | cell = None
|
| 121 | 1 | tkerber | if pbc:
|
| 122 | 1 | tkerber | line = readline() |
| 123 | 1 | tkerber | assert line.startswith('PRIMVEC') |
| 124 | 1 | tkerber | cell = [] |
| 125 | 1 | tkerber | for i in range(3): |
| 126 | 1 | tkerber | cell.append([float(x) for x in readline().split()]) |
| 127 | 1 | tkerber | |
| 128 | 1 | tkerber | line = readline() |
| 129 | 1 | tkerber | assert line.startswith('PRIMCOORD') |
| 130 | 1 | tkerber | |
| 131 | 1 | tkerber | natoms = int(readline().split()[0]) |
| 132 | 1 | tkerber | numbers = [] |
| 133 | 1 | tkerber | positions = [] |
| 134 | 1 | tkerber | for a in range(natoms): |
| 135 | 1 | tkerber | line = readline().split() |
| 136 | 1 | tkerber | numbers.append(int(line[0])) |
| 137 | 1 | tkerber | positions.append([float(x) for x in line[1:]]) |
| 138 | 1 | tkerber | |
| 139 | 1 | tkerber | positions = np.array(positions) |
| 140 | 1 | tkerber | if len(positions[0]) == 3: |
| 141 | 1 | tkerber | forces = None
|
| 142 | 1 | tkerber | else:
|
| 143 | 1 | tkerber | positions = positions[:, :3]
|
| 144 | 1 | tkerber | forces = positions[:, 3:] * Hartree
|
| 145 | 1 | tkerber | |
| 146 | 1 | tkerber | image = Atoms(numbers, positions, cell=cell, pbc=pbc) |
| 147 | 1 | tkerber | |
| 148 | 1 | tkerber | if forces is not None: |
| 149 | 1 | tkerber | image.set_calculator(SinglePointCalculator(None, forces, None, |
| 150 | 1 | tkerber | None, image))
|
| 151 | 1 | tkerber | images.append(image) |
| 152 | 1 | tkerber | |
| 153 | 1 | tkerber | return images[index] |