Skip to content

Commit

Permalink
Merge pull request i-pi#323 from janberges/elphmod
Browse files Browse the repository at this point in the history
Add elphmod example
  • Loading branch information
mahrossi authored Apr 17, 2024
2 parents b59b48b + fe564c2 commit 75cdc7b
Show file tree
Hide file tree
Showing 10 changed files with 206 additions and 0 deletions.
32 changes: 32 additions & 0 deletions drivers/py/pes/elphmod.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""Interface with [elphmod](https://github.com/janberges/elphmod) MD driver."""

import sys
from .dummy import Dummy_driver

__DRIVER_NAME__ = "elphmod"
__DRIVER_CLASS__ = "ModelIIIDriver"

ERROR_MSG = """
A pickled driver instance is required (see elphmod.md.Driver.save).
Example: python3 driver.py -u -m elphmod -o driver.pickle
"""


class ModelIIIDriver(Dummy_driver):
"""Wrapper around elphmod MD driver."""

def check_arguments(self):
"""Check arguments and load driver instance."""

import elphmod

if len(self.args) != 1:
sys.exit(ERROR_MSG)

self.driver = elphmod.md.Driver.load(self.args[0])

def __call__(self, cell, pos):
"""Calculate energy and forces for given structure."""

return self.driver(cell, pos)
10 changes: 10 additions & 0 deletions examples/clients/elphmod/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
*.Wmat
*.epmatwp
*.ifc
*.pdf
*.pickle
*.wigner
*.xyz
*_hr.dat
RESTART
!driver.xyz
38 changes: 38 additions & 0 deletions examples/clients/elphmod/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Makefile for the elphmod example
#
# This file is part of i-PI.
# i-PI Copyright (C) 2014-2024 i-PI developers
# See the "licenses" directory for full license information.

.PHONY: all model driver run run2 plot clean
all: plot

IPI = i-pi
MODEL = model_hr.dat model.ifc model.epmatwp model.wigner
DRIVER = driver.pickle driver.xyz
RUN = run.out run.pos_0.xyz run.for_0.xyz
PLOT = plot.pdf

model $(MODEL): model.py
python3 $<

driver $(DRIVER): driver.py $(MODEL)
python3 $<

run $(RUN): input.xml $(DRIVER)
$(IPI) $< &
sleep 5
i-pi-driver-py -u -m elphmod -o $(word 2,$^)
wait

run2: input.xml run.py $(DRIVER)
$(IPI) $< &
sleep 5
python3 $(word 2,$^)
wait

plot $(PLOT): plot.py $(RUN)
python3 $<

clean:
rm -rf $(MODEL) $(DRIVER) $(RUN) $(PLOT) RESTART EXIT '#'*
51 changes: 51 additions & 0 deletions examples/clients/elphmod/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
elphmod - i-PI example
======================

This example connects i-PI with [elphmod](https://github.com/janberges/elphmod),
which provides energy surfaces for distorted systems based on *ab initio* data
for the symmetric one, using the approximation of a linearized electron-lattice
coupling. This realizes *model III* by Schobert *et al.*, [SciPost Phys. **16**,
046 (2024)](https://doi.org/10.21468/SciPostPhys.16.2.046).

The Python packages `elphmod` and `matplotlib` (for plotting only) are required.
Both can be installed with `pip` or from `conda-forge`.

This example performs the structural optimization of a charge-density wave in
monolayer tantalum disulfide. Running `make` performs the following steps:

1. Usually, the calculation is based on a Wannier Hamiltonian from Wannier90
(`model_hr.dat`), force constants from the PHonon code of Quantum ESPRESSO
(`model.ifc`), and the corresponding representation of the coupling from a
[patched version](https://github.com/janberges/elphmod/tree/master/patches)
of the EPW code (`model.epmatwp`, `model.wigner`). To avoid the *ab initio*
step, here we use a nearest-neighbor model instead, which can be created with
`make model` or `python3 model.py`.

2. Based on these data, we can build a supercell model and set up the driver
with `make driver` or `python3 driver.py`. This will create files with the
driver object (`driver.pickle`) and initial ionic positions (`driver.xyz`).
Note that the dummy `driver.xyz` required for testing will be overwritten.
Git will show the file as modified (or deleted after running `make clean`).

3. Now we are ready to run i-PI and the driver, which will communicate via a
Unix domain socket, and perform the optimization with `make run`. This will
start i-PI in the background, wait until it is ready, and start the driver
with `i-pi-driver-py -u -m elphmod -o driver.pickle`. i-PI will output the
potential energies (`run.out`), positions (`run.pos_0.xyz`), and forces
(`run.for_0.xyz`) for all steps.

4. Finally, we can view the trajectory with `make plot` or `python3 plot.py`.
This should open an interactive figure and finally create `plot.pdf`, where
arrows indicate atomic displacements. Since we have used a simplistic model,
the periodic lattice distortion differs from the expected 3-by-3 pattern.

Note that saving the driver to an intermediate file `driver.pickle` has two
advantages: First, when running it through `i-pi-driver-py`, only a single
parameter (the filename) has to be specified on the command line, rather than
all details of the flexible setup in `driver.py`. Second, setting up the driver
can be quite time consuming, so it is more efficient to do this only once when
launching it multiple times later.

It is alternatively possible to run the driver through the module `ipi._driver`,
which is however only available if i-PI has been installed using `setuptools`,
e.g., through `pip`. This can be tested with `make run2` or `python3 run.py`.
26 changes: 26 additions & 0 deletions examples/clients/elphmod/driver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env python3

"""See [documentation](https://janberges.github.io/elphmod/modules/md.html)."""

import elphmod

el = elphmod.el.Model("model", rydberg=True)
ph = elphmod.ph.Model("model.ifc", divide_mass=False)
elph = elphmod.elph.Model("model.epmatwp", "model.wigner", el, ph, divide_mass=False)

driver = elphmod.md.Driver(
elph,
nk=(12, 12),
nq=(2, 2),
supercell=(9, 9),
kT=0.02,
f=elphmod.occupations.marzari_vanderbilt,
n=1.0,
)

driver.kT = 0.005
driver.f = elphmod.occupations.fermi_dirac
driver.random_displacements()

driver.save("driver.pickle")
driver.to_xyz("driver.xyz")
5 changes: 5 additions & 0 deletions examples/clients/elphmod/driver.xyz
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
3
# CELL{H}: 6.3116853 -3.15584265 0 0 5.466079812 0 0 0 28.34589207
Ta 0.000000000 3.644053207 0.000000000
S 3.155842650 1.822026604 2.834589207
S 3.155842650 1.822026604 -2.834589207
22 changes: 22 additions & 0 deletions examples/clients/elphmod/input.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<simulation>
<output prefix='run'>
<properties stride='1' filename='out'>[step, potential]</properties>
<trajectory stride='1' filename='pos'>positions</trajectory>
<trajectory stride='1' filename='for'>forces</trajectory>
</output>
<ffsocket name='elphmod' mode='unix' pbc='false'>
<address>localhost</address>
</ffsocket>
<system>
<initialize nbeads='1'>
<file mode='xyz'>driver.xyz</file>
</initialize>
<forces>
<force forcefield='elphmod'></force>
</forces>
<motion mode='minimize'>
<optimizer mode='bfgs'></optimizer>
<fixcom>True</fixcom>
</motion>
</system>
</simulation>
5 changes: 5 additions & 0 deletions examples/clients/elphmod/model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env python3

import elphmod.models.tas2 as model

model.create("model")
9 changes: 9 additions & 0 deletions examples/clients/elphmod/plot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env python3

import elphmod

driver = elphmod.md.Driver.load("driver.pickle")

driver.plot(interactive=True, scale=10, pause=0.1)
driver.from_xyz("run.pos_0.xyz")
driver.plot(filename="plot.pdf")
8 changes: 8 additions & 0 deletions examples/clients/elphmod/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env python3

import elphmod
import ipi._driver.driver

driver = elphmod.md.Driver.load("driver.pickle")

ipi._driver.driver.run_driver(unix=True, address="localhost", driver=driver)

0 comments on commit 75cdc7b

Please sign in to comment.