Skip to content

Commit

Permalink
Bugfixes
Browse files Browse the repository at this point in the history
Fixes #7, #11, #12, #14

Updated documentation, added tests.
  • Loading branch information
EmielSlootman authored Apr 21, 2022
1 parent c54afd3 commit 55b171b
Show file tree
Hide file tree
Showing 21 changed files with 281 additions and 63 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/self-hosted-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ jobs:
runs-on: [self-hosted]
strategy:
matrix:
python-version: ["3.9"]
python-version: ["3.7", "3.8", "3.9"]
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: |
pip install pylint pytest coverage coveralls
pip install -r requirements.txt
pip${{ matrix.python-version }} install pylint pytest coverage coveralls
pip${{ matrix.python-version }} install -r requirements.txt
- name: Linting with pylint
run: |
pylint $(git ls-files 'qmcblip/*.py')
python${{ matrix.python-version }} -m pylint $(git ls-files 'qmcblip/*.py')
- name: Test with pytest
run: |
coverage run -m --source=qmcblip pytest tests
coverage report
python${{ matrix.python-version }} -m coverage run -m --source=qmcblip pytest tests
python${{ matrix.python-version }} -m coverage report
- name: Coveralls
run: coveralls --service=github
run: python${{ matrix.python-version }} -m coveralls --service=github
env:
GITHUB_TOKEN: ${{ secrets.github_token }}
COVERALLS_FLAG_NAME: python-${{ matrix.python-version }}
Expand Down
4 changes: 4 additions & 0 deletions docs/examples/C2-gamess.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
C2 with GAMESS
--------------

.. literalinclude:: ../../examples/C2-gamess/run.py
2 changes: 1 addition & 1 deletion docs/examples/C2-quicksim.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
C2 Quick Simulation
===================
-------------------

.. literalinclude:: ../../examples/C2-quicksim/run.py
25 changes: 25 additions & 0 deletions docs/examples/examples.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Quicksim
========
.. toctree::
:maxdepth: 1
:caption: Quicksim

C2-quicksim
thio-quicksim

FLARE++
=======
.. toctree::
:maxdepth: 1
:caption: FLARE++

thio-300K
thio-300K-ex

GAMESS
========
.. toctree::
:maxdepth: 1
:caption: GAMESS

C2-gamess
6 changes: 3 additions & 3 deletions docs/examples/thio-300K-ex.rst
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
Thiophene 300K Excited State Geometry
=====================================
-------------------------------------

Running the simulation
----------------------
^^^^^^^^^^^^^^^^^^^^^^

.. literalinclude:: ../../examples/thio-300K-ex/run.py

Analyzing the simulation
------------------------
^^^^^^^^^^^^^^^^^^^^^^^^

.. literalinclude:: ../../examples/thio-300K-ex/plot.py

Expand Down
6 changes: 3 additions & 3 deletions docs/examples/thio-300K.rst
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
Thiophene 300K
==============
--------------

Running the simulation
----------------------
^^^^^^^^^^^^^^^^^^^^^^

.. literalinclude:: ../../examples/thio-300K/run.py

Analyzing the simulation
------------------------
^^^^^^^^^^^^^^^^^^^^^^^^

.. literalinclude:: ../../examples/thio-300K/plot.py

Expand Down
2 changes: 1 addition & 1 deletion docs/examples/thio-quicksim.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Thiophene Quick Simulation
==========================
--------------------------

.. literalinclude:: ../../examples/thio-quicksim/run.py
8 changes: 3 additions & 5 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@ Quantum Monte Carlo Based Learning of Interatomic Potentials
installation
qmcblip/champ
qmcblip/flare
qmcblip/analyze
qmcblip/quicksim
qmcblip/gamess

.. toctree::
:maxdepth: 1
:caption: Examples

examples/C2-quicksim
examples/thio-quicksim
examples/thio-300K
examples/thio-300K-ex
examples/examples

.. toctree::
:maxdepth: 1
Expand Down
15 changes: 14 additions & 1 deletion docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,24 @@ To install the code
* install the module ``pip install -e ./``


Installing Dependencies
=======================

Installing CHAMP
=================
----------------

To use this software, you need a special version of CHAMP which can export the forces and energy to a file.
For this you need to ase-coupling_ branch.
Simply clone this and build in the usual way, as specified by their documentation.

.. _ase-coupling: https://github.com/filippi-claudia/champ/tree/ase-coupling

Installing GAMESS
-----------------

GAMESS can be found at gamess_. To make CHAMP and GAMESS work together, we need to change some settings.
First, make sure that GAMESS is on your path, specifically the rungms file.
Secondly, in the ``gms-files.csh`` file change the ``setenv EXTBAS /dev/null`` to ``setenv EXTBAS /your/champ/location/pool/BFD/BASIS_gamess/BFD_Basis.EXTBAS``. Now GAMESS can use the BFD basis.

.. _gamess: https://www.msg.chem.iastate.edu/gamess/

23 changes: 0 additions & 23 deletions docs/qmcblip/analyze.rst

This file was deleted.

26 changes: 25 additions & 1 deletion docs/qmcblip/flare.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,28 @@ This array can be empty.
>>> calculator=flare_calculator,
>>> **otf_params)

See the `FLARE documentation`_ for more information about the other parts in the code on this page.
See the `FLARE documentation`_ for more information about the other parts in the code on this page.

Analyzing results
^^^^^^^^^^^^^^^^^

Due to the custom Velocity Verlet scheme we use with FLARE, the kinetic energy is one step out of phase with the potential energy.
To make it easier to analyze the data, we included a few tools to do so (see :class:`Analyze <qmcblip.tools.Analyze>`).
These tools also align the potential and kinetic energy:

>>> from caf.tools import Analyze
>>>
>>> # Import the thio.out file
>>> data = Analyze('H2.out')
>>>
>>> # Create the traj.xyz file
>>> data.to_xyz()
>>>
>>> # Returns a dictionary containing the keys 'times', 'potential energy', 'kinetic energy',
>>> # 'total energy' and 'temperature'
>>> results = data.get_data()
>>>
>>> # Plot the energy and save it to energy.png
>>> data.plot_energy(filename="energy.png")

This analyzing tool is only suitable for simulations that were performed with FLARE, and not pure QMC simulations.
40 changes: 40 additions & 0 deletions docs/qmcblip/gamess.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Creating Wavefunction
---------------------

Important warning: this part is currently still experimental and only confirmed to work for C2.

QMCblip also includes some tools to make the wavefunction for CHAMP using GAMESS. To use it, first import:

>>> from qmcblip.gamess.utils import WavefunctionCreator

Also create your molecular system:

>>> from ase import Atoms
>>> atoms = Atoms('C2', [(0,0,-0.7), (0,0, 0.7)])

We can now initialize our :obj:`WavefunctionCreator <qmcblip.gamess.utils.WavefunctionCreator>` object. The first argument are our atoms and the second argument is the location of the CHAMP base directory. This is not the directory containing ``vmc.mov1``, but the directory one level up.

>>> wf = WavefunctionCreator(atoms, '../../champ')

We can now run the GAMESS simulations. See the `GAMESS documentation`_ for more information. Using keywords and dictionaries you can supply additional GAMESS settings or change the defaults. Using the userscr keyword you can supply the location of the USERSCR directory. Usually the ASE GAMESS calculator can find it on its own, but if not you need to supply it.

>>> wf.setup_rhf()
>>> wf.setup_cas(system=dict(mwords=500), drt=dict(nmcc=2, ndoc=2, nval=2))
>>> wf.setup_ci(system=dict(mwords=500), cidrt=dict(nfzc=2, ndoc=2, nval=2))

After GAMESS is done we can convert the GAMESS output to CHAMP wavefunction.

>>> wf.convert_to_champ()

And we can also quickly make a CHAMP input file (``vmc.inp``).

>>> input = wf.create_champ_input()

Here ``input`` is of the :obj:`Settings <qmcblip.champio.Settings>` type. With that we can easily run a CHAMP simulation:

>>> from qmcblip.champ import CHAMP
>>> atoms.calc = CHAMP(champ_loc='../../champ/bin/vmc.mov1', settings = input)

For more examples, see :doc:`../examples/examples`.

.. _`GAMESS documentation`: https://www.msg.chem.iastate.edu/gamess/GAMESS_Manual/docs-input.txt
41 changes: 41 additions & 0 deletions docs/qmcblip/quicksim.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Quickly setup
-------------

QMCblip comes with a quicksim function to quickly perform QMC ML FF simulations. To do a quick FLARE simulation, import:

>>> from qmcblip.flare.quicksim import quicksim, OTFSettings

Depending on your system, you might want to use FLARE or FLARE++. To switch between the two, make an :obj:`OTFSettings<qmcblip.flare.quicksim.OTFSettings>` object:

>>> settings = OTFSettings(theory=OTFSettings.FLARE())

In the case you want to do a FLARE++ simulation, do:

>>> settings = OTFSettings(theory=OTFSettings.FLAREPP())

You also need to provide the CHAMP calculator

>>> from qmcblip.champ import CHAMP
>>> calc = CHAMP(champ_loc="/home/user/bin/vmc.mov1", ncore=4)

Finally, you also need to setup the molecular system (remember to put a box around it for FLARE):

>>> from ase import Atoms, units
>>> from ase.atoms import Cell
>>>
>>> atoms = Atoms('C2', [(0,0,-0.61385), (0,0,0.61385)])
>>> atoms.cell = Cell.fromcellpar([50, 50, 50, 90, 90, 90])
>>> atoms.pbc=[True, True, True]

Finally you are ready to perform the simulation. In this case we are performing a simulation of 100 steps with 0.5fs timestep.

>>> quicksim(atoms, 0.5, 100, calc, settings)

You can also supply an extra argument to change the CHAMP settings during the simulation. To change the amount of optimization steps at the 10th MD timestep:

>>> changes = [(10, {'optwf': {'nopt_iter': 10}})]
>>> quicksim(atoms, 0.5, 100, calc, settings, changes=changes)

For more examples, see :doc:`../examples/examples`.


19 changes: 19 additions & 0 deletions examples/C2-gamess/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from ase import Atoms
from qmcblip.gamess.utils import WavefunctionCreator
from qmcblip.champ import CHAMP
from qmcblip.champio import Settings

atoms = Atoms('C2', [(0,0,-0.7), (0,0, 0.7)])
wf = WavefunctionCreator(atoms, '../../champ')

wf.setup_rhf()
wf.setup_cas(system=dict(mwords=500), drt=dict(nmcc=2, ndoc=2, nval=2))
wf.setup_ci(system=dict(mwords=500), cidrt=dict(nfzc=2, ndoc=2, nval=2))
wf.convert_to_champ()
input = wf.create_champ_input()

input.optwf.nopt_iter = 100

atoms.calc = CHAMP(champ_loc='../../champ/bin/vmc.mov1', settings = input)

print(atoms.get_total_energy())
13 changes: 8 additions & 5 deletions qmcblip/champio.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,13 @@ def write(self, filename='vmc.inp'):
schema = self.schema()['properties']
for _, item in enumerate(self):
if isinstance(item[1], BaseModel):
schema2 = item[1].schema()['properties']
if callable(getattr(item[1], 'schema')):
schema2 = item[1].schema()['properties']
else:
schema2 = []
input_file.write("\n%module " + item[0] + "\n")
for _, item2 in enumerate(item[1]):
if 'postfix' in schema2[item2[0]]:
if item2[0] in schema2 and 'postfix' in schema2[item2[0]]:
if item2[1] is not None:
input_file.write("\t" + item2[0] + " " + str(item2[1]) +\
schema2[item2[0]]['postfix'] + "\n")
Expand All @@ -139,7 +142,7 @@ def write(self, filename='vmc.inp'):
input_file.write("\t" + item2[0] + " " + str(item2[1]) + "\n")
input_file.write("%endmodule\n\n")
else:
if 'prefix' in schema[item[0]]:
if item[0] in schema and 'prefix' in schema[item[0]]:
if item[1] is not None:
input_file.write(schema[item[0]]['prefix'] + item[0] + " " +\
str(item[1]) + '\n')
Expand All @@ -165,9 +168,9 @@ def read(cls: Type['BaseModel'], filename: Union[str, Path]) -> 'BaseModel':

path = PosixPath(filename).resolve().parent

if path.is_relative_to(Path.cwd()):
try:
path = path.relative_to(Path.cwd()).as_posix() + "/"
else:
except:
path = path.as_posix() + "/"

output = {}
Expand Down
24 changes: 18 additions & 6 deletions qmcblip/gamess/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,12 @@ def setup_rhf(self, **kwargs):

calc.calculate(self.atoms)

if calc.userscr is not None:
copyfile(Path(calc.userscr).joinpath(name + '.dat'), name + '.dat')
if calc.userscr is None:
raise RuntimeError("USERSCR is not defined")
if not Path(calc.userscr).is_dir():
raise RuntimeError("USERSCR is not found at: " + calc.userscr)

copyfile(Path(calc.userscr).joinpath(name + '.dat'), name + '.dat')

self.vec = '\n'.join(str(subprocess.check_output(
str(self.champ_path.joinpath('tools/interface/getvec.pl')) +\
Expand Down Expand Up @@ -164,8 +168,12 @@ def setup_cas(self, **kwargs):

calc.calculate(self.atoms)

if calc.userscr is not None:
copyfile(Path(calc.userscr).joinpath(name + '.dat'), name + '.dat')
if calc.userscr is None:
raise RuntimeError("USERSCR is not defined")
if not Path(calc.userscr).is_dir():
raise RuntimeError("USERSCR is not found at: " + calc.userscr)

copyfile(Path(calc.userscr).joinpath(name + '.dat'), name + '.dat')

self.vec = '\n'.join(str(subprocess.check_output(
str(self.champ_path.joinpath('tools/interface/getvec.pl')) +\
Expand Down Expand Up @@ -210,8 +218,12 @@ def setup_ci(self, **kwargs):

calc.calculate(self.atoms)

if calc.userscr is not None:
copyfile(Path(calc.userscr).joinpath(name + '.dat'), name + '.dat')
if calc.userscr is None:
raise RuntimeError("USERSCR is not defined")
if not Path(calc.userscr).is_dir():
raise RuntimeError("USERSCR is not found at: " + calc.userscr)

copyfile(Path(calc.userscr).joinpath(name + '.dat'), name + '.dat')

os.chdir('..')

Expand Down
Loading

0 comments on commit 55b171b

Please sign in to comment.