Open In Colab

Geometry Optimization

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,orb,chgnet,visualise] data-tutorials --system # Install janus-core with MACE, Orb, CHGNet, 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.0

Prepare data and modules

[3]:
from ase.io import read
from ase.optimize import FIRE
from weas_widget import WeasWidget

from data_tutorials.data import get_data

from janus_core.calculations.single_point import SinglePoint
from janus_core.calculations.geom_opt import GeomOpt

Use data_tutorials to get the data required for this tutorial:

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

Prepare for optimization of a deformed salt structure

[5]:
NaCl = read("data/NaCl-deformed.xyz")
NaCl.wrap()
v=WeasWidget()
v.from_ase(NaCl)
v.avr.model_style = 1
v.avr.show_hydrogen_bonds = True
v
[5]:
[6]:
sp_mace = SinglePoint(
    struct=NaCl.copy(),
    arch="mace_mp",
    device="cpu",
    model="small",
    calc_kwargs={"default_dtype": "float64"},
    properties="energy",
)

init_energy = sp_mace.run()["energy"]
/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 Materials Project MACE for MACECalculator with /home/runner/.cache/mace/20231210mace128L0_energy_epoch249model
Using float64 for MACECalculator, which is slower but more accurate. Recommended for geometry optimization.
Using head Default out of ['Default']
/home/runner/work/janus-core/janus-core/.venv/lib/python3.12/site-packages/mace/calculators/mace.py:197: 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)

To optimize only the atomic positions and not the cell, set filter_class = None:

[7]:
optimized_NaCl = GeomOpt(
    struct=sp_mace.struct,
    fmax=0.001,
    filter_class=None,
)

optimized_NaCl.run()
v=WeasWidget()
v.from_ase(optimized_NaCl.struct)
v.avr.model_style = 1
v.avr.show_hydrogen_bonds = True
v
       Step     Time          Energy          fmax
LBFGS:    0 22:24:01      -24.377063        2.732337
LBFGS:    1 22:24:01      -24.576368        2.152513
LBFGS:    2 22:24:01      -25.093690        0.949845
LBFGS:    3 22:24:01      -25.290212        0.685740
LBFGS:    4 22:24:01      -25.403788        0.951695
LBFGS:    5 22:24:01      -25.465213        1.066671
LBFGS:    6 22:24:02      -25.566446        1.095941
LBFGS:    7 22:24:02      -25.695050        0.931041
LBFGS:    8 22:24:02      -25.856683        0.857034
LBFGS:    9 22:24:02      -26.109079        0.811033
LBFGS:   10 22:24:02      -26.298823        0.545193
LBFGS:   11 22:24:02      -26.353032        0.656387
LBFGS:   12 22:24:02      -26.383904        0.710488
LBFGS:   13 22:24:02      -26.485793        0.790107
LBFGS:   14 22:24:02      -26.643853        0.768081
LBFGS:   15 22:24:02      -26.751857        0.477356
LBFGS:   16 22:24:02      -26.792940        0.329784
LBFGS:   17 22:24:02      -26.815123        0.343673
LBFGS:   18 22:24:02      -26.829194        0.334430
LBFGS:   19 22:24:02      -26.845943        0.317718
LBFGS:   20 22:24:02      -26.912307        0.249075
LBFGS:   21 22:24:02      -26.975682        0.229256
LBFGS:   22 22:24:02      -27.018210        0.150833
LBFGS:   23 22:24:02      -27.023510        0.093603
LBFGS:   24 22:24:02      -27.024214        0.075937
LBFGS:   25 22:24:02      -27.025149        0.061405
LBFGS:   26 22:24:02      -27.026800        0.051912
LBFGS:   27 22:24:02      -27.028754        0.038049
LBFGS:   28 22:24:02      -27.029848        0.016211
LBFGS:   29 22:24:02      -27.030067        0.005215
LBFGS:   30 22:24:02      -27.030081        0.000579
[7]:

Check energy has been lowered, and cell is unchanged:

[8]:
print(f"Initial cell: {NaCl.cell.cellpar()}")
print(f"Initial energy: {init_energy}")

print(f"Final cell: {optimized_NaCl.struct.cell.cellpar()}")
print(f"Final energy: {optimized_NaCl.struct.get_potential_energy()}")
Initial cell: [ 5.63  5.63  5.63 90.   90.   90.  ]
Initial energy: -24.377062746436568
Final cell: [ 5.63  5.63  5.63 90.   90.   90.  ]
Final energy: -27.030081292879448

Optimizing cell vectors and atomic positions

Setting filter_kwargs = {"hydrostatic_strain": True} allows the cell lengths to be changed, in addition to atomic positions, but cell angles remain fixed:

[9]:
optimized_NaCl_lengths = GeomOpt(
    struct=NaCl.copy(),
    arch="mace_mp",
    device="cpu",
    model="small",
    calc_kwargs={"default_dtype": "float64"},
    fmax=0.001,
    filter_kwargs={"hydrostatic_strain": True},
)
optimized_NaCl_lengths.run()
Using Materials Project MACE for MACECalculator with /home/runner/.cache/mace/20231210mace128L0_energy_epoch249model
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:197: 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)
Using head Default out of ['Default']
       Step     Time          Energy          fmax
LBFGS:    0 22:24:03      -24.377063        2.732337
LBFGS:    1 22:24:03      -24.593123        2.143240
LBFGS:    2 22:24:03      -25.178180        0.955170
LBFGS:    3 22:24:03      -25.445502        0.670912
LBFGS:    4 22:24:03      -25.641907        0.919610
LBFGS:    5 22:24:03      -25.735611        1.036999
LBFGS:    6 22:24:03      -25.816918        1.015167
LBFGS:    7 22:24:03      -25.937123        0.774473
LBFGS:    8 22:24:03      -26.075553        0.561448
LBFGS:    9 22:24:03      -26.194652        0.423668
LBFGS:   10 22:24:03      -26.290628        0.391005
LBFGS:   11 22:24:04      -26.323319        0.439570
LBFGS:   12 22:24:04      -26.337274        0.452690
LBFGS:   13 22:24:04      -26.372755        0.457902
LBFGS:   14 22:24:04      -26.436676        0.640085
LBFGS:   15 22:24:04      -26.522182        0.786499
LBFGS:   16 22:24:04      -26.636096        0.839171
LBFGS:   17 22:24:04      -26.785166        0.746960
LBFGS:   18 22:24:04      -26.953112        0.390060
LBFGS:   19 22:24:04      -27.019414        0.155454
LBFGS:   20 22:24:04      -27.024708        0.104189
LBFGS:   21 22:24:04      -27.025735        0.100499
LBFGS:   22 22:24:04      -27.040218        0.057352
LBFGS:   23 22:24:04      -27.043130        0.040815
LBFGS:   24 22:24:04      -27.043931        0.043724
LBFGS:   25 22:24:04      -27.044043        0.046083
LBFGS:   26 22:24:04      -27.044456        0.047834
LBFGS:   27 22:24:04      -27.045052        0.042667
LBFGS:   28 22:24:05      -27.045824        0.025832
LBFGS:   29 22:24:05      -27.046215        0.014974
LBFGS:   30 22:24:05      -27.046303        0.010039
LBFGS:   31 22:24:05      -27.046314        0.008152
LBFGS:   32 22:24:05      -27.046320        0.006968
LBFGS:   33 22:24:05      -27.046335        0.004495
LBFGS:   34 22:24:05      -27.046350        0.003398
LBFGS:   35 22:24:05      -27.046360        0.001411
LBFGS:   36 22:24:05      -27.046362        0.000409

Check energy has been lowered, and cell lengths have been updated, but angles remain unchanged:

[10]:
print(f"Initial cell: {NaCl.cell.cellpar()}")
print(f"Initial energy: {init_energy}")

print(f"Final cell: {optimized_NaCl_lengths.struct.cell.cellpar()}")
print(f"Final energy: {optimized_NaCl_lengths.struct.get_potential_energy()}")
Initial cell: [ 5.63  5.63  5.63 90.   90.   90.  ]
Initial energy: -24.377062746436568
Final cell: [ 5.6899881  5.6899881  5.6899881 90.        90.        90.       ]
Final energy: -27.04636186918374

Optimizing at constant pressure and volume

Calculations can also be run at a fixed pressure and volume, by setting filter_kwargs = {"scalar_pressure": x, "constant_volume": True}

By default, both the cell lengths and angles will be optimized, in addition to the atomic positions.

We can also set the optimizer and filter class used, either by passing the function itself (e.g. FIRE) or passing the name of the ASE function (e.g. "ExpCellFilter"):

[11]:
optimized_NaCl_pressure = GeomOpt(
    struct=NaCl.copy(),
    arch="mace_mp",
    device="cpu",
    model="small",
    calc_kwargs={"default_dtype": "float64"},
    fmax=0.01,
    filter_kwargs={"scalar_pressure": 0.05, "constant_volume": True},
    optimizer=FIRE,
    filter_class="ExpCellFilter",
)
optimized_NaCl_pressure.run()
Using Materials Project MACE for MACECalculator with /home/runner/.cache/mace/20231210mace128L0_energy_epoch249model
Using float64 for MACECalculator, which is slower but more accurate. Recommended for geometry optimization.
Using head Default out of ['Default']
      Step     Time          Energy          fmax
FIRE:    0 22:24:05      -24.321372        2.732337
/home/runner/work/janus-core/janus-core/.venv/lib/python3.12/site-packages/mace/calculators/mace.py:197: 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)
FIRE:    1 22:24:05      -24.475808        2.425259
FIRE:    2 22:24:05      -24.724546        1.986743
FIRE:    3 22:24:06      -24.989394        1.591361
FIRE:    4 22:24:06      -25.210859        1.296455
FIRE:    5 22:24:06      -25.366900        1.075710
FIRE:    6 22:24:06      -25.474543        0.903170
FIRE:    7 22:24:06      -25.563058        0.768084
FIRE:    8 22:24:06      -25.665958        0.788916
FIRE:    9 22:24:06      -25.804701        0.776696
FIRE:   10 22:24:06      -25.988476        0.629292
FIRE:   11 22:24:06      -26.185598        0.524310
FIRE:   12 22:24:07      -26.372697        0.544405
FIRE:   13 22:24:07      -26.529609        0.549348
FIRE:   14 22:24:07      -26.651271        0.500647
FIRE:   15 22:24:07      -26.733248        0.625696
FIRE:   16 22:24:07      -26.759626        0.705539
FIRE:   17 22:24:07      -26.768425        0.680857
FIRE:   18 22:24:07      -26.784768        0.633003
FIRE:   19 22:24:07      -26.806559        0.564653
FIRE:   20 22:24:07      -26.831285        0.478909
FIRE:   21 22:24:07      -26.856128        0.378669
FIRE:   22 22:24:08      -26.878203        0.266994
FIRE:   23 22:24:08      -26.895576        0.173920
FIRE:   24 22:24:08      -26.909428        0.195730
FIRE:   25 22:24:08      -26.920433        0.206251
FIRE:   26 22:24:08      -26.930828        0.201829
FIRE:   27 22:24:08      -26.943629        0.195696
FIRE:   28 22:24:08      -26.958594        0.174490
FIRE:   29 22:24:08      -26.970475        0.100623
FIRE:   30 22:24:08      -26.970442        0.055335
FIRE:   31 22:24:08      -26.970688        0.053585
FIRE:   32 22:24:09      -26.971042        0.050145
FIRE:   33 22:24:09      -26.971388        0.045125
FIRE:   34 22:24:09      -26.971749        0.038836
FIRE:   35 22:24:09      -26.972173        0.034034
FIRE:   36 22:24:09      -26.972587        0.024280
FIRE:   37 22:24:09      -26.972874        0.026451
FIRE:   38 22:24:09      -26.973086        0.031830
FIRE:   39 22:24:09      -26.973328        0.035290
FIRE:   40 22:24:09      -26.973544        0.035381
FIRE:   41 22:24:09      -26.973728        0.030713
FIRE:   42 22:24:10      -26.974006        0.021361
FIRE:   43 22:24:10      -26.974169        0.026135
FIRE:   44 22:24:10      -26.974266        0.009379

Check cell lengths and angles have both been updated:

[12]:
print(f"Initial cell: {NaCl.cell.cellpar()}")
print(f"Initial energy: {init_energy}")

print(f"Final cell: {optimized_NaCl_pressure.struct.cell.cellpar()}")
print(f"Final energy: {optimized_NaCl_pressure.struct.get_potential_energy()}")
Initial cell: [ 5.63  5.63  5.63 90.   90.   90.  ]
Initial energy: -24.377062746436568
Final cell: [ 5.63000038  5.63000038  5.63000038 90.0297029  90.0297029  90.0297029 ]
Final energy: -27.02995673099468

Comparing MACE to CHGNet and Orb

[13]:
optimized_NaCl_mace = GeomOpt(
    struct=NaCl.copy(),
    arch="mace_mp",
    device="cpu",
    model="small",
    calc_kwargs={"default_dtype": "float64"},
    fmax=0.01,
)
optimized_NaCl_mace.run()

optimized_NaCl_chgnet = GeomOpt(
    struct=NaCl.copy(),
    arch="chgnet",
    device="cpu",
    calc_kwargs={"default_dtype": "float64"},
    fmax=0.01,
)
optimized_NaCl_chgnet.run()

optimized_NaCl_orb = GeomOpt(
    struct=NaCl.copy(),
    arch="orb",
    device="cpu",
    fmax=0.01,
)
optimized_NaCl_orb.run()
Using Materials Project MACE for MACECalculator with /home/runner/.cache/mace/20231210mace128L0_energy_epoch249model
Using float64 for MACECalculator, which is slower but more accurate. Recommended for geometry optimization.
Using head Default out of ['Default']
       Step     Time          Energy          fmax
LBFGS:    0 22:24:10      -24.377063        2.732337
/home/runner/work/janus-core/janus-core/.venv/lib/python3.12/site-packages/mace/calculators/mace.py:197: 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)
LBFGS:    1 22:24:10      -24.593440        2.145517
LBFGS:    2 22:24:10      -25.187807        0.956555
LBFGS:    3 22:24:10      -25.462335        0.675018
LBFGS:    4 22:24:10      -25.663853        0.932226
LBFGS:    5 22:24:10      -25.757785        1.056063
LBFGS:    6 22:24:10      -25.841303        1.038396
LBFGS:    7 22:24:10      -25.968290        0.806821
LBFGS:    8 22:24:11      -26.115858        0.539264
LBFGS:    9 22:24:11      -26.230485        0.404401
LBFGS:   10 22:24:11      -26.323082        0.351277
LBFGS:   11 22:24:11      -26.354901        0.404205
LBFGS:   12 22:24:11      -26.366593        0.418519
LBFGS:   13 22:24:11      -26.402172        0.433457
LBFGS:   14 22:24:11      -26.468589        0.596828
LBFGS:   15 22:24:11      -26.555830        0.733795
LBFGS:   16 22:24:11      -26.664503        0.782841
LBFGS:   17 22:24:11      -26.800773        0.695400
LBFGS:   18 22:24:11      -26.945555        0.318072
LBFGS:   19 22:24:11      -26.988824        0.103903
LBFGS:   20 22:24:11      -26.991370        0.096582
LBFGS:   21 22:24:11      -26.992831        0.094488
LBFGS:   22 22:24:11      -27.005617        0.089660
LBFGS:   23 22:24:11      -27.016434        0.131020
LBFGS:   24 22:24:12      -27.024799        0.125041
LBFGS:   25 22:24:12      -27.027461        0.088453
LBFGS:   26 22:24:12      -27.028315        0.072906
LBFGS:   27 22:24:12      -27.029306        0.076504
LBFGS:   28 22:24:12      -27.031938        0.077353
LBFGS:   29 22:24:12      -27.036130        0.065283
LBFGS:   30 22:24:12      -27.040555        0.072759
LBFGS:   31 22:24:12      -27.042541        0.055032
LBFGS:   32 22:24:12      -27.042957        0.032514
LBFGS:   33 22:24:12      -27.043064        0.029534
LBFGS:   34 22:24:12      -27.043288        0.029905
LBFGS:   35 22:24:12      -27.043771        0.028507
LBFGS:   36 22:24:12      -27.044653        0.023671
LBFGS:   37 22:24:12      -27.045667        0.028947
LBFGS:   38 22:24:12      -27.046214        0.014389
LBFGS:   39 22:24:12      -27.046318        0.007933
CHGNet v0.3.0 initialized with 412,525 parameters
CHGNet will run on cpu
       Step     Time          Energy          fmax
LBFGS:    0 22:24:17      -26.927519        2.412754
LBFGS:    1 22:24:17      -27.131769        1.918887
LBFGS:    2 22:24:17      -27.805649        0.565096
LBFGS:    3 22:24:17      -27.966398        0.791144
/home/runner/work/janus-core/janus-core/.venv/lib/python3.12/site-packages/chgnet/model/model.py:898: UserWarning: Converting a tensor with requires_grad=True to a scalar may lead to unexpected behavior.
Consider using tensor.detach() first. (Triggered internally at /pytorch/torch/csrc/autograd/generated/python_variable_methods.cpp:835.)
  volumes = torch.tensor(volumes, dtype=TORCH_DTYPE, device=atomic_numbers.device)
LBFGS:    4 22:24:17      -28.067207        1.082411
LBFGS:    5 22:24:17      -28.132507        1.174292
LBFGS:    6 22:24:17      -28.220081        1.044132
LBFGS:    7 22:24:17      -28.391470        0.548099
LBFGS:    8 22:24:17      -28.461403        0.419197
LBFGS:    9 22:24:17      -28.516052        0.275545
LBFGS:   10 22:24:17      -28.557798        0.262427
LBFGS:   11 22:24:17      -28.571011        0.290122
LBFGS:   12 22:24:17      -28.575558        0.297268
LBFGS:   13 22:24:17      -28.598141        0.317090
LBFGS:   14 22:24:17      -28.643257        0.323914
LBFGS:   15 22:24:17      -28.681053        0.465963
LBFGS:   16 22:24:18      -28.747177        0.497098
LBFGS:   17 22:24:18      -28.953279        0.500156
LBFGS:   18 22:24:18      -29.102619        0.430038
LBFGS:   19 22:24:18      -29.193966        0.207565
LBFGS:   20 22:24:18      -29.201214        0.186311
LBFGS:   21 22:24:18      -29.204494        0.160775
LBFGS:   22 22:24:18      -29.213297        0.181536
LBFGS:   23 22:24:18      -29.232578        0.229094
LBFGS:   24 22:24:18      -29.254755        0.194659
LBFGS:   25 22:24:18      -29.271690        0.120733
LBFGS:   26 22:24:18      -29.275749        0.104425
LBFGS:   27 22:24:18      -29.277817        0.117926
LBFGS:   28 22:24:18      -29.279467        0.115817
LBFGS:   29 22:24:18      -29.298828        0.095487
LBFGS:   30 22:24:18      -29.315758        0.082726
LBFGS:   31 22:24:18      -29.323410        0.074013
LBFGS:   32 22:24:18      -29.327663        0.054278
LBFGS:   33 22:24:18      -29.328339        0.049837
LBFGS:   34 22:24:18      -29.328655        0.049829
LBFGS:   35 22:24:18      -29.327896        0.050463
LBFGS:   36 22:24:18      -29.330303        0.044617
LBFGS:   37 22:24:19      -29.331505        0.044598
LBFGS:   38 22:24:19      -29.337666        0.033554
LBFGS:   39 22:24:19      -29.339407        0.048409
LBFGS:   40 22:24:19      -29.340347        0.031239
LBFGS:   41 22:24:19      -29.340654        0.030123
LBFGS:   42 22:24:19      -29.340794        0.031641
LBFGS:   43 22:24:19      -29.341143        0.033355
LBFGS:   44 22:24:19      -29.341845        0.033064
LBFGS:   45 22:24:19      -29.342831        0.025225
LBFGS:   46 22:24:19      -29.343571        0.012435
LBFGS:   47 22:24:19      -29.343821        0.004649
/home/runner/work/janus-core/janus-core/.venv/lib/python3.12/site-packages/orb_models/utils.py:30: UserWarning: Setting global torch default dtype to torch.float32.
  warnings.warn(f"Setting global torch default dtype to {torch_dtype}.")
       Step     Time          Energy          fmax
LBFGS:    0 22:24:31      -24.265068        2.678413
LBFGS:    1 22:24:32      -24.471870        2.155989
LBFGS:    2 22:24:32      -25.102158        0.877886
LBFGS:    3 22:24:32      -25.363667        0.906848
LBFGS:    4 22:24:32      -25.559238        1.167910
LBFGS:    5 22:24:32      -25.683277        1.254069
LBFGS:    6 22:24:32      -25.802898        1.159610
LBFGS:    7 22:24:32      -25.938736        0.842668
LBFGS:    8 22:24:32      -26.111637        0.630701
LBFGS:    9 22:24:32      -26.253666        0.466285
LBFGS:   10 22:24:32      -26.356255        0.433666
LBFGS:   11 22:24:33      -26.387625        0.464013
LBFGS:   12 22:24:33      -26.407810        0.466415
LBFGS:   13 22:24:33      -26.442593        0.505818
LBFGS:   14 22:24:33      -26.498718        0.614437
LBFGS:   15 22:24:33      -26.595448        0.710127
LBFGS:   16 22:24:33      -26.715576        0.711504
LBFGS:   17 22:24:33      -26.867531        0.545680
LBFGS:   18 22:24:33      -26.989849        0.213212
LBFGS:   19 22:24:33      -27.028296        0.185188
LBFGS:   20 22:24:33      -27.031578        0.170842
LBFGS:   21 22:24:34      -27.036880        0.148630
LBFGS:   22 22:24:34      -27.049822        0.102285
LBFGS:   23 22:24:34      -27.063940        0.087025
LBFGS:   24 22:24:34      -27.073883        0.063416
LBFGS:   25 22:24:34      -27.076620        0.060450
LBFGS:   26 22:24:34      -27.077190        0.061787
LBFGS:   27 22:24:34      -27.078074        0.062960
LBFGS:   28 22:24:34      -27.079899        0.063419
LBFGS:   29 22:24:34      -27.082930        0.060704
LBFGS:   30 22:24:34      -27.085873        0.052252
LBFGS:   31 22:24:35      -27.087301        0.042536
LBFGS:   32 22:24:35      -27.087769        0.037576
LBFGS:   33 22:24:35      -27.088093        0.041301
LBFGS:   34 22:24:35      -27.088867        0.049756
LBFGS:   35 22:24:35      -27.090239        0.050578
LBFGS:   36 22:24:35      -27.091965        0.033245
LBFGS:   37 22:24:35      -27.092955        0.021311
LBFGS:   38 22:24:35      -27.093100        0.012242
LBFGS:   39 22:24:35      -27.093132        0.013078
LBFGS:   40 22:24:35      -27.093147        0.012978
LBFGS:   41 22:24:36      -27.093227        0.011362
LBFGS:   42 22:24:36      -27.093409        0.009878
[14]:
print(f"Initial energy: {init_energy}")

print(f"Final energy (MACE): {optimized_NaCl_mace.struct.get_potential_energy()}")
print(f"Final energy (CHGNet): {optimized_NaCl_chgnet.struct.get_potential_energy()}")
print(f"Final energy (Orb): {optimized_NaCl_orb.struct.get_potential_energy()}")
Initial energy: -24.377062746436568
Final energy (MACE): -27.046318223074785
Final energy (CHGNet): -29.343820571899414
Final energy (Orb): -27.093408584594727