Skip to content

Commit

Permalink
Update calculators
Browse files Browse the repository at this point in the history
  • Loading branch information
wgst authored Aug 12, 2024
1 parent e2841d0 commit cf9e74c
Show file tree
Hide file tree
Showing 13 changed files with 357 additions and 18 deletions.
2 changes: 1 addition & 1 deletion docs/adaptive_sampling/adaptive_sampling.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
layout: default
title: Adaptive sampling
nav_order: 7
nav_order: 10
has_children: true
permalink: /docs/adaptive_sampling
has_toc: false
Expand Down
2 changes: 1 addition & 1 deletion docs/adaptive_sampling/clustering.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
layout: default
title: Structure selection
parent: Adaptive sampling
nav_order: 9
nav_order: 12
---

# Structure selection
Expand Down
2 changes: 1 addition & 1 deletion docs/adaptive_sampling/high_error_structure_search.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
layout: default
title: High-error structure search
parent: Adaptive sampling
nav_order: 8
nav_order: 11
---

# High-energy structure search
Expand Down
69 changes: 69 additions & 0 deletions docs/calculators/ace.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
layout: default
title: ACE
parent: MLIP calculators
nav_order: 9
---

# ACE calculator

[ACEpotentials](https://github.com/ACEsuit/ACEpotentials.jl) is an atomic cluster expansion (ACE)-based linear MLIP.

Below are the instructions on how to initialize the ACEpotentials calculator, to run dynamics simulations within [NQCDynamics.jl](https://github.com/NQCD/NQCDynamics.jl) using [ASE interface](https://nqcd.github.io/NQCDynamics.jl/stable/NQCModels/ase/).

{: .warning }
The following instructions will include **Julia**-based code.

We start with importing NQCDynamics.jl packages and PyCall which allows importing Python-based packages.

```jl
using NQCDynamics
using PyCall
using NQCModels

# Importing Python modules with PyCall
io = pyimport("ase.io")
pyjulip = pyimport("pyjulip")
```


Now, we specify the cutoff distance, paths to the model, and Atoms objects. Then we read the ASE atoms object and we convert it to NQCDynamics object.

```jl
pes_model_path = "path/to/ace/model/h2cu_ace.json"
atoms_path = "path/to/atoms.xyz"
ase_atoms = io.read(atoms_path)
atoms, positions, cell = NQCDynamics.convert_from_ase_atoms(ase_atoms)
```


We then set up our ACEpotentials calculator and create NQCModels [AdiabaticASEModel](https://nqcd.github.io/NQCDynamics.jl/stable/api/NQCModels/adiabaticmodels/#NQCModels.AdiabaticModels.AdiabaticASEModel) object that includes the model.

```jl
calculator = pyjulip.ACE1(pes_model_path)
ase_atoms.set_calculator(calculator)
pes_model = AdiabaticASEModel(ase_atoms)
```

The model can be loaded also directly within julia:

```jl
using ASE
using JuLIP
using ACE1

IP = ACE1.read_dict(load_dict(model_path)["IP"])
JuLIP.set_calculator!(ase_atoms, IP)
pes_model = AdiabaticModels.JuLIPModel(ase_atoms)
```

Finally, we can use the model to e.g. initialize [Simulation](https://nqcd.github.io/NQCDynamics.jl/stable/api/NQCDynamics/nonadiabaticmoleculardynamics/#NQCDynamics.Simulation-Union%7BTuple%7BT%7D,%20Tuple%7BM%7D,%20Tuple%7BAtoms%7BT%7D,%20NQCModels.Model,%20M%7D%7D%20where%20%7BM,%20T%7D) object that is employed to run MD simulations.

```jl
sim = Simulation{Classical}(atoms, pes_model, cell=cell)
```


## References

[K. Schütt, O. Unke, M. Gastegger, Equivariant message passing for the prediction of tensorial properties and molecular spectra, PMLR 2021](https://proceedings.mlr.press/v139/schutt21a.html)
60 changes: 60 additions & 0 deletions docs/calculators/mace.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
layout: default
title: MACE
parent: MLIP calculators
nav_order: 8
---

# MACE calculator

[MACE](https://github.com/ACEsuit/mace) is an equivariant message-passing neural-network-based MLIP.

Below are the instructions on how to initialize the MACE calculator, to run dynamics simulations within [NQCDynamics.jl](https://github.com/NQCD/NQCDynamics.jl) using [ASE interface](https://nqcd.github.io/NQCDynamics.jl/stable/NQCModels/ase/).

{: .warning }
The following instructions will include **Julia**-based code.

We start with importing NQCDynamics.jl packages and PyCall which allows importing Python-based packages.

```jl
using NQCDynamics
using PyCall
using NQCModels

# Importing Python modules with PyCall
io = pyimport("ase.io")
mace_calc = pyimport("mace.calculators")
```


Now, we specify the cutoff distance, paths to the model, and Atoms objects. Then we read the ASE atoms object and we convert it to NQCDynamics object.

```jl
pes_model_path = "path/to/ace/model/MACE_model_swa.model"
atoms_path = "path/to/atoms.xyz"
ase_atoms = io.read(atoms_path)
atoms, positions, cell = NQCDynamics.convert_from_ase_atoms(ase_atoms)
```


We then set up our MACE calculator and create NQCModels [AdiabaticASEModel](https://nqcd.github.io/NQCDynamics.jl/stable/api/NQCModels/adiabaticmodels/#NQCModels.AdiabaticModels.AdiabaticASEModel) object that includes the model.

```jl
calculator = mace_calc.MACECalculator(
model_path=pes_model_path,
device="cpu",
default_dtype="float32") # device = "cpu" or "cuda"
ase_atoms.set_calculator(calculator)
pes_model = AdiabaticASEModel(ase_atoms)
```

Finally, we can use the model to e.g. initialize [Simulation](https://nqcd.github.io/NQCDynamics.jl/stable/api/NQCDynamics/nonadiabaticmoleculardynamics/#NQCDynamics.Simulation-Union%7BTuple%7BT%7D,%20Tuple%7BM%7D,%20Tuple%7BAtoms%7BT%7D,%20NQCModels.Model,%20M%7D%7D%20where%20%7BM,%20T%7D) object that is employed to run MD simulations.

```jl
sim = Simulation{Classical}(atoms, pes_model, cell=cell)
```


## References

[K. Schütt, O. Unke, M. Gastegger, Equivariant message passing for the prediction of tensorial properties and molecular spectra, PMLR 2021](https://proceedings.mlr.press/v139/schutt21a.html)
18 changes: 11 additions & 7 deletions docs/calculators/painn.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ nav_order: 6

# PaiNN calculator

[PaiNN](https://github.com/atomistic-machine-learning/schnetpack) is an equivariant message-passing neural-network-based MLIPs.
[PaiNN](https://github.com/atomistic-machine-learning/schnetpack) is an equivariant message-passing neural-network-based MLIP.

Below are the instructions on how to initialize the PaiNN calculator, to run dynamics simulations within [NQCDynamics.jl](https://github.com/NQCD/NQCDynamics.jl) using [ASE interface](https://nqcd.github.io/NQCDynamics.jl/stable/NQCModels/ase/).

Expand All @@ -23,9 +23,8 @@ using NQCModels

# Importing Python modules with PyCall
io = pyimport("ase.io")
spk_interfaces = pyimport("schnetpack.interfaces")
spk_ase_interface = pyimport("schnetpack.interfaces.ase_interface")
spk_transform = pyimport("schnetpack.transform")
torch = pyimport("torch")
```


Expand All @@ -43,11 +42,16 @@ atoms, positions, cell = NQCDynamics.convert_from_ase_atoms(ase_atoms)
We then set up our PaiNN calculator and create NQCModels [AdiabaticASEModel](https://nqcd.github.io/NQCDynamics.jl/stable/api/NQCModels/adiabaticmodels/#NQCModels.AdiabaticModels.AdiabaticASEModel) object that includes the model.

```jl
best_model = torch.load(pes_model_path,map_location=torch.device("cpu") ).to("cpu")
converter = spk_interfaces.AtomsConverter(neighbor_list=spk_transform.ASENeighborList(cutoff=cutoff), dtype=torch.float32)
calculator = spk_interfaces.SpkCalculator(model=best_model, converter=converter, energy_units="eV", forces_units="eV/Angstrom")
calculator = spk_ase_interface.SpkCalculator(
model_file=pes_model_path,
stress_key="stress",
neighbor_list=spk_transform.ASENeighborList(cutoff=cutoff),
energy_unit="eV",
forces_units="eV/Angstrom",
stress_units="eV/Ang/Ang/Ang"
)
ase_atoms.set_calculator(calculator)
model = AdiabaticASEModel(ase_atoms)
pes_model = AdiabaticASEModel(ase_atoms)
```

Finally, we can use the model to e.g. initialize [Simulation](https://nqcd.github.io/NQCDynamics.jl/stable/api/NQCDynamics/nonadiabaticmoleculardynamics/#NQCDynamics.Simulation-Union%7BTuple%7BT%7D,%20Tuple%7BM%7D,%20Tuple%7BAtoms%7BT%7D,%20NQCModels.Model,%20M%7D%7D%20where%20%7BM,%20T%7D) object that is employed to run MD simulations.
Expand Down
64 changes: 64 additions & 0 deletions docs/calculators/reann.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
layout: default
title: REANN
parent: MLIP calculators
nav_order: 7
---

# REANN calculator

[REANN](https://github.com/zhangylch/REANN) (recursively embedded atom neural network) is a message-passing neural-network-based MLIP.

Below are the instructions on how to initialize the REANN calculator, to run dynamics simulations within [NQCDynamics.jl](https://github.com/NQCD/NQCDynamics.jl) using [ASE interface](https://nqcd.github.io/NQCDynamics.jl/stable/NQCModels/ase/).

{: .warning }
The following instructions will include **Julia**-based code.

We start with importing NQCDynamics.jl packages and PyCall which allows importing Python-based packages.

```jl
using NQCDynamics
using PyCall
using NQCModels

# Importing Python modules with PyCall
io = pyimport("ase.io")
reann = pyimport("ase.calculators.reann")
```


Now, we specify the cutoff distance, paths to the model, and Atoms objects. Then we read the ASE atoms object and we convert it to NQCDynamics object.

```jl
pes_model_path = "path/to/reann/model/REANN_PES_DOUBLE.pt"
atoms_path = "path/to/atoms.xyz"
ase_atoms = io.read(atoms_path)
atoms, positions, cell = NQCDynamics.convert_from_ase_atoms(ase_atoms)
```


We then set up our REANN calculator and create NQCModels [AdiabaticASEModel](https://nqcd.github.io/NQCDynamics.jl/stable/api/NQCModels/adiabaticmodels/#NQCModels.AdiabaticModels.AdiabaticASEModel) object that includes the model.

```jl
atomtype = ["Cu","H"]
period = [1,1,1]

calculator = reann.REANN(
device="cpu",
atomtype=atomtype,
period=period,
nn=pes_model_path)
ase_atoms.set_calculator(calculator)
pes_model = AdiabaticASEModel(ase_atoms)
```

Finally, we can use the model to e.g. initialize [Simulation](https://nqcd.github.io/NQCDynamics.jl/stable/api/NQCDynamics/nonadiabaticmoleculardynamics/#NQCDynamics.Simulation-Union%7BTuple%7BT%7D,%20Tuple%7BM%7D,%20Tuple%7BAtoms%7BT%7D,%20NQCModels.Model,%20M%7D%7D%20where%20%7BM,%20T%7D) object that is employed to run MD simulations.

```jl
sim = Simulation{Classical}(atoms, pes_model, cell=cell)
```


## References

[K. Schütt, O. Unke, M. Gastegger, Equivariant message passing for the prediction of tensorial properties and molecular spectra, PMLR 2021](https://proceedings.mlr.press/v139/schutt21a.html)
4 changes: 2 additions & 2 deletions docs/calculators/schnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ nav_order: 5

# SchNet calculator

[SchNet](https://github.com/atomistic-machine-learning/schnetpack) is one of the most popular message-passing neural-network-based MLIPs.
[SchNet](https://github.com/atomistic-machine-learning/schnetpack) is one of the most popular message-passing neural-network-based MLIP.

Below are the instructions on how to initialize the SchNet calculator, to run dynamics simulations within [NQCDynamics.jl](https://github.com/NQCD/NQCDynamics.jl) using [ASE interface](https://nqcd.github.io/NQCDynamics.jl/stable/NQCModels/ase/).

Expand Down Expand Up @@ -44,7 +44,7 @@ model_args = spk_utils.read_from_json("$(pes_model_path)/args.json")
environment_provider = spk_utils.script_utils.settings.get_environment_provider(model_args,device="cpu")
calculator = spk_interfaces.SpkCalculator(spk_model, energy="energy", forces="forces", environment_provider=environment_provider)
ase_atoms.set_calculator(calculator)
model = AdiabaticASEModel(ase_atoms)
pes_model = AdiabaticASEModel(ase_atoms)
```


Expand Down
36 changes: 36 additions & 0 deletions scripts/calculators/pes/ace_jl.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using NQCDynamics
using PyCall
using NQCModels
using ASE
using JuLIP
using ACE1

# Importing Python modules with PyCall
io = pyimport("ase.io")
pyjulip = pyimport("pyjulip")

"""
Function for creating ASE object from ACE model
"""
function ace_model_pes(model_path, cur_atoms) # cur_atoms has to be JuLIP atoms object
IP = ACE1.read_dict(load_dict(model_path)["IP"])
JuLIP.set_calculator!(cur_atoms, IP)
model = AdiabaticModels.JuLIPModel(cur_atoms)

return model
end


################################################
################### USE MODEL ##################
################################################
pes_model_path = "../../../models/ace/h2cu_ace.json"
atoms_path = "../../../dbs/example_structures/cu111_h7.0_full_925K.in"
ase_atoms = io.read(atoms_path)
ase_jl = ASE.ASEAtoms(ase_atoms)
atoms_julip = JuLIP.Atoms(ase_jl)
atoms, positions, cell = NQCDynamics.convert_from_ase_atoms(ase_atoms)

println("Load ML models and initialize the simulation...")
pes_model = ace_model_pes(pes_model_path, atoms_julip)
sim = Simulation{Classical}(atoms, pes_model, cell=cell)
31 changes: 31 additions & 0 deletions scripts/calculators/pes/ace_py.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using NQCDynamics
using PyCall
using NQCModels

# Importing Python modules with PyCall
io = pyimport("ase.io")
pyjulip = pyimport("pyjulip")

"""
Function for creating ASE object from ACE model
"""
function ace_model_pes(model_path, cur_atoms) # cur_atoms has to be JuLIP atoms object
calculator = pyjulip.ACE1(model_path)
cur_atoms.set_calculator(calculator)
model = AdiabaticASEModel(cur_atoms)

return model
end


################################################
################### USE MODEL ##################
################################################
pes_model_path = "../../../models/ace/h2cu_ace.json"
atoms_path = "../../../dbs/example_structures/cu111_h7.0_full_925K.in"
ase_atoms = io.read(atoms_path)
atoms, positions, cell = NQCDynamics.convert_from_ase_atoms(ase_atoms)

println("Load ML models and initialize the simulation...")
pes_model = ace_model_pes(pes_model_path, ase_atoms)
sim = Simulation{Classical}(atoms, pes_model, cell=cell)
34 changes: 34 additions & 0 deletions scripts/calculators/pes/mace.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using NQCDynamics
using PyCall
using NQCModels

# Importing Python modules with PyCall
io = pyimport("ase.io")
mace_calc = pyimport("mace.calculators")

"""
Function for creating ASE object from MACE model
"""
function mace_model_pes(model_path, cur_atoms)
calculator = mace_calc.MACECalculator(
model_path=model_path,
device="cpu",
default_dtype="float32") # device = "cpu" or "cuda"
cur_atoms.set_calculator(calculator)
model = AdiabaticASEModel(cur_atoms)

return model
end


################################################
################### USE MODEL ##################
################################################
pes_model_path = "../../../models/mace/MACE_model_swa.model"
atoms_path = "../../../dbs/example_structures/cu111_h7.0_full_925K.in"
ase_atoms = io.read(atoms_path)
atoms, positions, cell = NQCDynamics.convert_from_ase_atoms(ase_atoms)

println("Load ML models and initialize the simulation...")
pes_model = mace_model_pes(pes_model_path, ase_atoms)
sim = Simulation{Classical}(atoms, pes_model, cell=cell)
Loading

0 comments on commit cf9e74c

Please sign in to comment.