Skip to content

Commit

Permalink
Merge pull request #148 from pyiron/matgl
Browse files Browse the repository at this point in the history
Matgl: Test universal machine learning potential
  • Loading branch information
jan-janssen authored Dec 18, 2023
2 parents fad4a11 + a2ffeb7 commit 3ca0504
Show file tree
Hide file tree
Showing 7 changed files with 258 additions and 1 deletion.
4 changes: 4 additions & 0 deletions .ci_support/environment-matgl.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
channels:
- conda-forge
dependencies:
- matgl =0.9.1
36 changes: 36 additions & 0 deletions .github/workflows/unittests_matgl.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: MatGL Unittest Linux 3.11

on:
push:
branches: [ main ]
pull_request:

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Merge Notebook environment
run: |
cp .ci_support/environment.yml environment.yml
tail --lines=+4 .ci_support/environment-matgl.yml >> environment.yml
- name: Setup Mambaforge
uses: conda-incubator/setup-miniconda@v2
with:
python-version: '3.11'
miniforge-variant: Mambaforge
channels: conda-forge
channel-priority: strict
activate-environment: my-env
environment-file: environment.yml
use-mamba: true
- name: Test
shell: bash -l {0}
timeout-minutes: 60
run: |
pip install versioneer[toml]==0.29
pip install . --no-deps --no-build-isolation
python -m unittest tests/test_evcurve_ase_matgl.py
python -m unittest tests/test_phonons_ase_matgl.py
python -m unittest tests/test_quasiharmonic_ase_matgl.py
python -m unittest tests/test_ase_md_matgl.py
1 change: 0 additions & 1 deletion tests/test_ase_md_emt.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ def test_ase_langevin(self):
temperature=100,
friction=0.002,
)
print(result_dict)
self.assertEqual(result_dict["positions"].shape, (10, 32, 3))
self.assertEqual(result_dict["velocities"].shape, (10, 32, 3))
self.assertEqual(result_dict["cell"].shape, (10, 3, 3))
Expand Down
41 changes: 41 additions & 0 deletions tests/test_ase_md_matgl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from ase import units
from ase.build import bulk
from atomistics.calculators import calc_molecular_dynamics_langevin_with_ase
import unittest


try:
import matgl
from matgl.ext.ase import M3GNetCalculator

skip_matgl_test = False
except ImportError:
skip_matgl_test = True


@unittest.skipIf(
skip_matgl_test, "matgl is not installed, so the matgl tests are skipped."
)
class TestASEMD(unittest.TestCase):
def test_ase_langevin(self):
structure = bulk("Al", cubic=True).repeat([2, 2, 2])
ase_calculator = M3GNetCalculator(matgl.load_model("M3GNet-MP-2021.2.8-PES"))
result_dict = calc_molecular_dynamics_langevin_with_ase(
structure=structure,
ase_calculator=ase_calculator,
run=100,
thermo=10,
timestep=1 * units.fs,
temperature=100,
friction=0.002,
)
self.assertEqual(result_dict["positions"].shape, (10, 32, 3))
self.assertEqual(result_dict["velocities"].shape, (10, 32, 3))
self.assertEqual(result_dict["cell"].shape, (10, 3, 3))
self.assertEqual(result_dict["forces"].shape, (10, 32, 3))
self.assertEqual(result_dict["temperature"].shape, (10, ))
self.assertEqual(result_dict["energy_pot"].shape, (10, ))
self.assertEqual(result_dict["energy_tot"].shape, (10, ))
self.assertEqual(result_dict["pressure"].shape, (10, 3, 3))
self.assertTrue(result_dict["temperature"][-1] > 25)
self.assertTrue(result_dict["temperature"][-1] < 75)
54 changes: 54 additions & 0 deletions tests/test_evcurve_ase_matgl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from ase.build import bulk
from ase.optimize import LBFGS
import numpy as np
import unittest

from atomistics.calculators import evaluate_with_ase
from atomistics.workflows import optimize_positions_and_volume, EnergyVolumeCurveWorkflow


try:
import matgl
from matgl.ext.ase import M3GNetCalculator

skip_matgl_test = False
except ImportError:
skip_matgl_test = True


@unittest.skipIf(
skip_matgl_test, "matgl is not installed, so the matgl tests are skipped."
)
class TestEvCurve(unittest.TestCase):
def test_calc_evcurve(self):
structure = bulk("Al", cubic=True)
ase_calculator = M3GNetCalculator(matgl.load_model("M3GNet-MP-2021.2.8-PES"))
task_dict = optimize_positions_and_volume(structure=structure)
result_dict = evaluate_with_ase(
task_dict=task_dict,
ase_calculator=ase_calculator,
ase_optimizer=LBFGS,
ase_optimizer_kwargs={"fmax": 0.001}
)
workflow = EnergyVolumeCurveWorkflow(
structure=result_dict["structure_with_optimized_positions_and_volume"],
num_points=11,
fit_type='polynomial',
fit_order=3,
vol_range=0.05,
axes=('x', 'y', 'z'),
strains=None,
)
task_dict = workflow.generate_structures()
result_dict = evaluate_with_ase(
task_dict=task_dict,
ase_calculator=ase_calculator,
)
fit_dict = workflow.analyse_structures(output_dict=result_dict)
temperatures_ev, volumes_ev = workflow.get_thermal_expansion(output_dict=result_dict, temperatures=[100, 1000])
self.assertTrue(np.isclose(fit_dict['volume_eq'], 66.56048874824006, atol=1e-04))
self.assertTrue(np.isclose(fit_dict['bulkmodul_eq'], 50.96266448851179, atol=1e-02))
self.assertTrue(np.isclose(fit_dict['b_prime_eq'], 4.674534962000779, atol=1e-02))
self.assertEqual(len(temperatures_ev), 2)
self.assertEqual(len(volumes_ev), 2)
self.assertTrue(volumes_ev[0] < volumes_ev[-1])
55 changes: 55 additions & 0 deletions tests/test_phonons_ase_matgl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from ase.build import bulk
from ase.optimize import LBFGS
from phonopy.units import VaspToTHz
import unittest

from atomistics.calculators import evaluate_with_ase
from atomistics.workflows import optimize_positions_and_volume, PhonopyWorkflow


try:
import matgl
from matgl.ext.ase import M3GNetCalculator

skip_matgl_test = False
except ImportError:
skip_matgl_test = True


@unittest.skipIf(
skip_matgl_test, "matgl is not installed, so the matgl tests are skipped."
)
class TestPhonons(unittest.TestCase):
def test_calc_phonons(self):
structure = bulk("Al", cubic=True)
ase_calculator = M3GNetCalculator(matgl.load_model("M3GNet-MP-2021.2.8-PES"))
task_dict = optimize_positions_and_volume(structure=structure)
result_dict = evaluate_with_ase(
task_dict=task_dict,
ase_calculator=ase_calculator,
ase_optimizer=LBFGS,
ase_optimizer_kwargs={"fmax": 0.001}
)
workflow = PhonopyWorkflow(
structure=result_dict["structure_with_optimized_positions_and_volume"],
interaction_range=10,
factor=VaspToTHz,
displacement=0.01,
dos_mesh=20,
primitive_matrix=None,
number_of_snapshots=None,
)
task_dict = workflow.generate_structures()
result_dict = evaluate_with_ase(
task_dict=task_dict,
ase_calculator=ase_calculator,
)
mesh_dict, dos_dict = workflow.analyse_structures(output_dict=result_dict)
self.assertEqual((324, 324), workflow.get_hesse_matrix().shape)
self.assertTrue('qpoints' in mesh_dict.keys())
self.assertTrue('weights' in mesh_dict.keys())
self.assertTrue('frequencies' in mesh_dict.keys())
self.assertTrue('eigenvectors' in mesh_dict.keys())
self.assertTrue('group_velocities' in mesh_dict.keys())
self.assertTrue('frequency_points' in dos_dict.keys())
self.assertTrue('total_dos' in dos_dict.keys())
68 changes: 68 additions & 0 deletions tests/test_quasiharmonic_ase_matgl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from ase.build import bulk
from ase.optimize import LBFGS
from phonopy.units import VaspToTHz
import unittest

from atomistics.calculators import evaluate_with_ase
from atomistics.workflows import QuasiHarmonicWorkflow, optimize_positions_and_volume


try:
import matgl
from matgl.ext.ase import M3GNetCalculator

skip_matgl_test = False
except ImportError:
skip_matgl_test = True


@unittest.skipIf(
skip_matgl_test, "matgl is not installed, so the matgl tests are skipped."
)
class TestPhonons(unittest.TestCase):
def test_calc_phonons(self):
structure = bulk("Al", cubic=True)
ase_calculator = M3GNetCalculator(matgl.load_model("M3GNet-MP-2021.2.8-PES"))
task_dict = optimize_positions_and_volume(structure=structure)
result_dict = evaluate_with_ase(
task_dict=task_dict,
ase_calculator=ase_calculator,
ase_optimizer=LBFGS,
ase_optimizer_kwargs={"fmax": 0.001}
)
workflow = QuasiHarmonicWorkflow(
structure=result_dict["structure_with_optimized_positions_and_volume"],
num_points=11,
vol_range=0.10,
interaction_range=10,
factor=VaspToTHz,
displacement=0.01,
dos_mesh=20,
primitive_matrix=None,
number_of_snapshots=None,
)
task_dict = workflow.generate_structures()
result_dict = evaluate_with_ase(
task_dict=task_dict,
ase_calculator=ase_calculator,
)
eng_internal_dict, mesh_collect_dict, dos_collect_dict = workflow.analyse_structures(output_dict=result_dict)
tp_collect_dict = workflow.get_thermal_properties(t_min=1, t_max=501, t_step=50, temperatures=None)
temperatures_qh_qm, volumes_qh_qm = workflow.get_thermal_expansion(
output_dict=result_dict,
temperatures=[100, 500],
quantum_mechanical=True
)
temperatures_qh_cl, volumes_qh_cl = workflow.get_thermal_expansion(
output_dict=result_dict,
temperatures=[100, 500],
quantum_mechanical=False
)
self.assertEqual(len(eng_internal_dict.keys()), 11)
self.assertEqual(len(tp_collect_dict.keys()), 5)
self.assertEqual(len(temperatures_qh_qm), 2)
self.assertEqual(len(volumes_qh_qm), 2)
self.assertTrue(volumes_qh_qm[0] < volumes_qh_qm[-1])
self.assertEqual(len(temperatures_qh_cl), 2)
self.assertEqual(len(volumes_qh_cl), 2)
self.assertTrue(volumes_qh_cl[0] < volumes_qh_cl[-1])

0 comments on commit 3ca0504

Please sign in to comment.