Skip to content

Commit

Permalink
Merge branch 'public' of https://github.com/libAtoms/QUIP into public
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinSchlegel committed May 21, 2018
2 parents 28f0da4 + a46cd04 commit 874ee9d
Show file tree
Hide file tree
Showing 36 changed files with 1,882 additions and 326 deletions.
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -27,7 +27,7 @@ Alan Nichol, David Packwood, Lars Pastewka, Giovanni Peralta, Ivan
Solt, Oliver Strickson, Wojciech Szlachta, Csilla Varnai, Steven
Winfield.

Copyright 2006-2016.
Copyright 2006-2018.

Most of the publicly available version is released under the GNU
General Public license, version 2, with some portions in the public
Expand Down Expand Up @@ -260,5 +260,5 @@ to get up and running quickly.

14. In order to run QUIP potentials via LAMMPS, ``make libquip`` to get QUIP
into library form, and then follow the instructions in the
[LAMMPS documentation](http://lammps.sandia.gov/doc/pair_quip.html).
[LAMMPS documentation](http://lammps.sandia.gov/doc/pair_quip.html). You need at least 11 Aug 2017 version or later.

35 changes: 35 additions & 0 deletions arch/Makefile.linux_x86_64_gfortran_CrayXE6_mpi
@@ -0,0 +1,35 @@
# H0 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# H0 X
# H0 X libAtoms+QUIP: atomistic simulation library
# H0 X
# H0 X Portions of this code were written by
# H0 X Albert Bartok-Partay, Silvia Cereda, Gabor Csanyi, James Kermode,
# H0 X Ivan Solt, Wojciech Szlachta, Csilla Varnai, Steven Winfield.
# H0 X
# H0 X Copyright 2006-2010.
# H0 X
# H0 X These portions of the source code are released under the GNU General
# H0 X Public License, version 2, http://www.gnu.org/copyleft/gpl.html
# H0 X
# H0 X If you would like to license the source code under different terms,
# H0 X please contact Gabor Csanyi, gabor@csanyi.net
# H0 X
# H0 X Portions of this code were written by Noam Bernstein as part of
# H0 X his employment for the U.S. Government, and are not subject
# H0 X to copyright in the USA.
# H0 X
# H0 X
# H0 X When using this software, please cite the following reference:
# H0 X
# H0 X http://www.libatoms.org
# H0 X
# H0 X Additional contributions by
# H0 X Alessio Comisso, Chiara Gattinoni, and Gianpietro Moras
# H0 X
# H0 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

# declarations

include arch/Makefile.linux_x86_64_gfortran_CrayXE6

DEFINES += -D_MPI -DMPI_1
45 changes: 45 additions & 0 deletions doc/io.rst
Expand Up @@ -102,6 +102,8 @@ reading from or writing to XYZ or NetCDF files.
+----------------+----------------------------+
| ``nc`` | :ref:`netcdf` |
+----------------+----------------------------+
| ``nmd`` | :ref:`nmwiz` |
+----------------+----------------------------+
| ``pos`` | :ref:`asap` |
+----------------+----------------------------+
| ``pov`` | :ref:`povray` |
Expand Down Expand Up @@ -369,6 +371,49 @@ IMD checkpoint
:synopsis: IMD checkpoint reader
:members:

.. _nmwiz:

NMWiz plugin for VMD
------------------------------------

Supports the ``.nmd`` format used by ProDy_ and the NMWiz_ plugin for
VMD_. The files can be read directly into VMD to visualise a molecule's
normal modes.

.. _ProDy: http://prody.csb.pitt.edu/
.. _NMWiz: http://www.ks.uiuc.edu/Research/vmd/plugins/nmwiz/
.. _VMD: http://www.ks.uiuc.edu/Research/vmd/

.. py:module:: quippy.nmwiz
.. I have to copy the docstring explicitly so it doesn't get
the ugly and unnecessary numpydoc autosummary
.. py:class:: NMDWriter
Writer for the ``.nmd`` format

The Atoms object must have normal modes -- both eigenvectors and
eigenvalues (force constants in the normal-mode basis) of the
Hessian matrix -- stored in ``atoms.info['hessian_eigenvalue_X']``
and ``atoms.arrays['hessian_eigenvector_X']``, where ``X`` ranges
from 1 to the number of stored normal modes.

This writer implements the context manager protocol, so you can
use it like so::

with NMDWriter(filename) as writer:
writer.write(atoms)

and the associated file will be closed automatically when done.

The ``.nmd`` file format only supports single configurations, so
this writer doesn't accept trajectories.

.. automethod:: __init__
.. automethod:: write
.. automethod:: close

.. _povray:

POV-ray
Expand Down
5 changes: 3 additions & 2 deletions docker/Dockerfile
@@ -1,4 +1,4 @@
# Base Python image has most up to date Python parts
# Base Python image has most up to date Python parts
FROM libatomsquip/quip-base-software

MAINTAINER Tom Daff "tdd20@cam.ac.uk"
Expand Down Expand Up @@ -92,6 +92,7 @@ ENV PATH ${QUIP_ROOT}/bin:${QUIP_ROOT}/src/AtomEye/bin:${PATH}
WORKDIR /root/
ADD files/demo.ipynb /root/

CMD jupyter notebook --port=8899 --ip='*' --allow-root --NotebookApp.token='' --NotebookApp.password=''
CMD jupyter notebook --port=8899 --ip='*' --allow-root

EXPOSE 8899

4 changes: 2 additions & 2 deletions docker/Dockerfile.gap
Expand Up @@ -88,7 +88,7 @@ ENV PATH ${QUIP_ROOT}/bin:${QUIP_ROOT}/src/AtomEye/bin:${PATH}

# GloSim also uses quippy and GAP (SOAP)

RUN git clone --depth 1 https://github.com/cosmo-epfl/glosim /usr/local/src/glosim
RUN git clone --depth 1 https://github.com/cosmo-epfl/glosim /opt/glosim

# ENTRYPOINT ["/bin/bash", "-c"]

Expand All @@ -103,6 +103,6 @@ RUN mkdir -p /bin/real/ \

ADD docker/files/fakebash /bin/bash

CMD bash -c exit && jupyter notebook --port=8899 --ip='*' --allow-root --NotebookApp.token='' --NotebookApp.password=''
CMD bash -c exit && jupyter notebook --port=8899 --ip='*' --allow-root

EXPOSE 8899
2 changes: 1 addition & 1 deletion docker/Dockerfile.private
Expand Up @@ -92,6 +92,6 @@ ENV PATH ${QUIP_ROOT}/bin:${QUIP_ROOT}/src/AtomEye/bin:${PATH}
WORKDIR /root/
ADD docker/files/demo.ipynb /root/

CMD jupyter notebook --port=8899 --ip='*' --allow-root --NotebookApp.token='' --NotebookApp.password=''
CMD jupyter notebook --port=8899 --ip='*' --allow-root

EXPOSE 8899
19 changes: 15 additions & 4 deletions docker/README.md
Expand Up @@ -53,16 +53,27 @@ docker run -it -p 8899:8899 -v ~/Work/DockerHome:/root/ libatomsquip/quip
and can interact with it.
- ``-p 8899:8899`` the Jupyter notebook is set to run on port 8899, this
allows access to that port from outside the container. Access the notebook
at http://localhost:8899/ in your browser.
at http://localhost:8899/ in your browser. **Note:** by default this
port will be exposed to all hosts, so if your machine in on a public IP
address take care; you may wish to use e.g. ``-p 127.0.0.1:8899:8899``
to restrict to local connections.
- ``-v ~/Work/DockerHome:/root/`` makes the ``Work/DockerHome`` folder in
your home directory become the ``$HOME`` directory of the docker user
(root). This is the best way to make data available inside the container,
and **any changes that you want to keep after the container stops must be
made in a mounted volume!**

If you'd prefer to use a shell in the image just add ``bash`` to the very end
of the command. Alternatively, the Jupyter notebook allows you to have fully
functional terminal sessions in your web browser.
This command will start the jupyter notebook server. One useful workflow is to
stop this first container, and then restart it with ``docker container start <label>``,
after which shells can be opened into it with ``docker exec -it <label> bash``.

You can get a list of available containers and their labels (even stopped ones) by typing ``docker container ls -a``. The hexademical labels can be replaced with the friendly names provided by docker, or even renamed to your own, e.g. ``docker container rename <label> quip`` after which you can refer to the container by use the ``quip`` label.

If you'd prefer to use a shell in the image right away, just add ``bash`` to the very end
of the first run command.

Any any case, the first time you run a shell, you will be asked to agree to a license agreement
(basically non-commercial use), by typing your email.

Tips
----
Expand Down
1 change: 1 addition & 0 deletions quippy/quippy/__init__.py
Expand Up @@ -285,6 +285,7 @@ def quippy_cleanup():
import quippy.povray
import quippy.cube
import quippy.netcdf
import quippy.nmwiz
import quippy.imd
import quippy.vasp
import quippy.dan
Expand Down
8 changes: 0 additions & 8 deletions quippy/quippy/atoms.py
Expand Up @@ -538,14 +538,6 @@ def iteratoms(self):
for i in self.indices:
yield self.get_atom(i)

def __eq__(self, other):
"""Test for equality (==) of two Atoms objects. Use equivalent() for
better compatibility with ase.atoms.Atoms.__eq__() semantics, so things like
calculators that use == to check for recalculation behave
as expected"""

return self.equivalent(other)

def equivalent(self, other):
"""Test for equivalence of two Atoms objects.
Expand Down
28 changes: 17 additions & 11 deletions quippy/quippy/descriptors.py
Expand Up @@ -109,39 +109,45 @@ def calc(self, at, grad=False, args_str=None, **calc_args):
"""
Calculates all descriptors of this type in the Atoms object, and
gradients if grad=True. Results can be accessed dictionary- or
attribute-style; 'descriptor' contains descriptor values, 'grad'
contains gradients, 'index' contains indices to gradients
(descriptor, atom, coordinate). Cutoffs and gradients of cutoffs
are also returned.
attribute-style; 'descriptor' contains descriptor values,
'descriptor_index_0based' contains the 0-based indices of the central
atom(s) in each descriptor, 'grad' contains gradients,
'grad_index_0based' contains indices to gradients (descriptor, atom).
Cutoffs and gradients of cutoffs are also returned.
"""
if args_str is None:
args_str = dict_to_args_str(calc_args)

n_desc, n_cross = self.descriptor_sizes(at)
n_index = fzeros(1,'i')
n_desc, n_cross = self.descriptor_sizes(at,n_index=n_index)
n_index = n_index[1]
data = fzeros((self.n_dim, n_desc))
cutoff = fzeros(n_desc)
data_index = fzeros((n_index,n_desc),'i')

if grad:
# n_cross is number of cross-terms, proportional to n_desc
data_grad = fzeros((self.n_dim, 3 ,n_cross))
data_index = fzeros((2, n_cross), 'i')
data_grad_index = fzeros((2, n_cross), 'i')
cutoff_grad = fzeros((3 ,n_cross))

if not grad:
RawDescriptor.calc(self, at, descriptor_out=data, covariance_cutoff=cutoff,
args_str=args_str)
RawDescriptor.calc(self, at, descriptor_out=data, covariance_cutoff=cutoff,
descriptor_index=data_index, args_str=args_str)
else:
RawDescriptor.calc(self, at, descriptor_out=data, covariance_cutoff=cutoff,
grad_descriptor_out=data_grad, grad_descriptor_index=data_index,
grad_covariance_cutoff=cutoff_grad,args_str=args_str)
descriptor_index=data_index, grad_descriptor_out=data_grad,
grad_descriptor_index=data_grad_index, grad_covariance_cutoff=cutoff_grad,
args_str=args_str)

results = DescriptorCalcResult()
convert = lambda data: np.array(data).T
results.descriptor = convert(data)
results.cutoff = convert(cutoff)
results.descriptor_index_0based = convert(data_index-1)
if grad:
results.grad = convert(data_grad)
results.index = convert(data_index)
results.grad_index_0based = convert(data_grad_index-1)
results.cutoff_grad = convert(cutoff_grad)

return results
Expand Down
132 changes: 132 additions & 0 deletions quippy/quippy/nmwiz.py
@@ -0,0 +1,132 @@
# HQ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# HQ X
# HQ X quippy writer for normal mode (`.nmd`) files
# HQ X Copyright Max Veit 2018
# HQ X File format used by ProDy (http://prody.csb.pitt.edu/)
# HQ X and VMD's NMWiz plugin
# HQ X (http://www.ks.uiuc.edu/Research/vmd/plugins/nmwiz/)
# HQ X
# HQ X Part of:
# HQ X quippy: Python interface to QUIP atomistic simulation library
# HQ X Copyright James Kermode 2010
# HQ X
# HQ X These portions of the source code are released under the GNU General
# HQ X Public License, version 2, http://www.gnu.org/copyleft/gpl.html
# HQ X
# HQ X If you would like to license the source code under different terms,
# HQ X please contact James Kermode, james.kermode@gmail.com
# HQ X
# HQ X When using this software, please cite the following reference:
# HQ X
# HQ X http://www.jrkermode.co.uk/quippy
# HQ X
# HQ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
"""nmwiz: Write atoms and normal modes to '.nmd' format.
Contents:
NMDWriter Writer for the .nmd format
"""


from __future__ import division, print_function, unicode_literals
from itertools import izip
import sys

from numpy import abs, sqrt
import quippy
from quippy.io import AtomsWriters


class NMDWriter(object):

"""Writer for the '.nmd' format
The Atoms object must have normal modes -- both eigenvectors and
eigenvalues (force constants in the normal-mode basis) of the
Hessian matrix -- stored in 'atoms.info["hessian_eigenvalue_X"]'
and 'atoms.arrays["hessian_eigenvector_X"]', where 'X' ranges
from 1 to the number of stored normal modes.
This writer implements the context manager protocol, so you can
use it like so:
with NMDWriter(filename) as writer:
writer.write(atoms)
and the associated file will be closed automatically when done.
The '.nmd' file format only supports single configurations, so
this writer doesn't accept trajectories.
"""

def __init__(self, filename):
"""Open ``filename`` for writing (use ``-`` for stdout)"""
if filename == '-':
self._file = sys.stdout
else:
self._file = open(filename, 'w')

def __enter__(self):
# The writer interface requires we open the file in __init__(),
# so do nothing here.
# In particular, don't reopen the file if it's already been closed.
return self

def write(self, atoms, title='quippy atoms'):
"""Write out the atoms and modes with an optional title"""
# Get the modes from the Atoms object
try:
mode_idx = 1
eigvecs = []
mode_idces = []
while True:
mode_string = 'hessian_eigenvector_{:d}'.format(mode_idx)
eigvecs.append(atoms.get_array(mode_string))
mode_idces.append(mode_idx)
mode_idx += 1
except KeyError as kerr:
if not mode_idces:
# Oh great, Python 2 doesn't support exception chaining
#py2kfacepalm
#raise ValueError("Couldn't find any Hessian eigenvectors "
# "in Atoms object") from kerr
raise ValueError(
"Couldn't find any Hessian eigenvectors in Atoms object "
"(key '{:s}' missing)".format(mode_string))
try:
eigvals = []
for mode_idx in mode_idces:
mode_string = 'hessian_eigenvalue_{:d}'.format(mode_idx)
eigvals.append(atoms.info[mode_string])
except KeyError as kerr:
# This is how easy it would be in Python 3
#raise ValueError("Couldn't find Hessian eigenvalue number "
# "{:d}".format(mode_idx)) from kerr
raise ValueError("Couldn't find Hessian eigenvalue number "
"{:d} (key '{:s}')".format(mode_idx, mode_string))
# Write the actual file
self._file.write('title ' + title + '\n')
self._file.write('coordinates ')
atoms.get_positions().tofile(self._file, ' ', '%.6f')
self._file.write('\n')
self._file.write('names ')
self._file.write(' '.join(atoms.get_chemical_symbols()))
self._file.write('\n')
for idx, eigval, eigvec in izip(mode_idces, eigvals, eigvecs):
self._file.write('mode {:d} {:.6f} '.format(idx, eigval))
eigvec.tofile(self._file, ' ', '%.6f')
self._file.write('\n')

def __exit__(self, exc_type, exc_value, traceback):
if self._file is not sys.stdout:
self._file.close()
# Don't suppress any exceptions
return False

def close(self):
"""Close the file (unnecessary if using the ``with`` statment)"""
self.__exit__(None, None, None)


AtomsWriters['nmd'] = NMDWriter

0 comments on commit 874ee9d

Please sign in to comment.