Supporting scripts¶
Generating input files for force matching¶
The prepare_configurations_for_force_matching.py script that can be found in the utility_scripts directory allows one to create structure files that contain not only positions but also forces suitable for force matching. The script reads an atomic simulation environment (ASE) compatible input file containing one or more configurations of positions and forces, e.g. a VASP OUTCAR file or a .traj file. It then writes one or more corresponding files in a modified POSCAR format that includes forces, which is suitable for force matching using atomicrex.
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 | #!/usr/bin/env python
# PE, 2015/06/04
description_string =
"""The script reads an ASE compatible input file containing one or
more configurations of positions and forces, e.g. a VASP OUTCAR file
or a .traj file. It then writes one or more corresponding files in a
POSCAR like format including forces, which is suitable for force
matching using the atomicrex code.
"""
from ase import *
from ase.io import *
#------------------------------------------------
# Handle the command line
import argparse
parser = argparse.ArgumentParser(description=description_string)
parser.add_argument('filename', help='input structure in ASE readable format; the file can contain multiple configurations')
parser.add_argument('-o', '--outfile', default='FPOSCAR.new', help='name of output file')
args = parser.parse_args()
#------------------------------------------------
def write_configuration(outfile, conf, direct=False, comment='', form='%21.16f'):
with open(outfile, 'w') as f:
# Element names
elements = []
for elem in conf.get_chemical_symbols():
if not elem in elements: elements.append(elem)
# Comment line (here we store the energy per atom)
energy = conf.get_potential_energy()
energy /= conf.get_number_of_atoms()
f.write('%.6g\n' % energy)
# Cell metric
f.write('1.0\n')
for vec in conf.cell:
for v in vec: f.write((' '+form) % v)
f.write('\n')
# Element names
for elem in elements: f.write(' %2s' % elem)
f.write('\n')
# Number of elements per type
for elem in elements:
f.write(' %d' % conf.get_chemical_symbols().count(elem))
f.write('\n')
# Scaled or cartesian coordinates
if direct:
coordinates = atoms.get_scaled_positions()
f.write('Direct\n')
else:
coordinates = conf.get_positions()
f.write('Cartesian\n')
# Coordinates and forces
for coord,force in zip(coordinates, conf.get_forces()):
for r in coord: f.write((' '+form) % r)
f.write(' ')
for r in force: f.write((' '+form) % r)
f.write('\n')
#------------------------------------------------
# Read and write configuration
fname = args.filename
try:
confs = read(fname, ':')
except:
print "ERROR: file %s could not be read"%fname
raise
for k,conf in enumerate(confs):
if len(confs) > 1:
outfile = args.outfile+'_%d' % k
else:
outfile = args.outfile
write_configuration(outfile, conf)
|
Generating XML code for the <structures> block¶
The prepare_structure_xml_file.py script that can be found in the
utility_scripts directory allows one to generate XML code suitable
for insertion into the <structures>
block of an atomicrex
input file. The script reads a series of atomic simulation environment
(ASE) compatible input files
containing one or more configurations of positions and forces.
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 | #!/usr/bin/env python
# PE, 2015/06/04
description_string =
"""The script reads an ASE compatible input files containing one or
more configurations of positions and forces. It then prints XML code
to standard output that can be inserted into an atomicrex input file.
"""
import xml.etree.cElementTree as ET
import os
#------------------------------------------------
# Handle the command line
import argparse
parser = argparse.ArgumentParser(description=description_string)
parser.add_argument('files', nargs='+', action='append',
help='input files in modified POSCAR format for force matching.')
args = parser.parse_args()
root = ET.Element('group')
root.attrib['exclude-fit'] = 'false'
root.attrib['exclude-output'] = 'false'
for fname in args.files[0]:
structure = ET.SubElement(root, 'user-structure')
structure.attrib['id'] = os.path.basename(fname)
conffile = ET.SubElement(structure, 'poscar-file').text = fname
properties = ET.SubElement(structure, 'properties')
with open(fname, 'r') as f:
target_energy = float(f.readline().split()[0])
energy = ET.SubElement(properties, 'atomic-energy')
energy.attrib['relax'] = 'false'
energy.attrib['fit'] = 'true'
energy.attrib['target'] = '%.6f' % target_energy
forces = ET.SubElement(properties, 'atomic-forces')
forces.attrib['fit'] = 'true'
forces.attrib['output-all'] = 'true'
print ET.tostring(root)
|