Skip to content

Commit

Permalink
Merge pull request #65 from jan-janssen/atomistics_evcurve
Browse files Browse the repository at this point in the history
Calculate Energy volume curve with atomistics package
  • Loading branch information
jan-janssen authored Aug 30, 2024
2 parents 9d6c388 + 2b20a1f commit 245896b
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 20 deletions.
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ channels:
- conda-forge
dependencies:
- ase =3.23.0
- atomistics =0.1.32
- langchain =0.2.5
- numexpr =2.10.0
- langchain-openai =0.1.8
Expand Down
65 changes: 49 additions & 16 deletions langsim/tools/interface.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import os
from ase.atoms import Atoms
from ase.build import bulk
from ase.constraints import UnitCellFilter
from ase.eos import calculate_eos, plot
from ase.optimize import LBFGS
from ase.units import kJ
from atomistics.calculators import evaluate_with_ase
from atomistics.workflows import optimize_positions_and_volume
from atomistics.workflows.evcurve.helper import (
analyse_structures_helper,
generate_structures_helper,
)
import pandas
from langchain.agents import tool
from mendeleev.fetch import fetch_table
Expand Down Expand Up @@ -48,10 +52,13 @@ def get_atom_dict_equilibrated_structure(
AtomsDict: DataClass representing the equilibrated atomic structure
"""
try:
atoms = Atoms(**atom_dict.dict())
atoms.calc = get_calculator(calculator_str=calculator_str)
ase_optimizer_obj = LBFGS(UnitCellFilter(atoms))
ase_optimizer_obj.run(fmax=0.000001)
task_dict = optimize_positions_and_volume(structure=Atoms(**atom_dict.dict()))
atoms = evaluate_with_ase(
task_dict=task_dict,
ase_calculator=get_calculator(calculator_str=calculator_str),
ase_optimizer=LBFGS,
ase_optimizer_kwargs={"fmax": 0.000001},
)["structure_with_optimized_positions_and_volume"]
return AtomsDict(**{k: v.tolist() for k, v in atoms.todict().items()})
except Exception as error:
# handle the exception
Expand Down Expand Up @@ -98,11 +105,24 @@ def get_bulk_modulus(atom_dict: AtomsDict, calculator_str: str) -> str:
str: Bulk Modulus in GPa
"""
try:
atoms = Atoms(**atom_dict.dict())
atoms.calc = get_calculator(calculator_str=calculator_str)
eos = calculate_eos(atoms)
v, e, B = eos.fit()
return B / kJ * 1.0e24
structure_dict = generate_structures_helper(
structure=Atoms(**atom_dict.dict()),
vol_range=0.05,
num_points=11,
strain_lst=None,
axes=("x", "y", "z"),
)
result_dict = evaluate_with_ase(
task_dict={"calc_energy": structure_dict},
ase_calculator=get_calculator(calculator_str=calculator_str),
)
fit_dict = analyse_structures_helper(
output_dict=result_dict,
structure_dict=structure_dict,
fit_type="polynomial",
fit_order=5,
)
return fit_dict["bulkmodul_eq"]
except Exception as error:
# handle the exception
return "An exception occurred: {}"
Expand All @@ -124,11 +144,24 @@ def get_equilibrium_volume(atom_dict: AtomsDict, calculator_str: str) -> str:
Returns:
str: Equilibrium volume in Angstrom^3
"""
atoms = Atoms(**atom_dict.dict())
atoms.calc = get_calculator(calculator_str=calculator_str)
eos = calculate_eos(atoms)
v, e, B = eos.fit()
return v
structure_dict = generate_structures_helper(
structure=Atoms(**atom_dict.dict()),
vol_range=0.05,
num_points=11,
strain_lst=None,
axes=("x", "y", "z"),
)
result_dict = evaluate_with_ase(
task_dict={"calc_energy": structure_dict},
ase_calculator=get_calculator(calculator_str=calculator_str),
)
fit_dict = analyse_structures_helper(
output_dict=result_dict,
structure_dict=structure_dict,
fit_type="polynomial",
fit_order=5,
)
return fit_dict["volume_eq"]


@tool
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
packages=find_packages(),
install_requires=[
"ase==3.23.0",
"atomistics==0.1.32",
"langchain==0.2.5",
"numexpr==2.10.0",
"langchain-openai==0.1.8",
Expand All @@ -23,4 +24,4 @@
"langchain-experimental==0.0.61",
],
}
)
)
6 changes: 3 additions & 3 deletions tests/test_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ def test_structure(self):

def test_bulk_modulus(self):
b0 = get_bulk_modulus.invoke({"atom_dict": self.structure, "calculator_str": self.calculator_str})
self.assertAlmostEqual(b0, 39.518515298270835)
self.assertAlmostEqual(b0, 39.73699875059587)

def test_equilibrium_volume(self):
v0 = get_equilibrium_volume.invoke({"atom_dict": self.structure, "calculator_str": self.calculator_str})
self.assertAlmostEqual(v0, 15.931553356465589)
self.assertAlmostEqual(v0, 15.931368308723524)


class TestInterfaceMace(TestCase):
Expand All @@ -51,7 +51,7 @@ def test_structure(self):

def test_bulk_modulus(self):
b0 = get_bulk_modulus.invoke({"atom_dict": self.structure, "calculator_str": self.calculator_str})
self.assertTrue(np.isclose(b0, 63.866120321206715, atol=10**-2))
self.assertTrue(np.isclose(b0, 63.508867430434144, atol=10**-2))

def test_equilibrium_volume(self):
v0 = get_equilibrium_volume.invoke({"atom_dict": self.structure, "calculator_str": self.calculator_str})
Expand Down

0 comments on commit 245896b

Please sign in to comment.