Open In Colab

Equation of State

Set up environment (optional)

These steps are required to run this tutorial with Google Colab. To do so, uncomment and run the cell below.

This will replace pre-installed versions of numpy and torch in Colab with versions that are known to be compatible with janus-core.

It may be possible to skip the steps that uninstall and reinstall torch, which will save a considerable amount of time.

These instructions but may work for other systems too, but it is typically preferable to prepare a virtual environment separately before running this notebook if possible.

[1]:
# import locale
# locale.getpreferredencoding = lambda: "UTF-8"

# ! pip uninstall numpy -y # Uninstall pre-installed numpy

# ! pip uninstall torch torchaudio torchvision transformers -y # Uninstall pre-installed torch
# ! uv pip install torch==2.5.1 # Install pinned version of torch

# ! uv pip install janus-core[mace,visualise] data-tutorials --system # Install janus-core with MACE and WeasWidget, and data-tutorials

# get_ipython().kernel.do_shutdown(restart=True) # Restart kernel to update libraries. This may warn that your session has crashed.

To ensure you have the latest version of janus-core installed, compare the output of the following cell to the latest version available at https://pypi.org/project/janus-core/

[2]:
from janus_core import __version__

print(__version__)
0.9.3

Prepare data

Use data_tutorials to get the data required for this tutorial:

[3]:
from data_tutorials.data import get_data

get_data(
    url="https://raw.githubusercontent.com/stfc/janus-core/main/docs/source/tutorials/data/",
    filename=["beta_quartz.cif"],
    folder="data",
)
try to download beta_quartz.cif from https://raw.githubusercontent.com/stfc/janus-core/main/docs/source/tutorials/data/ and save it in data/beta_quartz.cif
saved in data/beta_quartz.cif
[4]:
from pathlib import Path

from ase import Atoms
from ase.io import write
from weas_widget import WeasWidget
Path("../data").mkdir(exist_ok=True)

α_quartz = Atoms(
    symbols=(*["Si"] * 3, *["O"] * 6),
    scaled_positions=[
        [0.469700, 0.000000, 0.000000],
        [0.000000, 0.469700, 0.666667],
        [0.530300, 0.530300, 0.333333],
        [0.413500, 0.266900, 0.119100],
        [0.266900, 0.413500, 0.547567],
        [0.733100, 0.146600, 0.785767],
        [0.586500, 0.853400, 0.214233],
        [0.853400, 0.586500, 0.452433],
        [0.146600, 0.733100, 0.880900],
    ],
    cell=[
        [4.916000, 0.000000, 0.000000],
        [-2.45800, 4.257381, 0.000000],
        [0.000000, 0.000000, 5.405400],
    ],
    pbc=True,
)

write("../data/α_quartz.xyz", α_quartz)

v=WeasWidget()
v.from_ase(α_quartz)
v.avr.model_style = 1
v.avr.show_hydrogen_bonds = True
v
[4]:

Command-line help and options

Once janus-core is installed, the janus CLI command should be available:

[5]:
! janus eos --help
                                                                                
 Usage: janus eos [OPTIONS]                                                     
                                                                                
 Calculate equation of state.

╭─ Options ────────────────────────────────────────────────────────────────────╮
│ --config        TEXT  Path to configuration file.                            │
│ --help                Show this message and exit.                            │
╰──────────────────────────────────────────────────────────────────────────────╯
╭─ MLIP calculator ────────────────────────────────────────────────────────────╮
│ *  --arch               [mace|mace_mp|mace_off|c  MLIP architecture to use   │
│                         hgnet|sevennet|nequip|dp  for calculations.          │
│                         a3|orb|mattersim|grace|u  [required]                 │
│                         pet|fairchem|mace_omol]                              │
│    --device             [cpu|cuda|mps|xpu]        Device to run calculations │
│                                                   on.                        │
│                                                   [default: cpu]             │
│    --model              TEXT                      MLIP model name, or path   │
│                                                   to model.                  │
│    --calc-kwargs        DICT                      Keyword arguments to pass  │
│                                                   to selected calculator.    │
│                                                   Must be passed as a        │
│                                                   dictionary wrapped in      │
│                                                   quotes, e.g. "{'key':      │
│                                                   value}".                   │
╰──────────────────────────────────────────────────────────────────────────────╯
╭─ Calculation ────────────────────────────────────────────────────────────────╮
│ *  --struct                               PATH              Path of          │
│                                                             structure to     │
│                                                             simulate.        │
│                                                             [required]       │
│    --min-volume                           FLOAT             Minimum volume   │
│                                                             scale factor.    │
│                                                             [default: 0.95]  │
│    --max-volume                           FLOAT             Maximum volume   │
│                                                             scale factor.    │
│                                                             [default: 1.05]  │
│    --n-volumes                            INTEGER           Number of        │
│                                                             volumes.         │
│                                                             [default: 7]     │
│    --eos-type                             [sj|taylor|murna  Type of fit for  │
│                                           ghan|birch|birch  equation of      │
│                                           murnaghan|pourie  state.           │
│                                           rtarantola|vinet  [default:        │
│                                           |antonschmidt|p3  birchmurnaghan]  │
│                                           ]                                  │
│    --minimize          --no-minimize                        Whether to       │
│                                                             minimize initial │
│                                                             structure before │
│                                                             calculations.    │
│                                                             [default:        │
│                                                             minimize]        │
│    --minimize-all      --no-minimize-…                      Whether to       │
│                                                             minimize all     │
│                                                             generated        │
│                                                             structures for   │
│                                                             calculations.    │
│                                                             [default:        │
│                                                             no-minimize-all] │
│    --fmax                                 FLOAT             Maximum force    │
│                                                             for optimization │
│                                                             convergence.     │
│                                                             [default: 0.1]   │
│    --minimize-kwar…                       DICT              Keyword          │
│                                                             arguments to     │
│                                                             pass to geometry │
│                                                             optimizer,       │
│                                                             including        │
│                                                             "opt_kwargs",    │
│                                                             "filter_kwargs", │
│                                                             and              │
│                                                             "traj_kwargs".   │
│                                                             Must be passed   │
│                                                             as a dictionary  │
│                                                             wrapped in       │
│                                                             quotes, e.g.     │
│                                                             "{'key':         │
│                                                             value}".         │
│    --write-structu…    --no-write-str…                      Whether to write │
│                                                             out all          │
│                                                             genereated       │
│                                                             structures.      │
│                                                             [default:        │
│                                                             no-write-struct… │
│    --plot-to-file      --no-plot-to-f…                      Whether to plot  │
│                                                             equation of      │
│                                                             state.           │
│                                                             [default:        │
│                                                             no-plot-to-file] │
╰──────────────────────────────────────────────────────────────────────────────╯
╭─ Structure I/O ──────────────────────────────────────────────────────────────╮
│ --file-prefix         PATH  Prefix for output files, including directories.  │
│                             Default directory is ./janus_results, and        │
│                             default filename prefix is inferred from the     │
│                             input stucture filename.                         │
│ --read-kwargs         DICT  Keyword arguments to pass to ase.io.read. Must   │
│                             be passed as a dictionary wrapped in quotes,     │
│                             e.g. "{'key': value}". By default,               │
│                             read_kwargs['index'] = -1, so only the last      │
│                             structure is read.                               │
│ --write-kwargs        DICT  Keyword arguments to pass to ase.io.write when   │
│                             saving any structures. Must be passed as a       │
│                             dictionary wrapped in quotes, e.g. "{'key':      │
│                             value}".                                         │
╰──────────────────────────────────────────────────────────────────────────────╯
╭─ Logging/summary ────────────────────────────────────────────────────────────╮
│ --log                        PATH  Path to save logs to. Default is inferred │
│                                    from `file_prefix`                        │
│ --tracker    --no-tracker          Whether to save carbon emissions of       │
│                                    calculation                               │
│                                    [default: tracker]                        │
│ --summary                    PATH  Path to save summary of inputs, start/end │
│                                    time, and carbon emissions. Default is    │
│                                    inferred from `file_prefix`.              │
╰──────────────────────────────────────────────────────────────────────────────╯

Equation of state for α-quartz

[6]:
%%writefile eos.yml

struct: ../data/α_quartz.xyz
device: cpu
arch: mace_mp
model: medium-omat-0
min_volume: 0.75
max_volume: 1.25
n_volumes: 20
plot_to_file: True
write_structures: True
minimize: False
tracker: False
Writing eos.yml
[7]:
!janus eos --config eos.yml
/home/runner/work/janus-core/janus-core/.venv/lib/python3.12/site-packages/e3nn/o3/_wigner.py:10: UserWarning: Environment variable TORCH_FORCE_NO_WEIGHTS_ONLY_LOAD detected, since the`weights_only` argument was not explicitly passed to `torch.load`, forcing weights_only=False.
  _Jd, _W3j_flat, _W3j_indices = torch.load(os.path.join(os.path.dirname(__file__), 'constants.pt'))
cuequivariance or cuequivariance_torch is not available. Cuequivariance acceleration will be disabled.
Using model under Academic Software License (ASL) license, see https://github.com/gabor1/ASL
 To use this model you accept the terms of the license.
Downloading MACE model from 'https://github.com/ACEsuit/mace-mp/releases/download/mace_omat_0/mace-omat-0-medium.model'
Cached MACE model to /home/runner/.cache/mace/maceomat0mediummodel
Using Materials Project MACE for MACECalculator with /home/runner/.cache/mace/maceomat0mediummodel
Using float64 for MACECalculator, which is slower but more accurate. Recommended for geometry optimization.
/home/runner/work/janus-core/janus-core/.venv/lib/python3.12/site-packages/mace/calculators/mace.py:199: UserWarning: Environment variable TORCH_FORCE_NO_WEIGHTS_ONLY_LOAD detected, since the`weights_only` argument was not explicitly passed to `torch.load`, forcing weights_only=False.
  torch.load(f=model_path, map_location=device)
[8]:
!ls janus_results/
Aluminium-elastic_tensor.dat            Diamond-elasticity-opt.extxyz
Aluminium-elasticity-log.yml            Diamond-elasticity-summary.yml
Aluminium-elasticity-summary.yml        α_quartz-eos-fit.dat
Carbon-nanotube-elastic_tensor.dat      α_quartz-eos-log.yml
Carbon-nanotube-elasticity-log.yml      α_quartz-eos-plot.svg
Carbon-nanotube-elasticity-summary.yml  α_quartz-eos-raw.dat
Diamond-elastic_tensor.dat              α_quartz-eos-summary.yml
Diamond-elasticity-generated.extxyz     α_quartz-generated.extxyz
Diamond-elasticity-log.yml

Since we saved the equation of state plot and generated structures, we can visualise these:

[9]:
from IPython.display import SVG, display
display(SVG("janus_results/α_quartz-eos-plot.svg"))
../../_images/tutorials_cli_eos_18_0.svg
[10]:
from ase.io import read

α_quartz_eos = read("janus_results/α_quartz-generated.extxyz", index=":")

w=WeasWidget()
w.from_ase(α_quartz_eos)
w.avr.model_style = 1
w.avr.show_hydrogen_bonds = True
w
[10]:

Equation of state for β-quartz

Perform the same calculation for β-quartz:

[11]:
β_quartz = read("data/beta_quartz.cif")

v=WeasWidget()
v.from_ase(β_quartz)
v.avr.model_style = 1
v.avr.show_hydrogen_bonds = True
v
[11]:

Here we also add to options to run geometry optimisations. --minimize performs a relaxation on the initial β-quartz structure, including allowing the cell to be fully optimised, while --minimize-all relaxes the scaled structures that are generated, but does so at constant volume automatically.

[12]:
!janus eos --config eos.yml --struct ../data/beta_quartz.cif --minimize --minimize-all
/home/runner/work/janus-core/janus-core/.venv/lib/python3.12/site-packages/e3nn/o3/_wigner.py:10: UserWarning: Environment variable TORCH_FORCE_NO_WEIGHTS_ONLY_LOAD detected, since the`weights_only` argument was not explicitly passed to `torch.load`, forcing weights_only=False.
  _Jd, _W3j_flat, _W3j_indices = torch.load(os.path.join(os.path.dirname(__file__), 'constants.pt'))
cuequivariance or cuequivariance_torch is not available. Cuequivariance acceleration will be disabled.
Using model under Academic Software License (ASL) license, see https://github.com/gabor1/ASL
 To use this model you accept the terms of the license.
Using Materials Project MACE for MACECalculator with /home/runner/.cache/mace/maceomat0mediummodel
Using float64 for MACECalculator, which is slower but more accurate. Recommended for geometry optimization.
/home/runner/work/janus-core/janus-core/.venv/lib/python3.12/site-packages/mace/calculators/mace.py:199: UserWarning: Environment variable TORCH_FORCE_NO_WEIGHTS_ONLY_LOAD detected, since the`weights_only` argument was not explicitly passed to `torch.load`, forcing weights_only=False.
  torch.load(f=model_path, map_location=device)
       Step     Time          Energy          fmax
LBFGS:    0 10:40:26      -70.816092        1.070473
LBFGS:    1 10:40:26      -70.878613        0.943653
LBFGS:    2 10:40:27      -71.049051        0.301119
LBFGS:    3 10:40:27      -71.059568        0.284711
LBFGS:    4 10:40:27      -71.109308        0.234023
LBFGS:    5 10:40:27      -71.122518        0.109988
LBFGS:    6 10:40:27      -71.125781        0.032544
       Step     Time          Energy          fmax
LBFGS:    0 10:40:27      -64.377985        3.217341
LBFGS:    1 10:40:28      -65.184060        2.614779
LBFGS:    2 10:40:28      -66.355112        0.872584
LBFGS:    3 10:40:28      -66.471393        0.411935
LBFGS:    4 10:40:28      -66.477159        0.434348
LBFGS:    5 10:40:28      -66.490048        0.469241
LBFGS:    6 10:40:29      -66.524917        0.532586
LBFGS:    7 10:40:29      -66.607286        0.693256
LBFGS:    8 10:40:29      -66.690228        0.906345
LBFGS:    9 10:40:29      -66.777735        1.028734
LBFGS:   10 10:40:29      -66.871437        1.075815
LBFGS:   11 10:40:30      -66.967941        1.034636
LBFGS:   12 10:40:30      -67.078366        0.825575
LBFGS:   13 10:40:30      -67.181760        0.292938
LBFGS:   14 10:40:30      -67.201648        0.051056
       Step     Time          Energy          fmax
LBFGS:    0 10:40:31      -66.024111        2.680454
LBFGS:    1 10:40:31      -66.584972        2.193493
LBFGS:    2 10:40:31      -67.501176        0.565529
LBFGS:    3 10:40:31      -67.556122        0.327320
LBFGS:    4 10:40:31      -67.559190        0.338748
LBFGS:    5 10:40:31      -67.571547        0.370929
LBFGS:    6 10:40:32      -67.599566        0.418291
LBFGS:    7 10:40:32      -67.662416        0.588852
LBFGS:    8 10:40:32      -67.724259        0.742209
LBFGS:    9 10:40:32      -67.790280        0.797124
LBFGS:   10 10:40:32      -67.857674        0.772962
LBFGS:   11 10:40:32      -67.932301        0.582794
LBFGS:   12 10:40:33      -67.989313        0.195350
LBFGS:   13 10:40:33      -67.998449        0.037340
       Step     Time          Energy          fmax
LBFGS:    0 10:40:33      -67.369598        2.201391
LBFGS:    1 10:40:33      -67.748775        1.812931
LBFGS:    2 10:40:34      -68.433065        0.350135
LBFGS:    3 10:40:34      -68.456852        0.257990
LBFGS:    4 10:40:34      -68.458518        0.262619
LBFGS:    5 10:40:34      -68.475423        0.293874
LBFGS:    6 10:40:34      -68.506576        0.354896
LBFGS:    7 10:40:34      -68.553926        0.496758
LBFGS:    8 10:40:35      -68.600485        0.550510
LBFGS:    9 10:40:35      -68.644075        0.501505
LBFGS:   10 10:40:35      -68.684906        0.272785
LBFGS:   11 10:40:35      -68.699560        0.055234
       Step     Time          Energy          fmax
LBFGS:    0 10:40:36      -68.453702        1.776856
LBFGS:    1 10:40:36      -68.701272        1.471674
LBFGS:    2 10:40:36      -69.187370        0.238250
LBFGS:    3 10:40:36      -69.196509        0.197890
LBFGS:    4 10:40:36      -69.197428        0.198842
LBFGS:    5 10:40:36      -69.238227        0.247402
LBFGS:    6 10:40:37      -69.271040        0.363898
LBFGS:    7 10:40:37      -69.299012        0.303164
LBFGS:    8 10:40:37      -69.313883        0.139707
LBFGS:    9 10:40:37      -69.317412        0.011580
       Step     Time          Energy          fmax
LBFGS:    0 10:40:38      -69.311989        1.402162
LBFGS:    1 10:40:38      -69.466470        1.167213
LBFGS:    2 10:40:38      -69.790662        0.163474
LBFGS:    3 10:40:38      -69.793860        0.143501
LBFGS:    4 10:40:38      -69.794343        0.142778
LBFGS:    5 10:40:38      -69.828835        0.099392
       Step     Time          Energy          fmax
LBFGS:    0 10:40:39      -69.974994        1.070704
LBFGS:    1 10:40:39      -70.065248        0.895462
LBFGS:    2 10:40:39      -70.264995        0.106942
LBFGS:    3 10:40:39      -70.266048        0.097596
       Step     Time          Energy          fmax
LBFGS:    0 10:40:40      -70.467520        0.775924
LBFGS:    1 10:40:40      -70.515007        0.651792
LBFGS:    2 10:40:40      -70.625160        0.061961
       Step     Time          Energy          fmax
LBFGS:    0 10:40:40      -70.809983        0.514369
LBFGS:    1 10:40:40      -70.830892        0.433894
LBFGS:    2 10:40:41      -70.881457        0.026687
       Step     Time          Energy          fmax
LBFGS:    0 10:40:41      -71.020666        0.283249
LBFGS:    1 10:40:41      -71.027021        0.239862
LBFGS:    2 10:40:41      -71.042969        0.003625
       Step     Time          Energy          fmax
LBFGS:    0 10:40:41      -71.116336        0.078834
       Step     Time          Energy          fmax
LBFGS:    0 10:40:42      -71.111870        0.103578
LBFGS:    1 10:40:42      -71.112725        0.088487
       Step     Time          Energy          fmax
LBFGS:    0 10:40:42      -71.019923        0.267027
LBFGS:    1 10:40:42      -71.025604        0.229081
LBFGS:    2 10:40:43      -71.041589        0.023152
       Step     Time          Energy          fmax
LBFGS:    0 10:40:43      -70.851020        0.412465
LBFGS:    1 10:40:43      -70.864595        0.355286
LBFGS:    2 10:40:43      -70.904070        0.026822
       Step     Time          Energy          fmax
LBFGS:    0 10:40:43      -70.613941        0.540996
LBFGS:    1 10:40:44      -70.637335        0.467931
LBFGS:    2 10:40:44      -70.707727        0.025270
       Step     Time          Energy          fmax
LBFGS:    0 10:40:44      -70.316527        0.654714
LBFGS:    1 10:40:44      -70.350858        0.568833
LBFGS:    2 10:40:44      -70.458071        0.021706
       Step     Time          Energy          fmax
LBFGS:    0 10:40:45      -69.966055        0.755534
LBFGS:    1 10:40:45      -70.011872        0.659518
LBFGS:    2 10:40:45      -70.160630        0.018928
       Step     Time          Energy          fmax
LBFGS:    0 10:40:45      -69.569334        0.844408
LBFGS:    1 10:40:45      -69.626690        0.740570
LBFGS:    2 10:40:46      -69.820386        0.017224
       Step     Time          Energy          fmax
LBFGS:    0 10:40:46      -69.132509        0.922020
LBFGS:    1 10:40:46      -69.201041        0.812387
LBFGS:    2 10:40:46      -69.441950        0.016461
       Step     Time          Energy          fmax
LBFGS:    0 10:40:47      -68.661218        0.989361
LBFGS:    1 10:40:47      -68.740294        0.875653
LBFGS:    2 10:40:47      -69.029836        0.016358
       Step     Time          Energy          fmax
LBFGS:    0 10:40:47      -68.160679        1.047655
LBFGS:    1 10:40:47      -68.249525        0.931186
LBFGS:    2 10:40:47      -68.588346        0.016671

We can now visulise these as before:

[13]:
display(SVG("janus_results/beta_quartz-eos-plot.svg"))
../../_images/tutorials_cli_eos_26_0.svg
[14]:
beta_quartz_eos = read("janus_results/beta_quartz-generated.extxyz", index=":")

w=WeasWidget()
w.from_ase(beta_quartz_eos)
w.avr.model_style = 1
w.avr.show_hydrogen_bonds = True
w
[14]: