Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
3df7c35
Updated the neighborlists.ipynb for an example calculating dispersion…
MarshallYan Feb 24, 2026
aed8504
Calculate D3 with modelforge provided neighbor lists in the notebook.
MarshallYan Feb 25, 2026
94d6ac3
Add a batch D3 calculation example in the notebook
MarshallYan Feb 26, 2026
7441ce9
Add parameter_set and engine to postprocessing config parameters
MarshallYan Mar 3, 2026
096d5b5
Parse corresponding postprocessing parameters to DispersionPotential
MarshallYan Mar 3, 2026
60a08b5
test nvalchemiops d3 module (output should be close to that of tad-df…
MarshallYan Mar 17, 2026
aaa4521
add d3_engine as an option in the DispersionPotential class; add a CO…
MarshallYan Mar 17, 2026
900bb4c
save the current version of dftd3_parameters downloaded from "https:/…
MarshallYan Mar 17, 2026
3bfd3dc
uncomment vdw pair calculations
MarshallYan Mar 17, 2026
c34c5ee
implement dipersion calculation with nvalchemiops
MarshallYan Mar 19, 2026
2936742
Merge branch 'main' into feature-nvalchemi-d3-support
MarshallYan Mar 19, 2026
4df63de
add nvalchemiops to dependency
MarshallYan Mar 19, 2026
2fc0bd1
function calling typo fix
MarshallYan Mar 19, 2026
ec0c09c
refactor importing to match the updated nvalchemiops 0.3.0
MarshallYan Mar 20, 2026
e32d313
typo jax->torch
MarshallYan Mar 20, 2026
763f543
dispersion potential data class: engine -> d3_engine
MarshallYan Mar 20, 2026
86f7e34
relative path correspond to the repository
MarshallYan Mar 20, 2026
12fbdb8
engine->d3_engine, reformat with black
MarshallYan Mar 20, 2026
5334dff
reformat with black
MarshallYan Mar 20, 2026
381e40f
reformat with black
MarshallYan Mar 20, 2026
793190e
xfail python version 3.10
MarshallYan Mar 23, 2026
795764a
backslashes included in the doc string, should use raw string
MarshallYan Mar 23, 2026
0024130
black reformat xfail lines
MarshallYan Mar 23, 2026
22ac7a0
specify nvalchemiops 0.3.0
MarshallYan Mar 23, 2026
88e287b
only install nvalchemiops in CI when python>3.10
MarshallYan Mar 23, 2026
a221edf
only install nvalchemiops in CI when python>3.10
MarshallYan Mar 23, 2026
a757e0a
only install nvalchemiops in CI when python>3.10
MarshallYan Mar 23, 2026
1b384c0
remove nvalchemiops from test_env.yaml; control the logic in workflow…
MarshallYan Mar 23, 2026
bd4057f
move importing nvalchemiops inside specific functions
MarshallYan Mar 23, 2026
691e5ab
rename as default d3 param
MarshallYan Mar 26, 2026
9989cb8
rename linked file name in the notebook
MarshallYan Mar 26, 2026
eb26061
when not input, set d3 param to default independent of its relative path
MarshallYan Mar 26, 2026
6d5cb81
black reformat
MarshallYan Mar 26, 2026
9168313
d3 param log file
MarshallYan Mar 26, 2026
9d05d59
doc string update
MarshallYan Mar 29, 2026
93ce080
d3_parameter_path option in toml configs
MarshallYan Mar 29, 2026
95678b1
update AIMNet2 example using updated postprocessing dispersion config
MarshallYan Mar 29, 2026
25e3386
add d3_parameters_path to toml configs
MarshallYan Mar 29, 2026
35f8c1a
d3_parameters_path should be a string
MarshallYan Mar 29, 2026
71720ba
match parameter order
MarshallYan Mar 29, 2026
affb757
raw string
MarshallYan Mar 29, 2026
7f194c8
the key to the vdw neighbor list is "vdw_pair_indices"
MarshallYan Mar 29, 2026
547d6f2
explicitly state that the cutoff only works with nvalchemiops in docs
MarshallYan Mar 29, 2026
ab1b779
Parse the vdw pair list when using nvalchemiops (and not when using t…
MarshallYan Mar 29, 2026
ed0fa9a
always parse neighbor list when doing vdw postprocessing
MarshallYan Mar 29, 2026
2846200
spell typo
MarshallYan Mar 29, 2026
f5a2612
update docs
MarshallYan Mar 29, 2026
a346619
black reformat
MarshallYan Mar 29, 2026
7e53f7a
update test key to vdw neighbor list
MarshallYan Mar 29, 2026
f577eee
resolve docing issues
MarshallYan Mar 31, 2026
2c5d228
put a fixme for a logic to determine whether neighbor list should be …
MarshallYan Mar 31, 2026
b83f977
only work with the d3_parameter_path when d3 engine is nvalchemiops
MarshallYan Mar 31, 2026
ef96dfb
reformat
MarshallYan Mar 31, 2026
5c4bda4
doc string for calculate_neighbor_ptr_from_neighbor_list
MarshallYan Mar 31, 2026
dfa03da
double check JIT
MarshallYan Mar 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/CI.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ jobs:

micromamba list

# Skip nvalchemiops if Python version is 3.10
- name: Install nvalchemi-toolkit-ops
if: matrix.python-version != '3.10'
run: pip install nvalchemi-toolkit-ops==0.3.0

# this will figure out what datasets we will use in our tests
# and save them to a file so we can hash this file to see if the cache needs updating
# this will save "downloaded_datasets.txt" in the modelforge testing cache folder
Expand Down
1 change: 1 addition & 0 deletions devtools/conda-envs/test_env.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,5 @@ dependencies:
- pytorch2jax
#- git+https://github.com/ArnNag/sake.git@nanometer
- pytest-xdist
#- nvalchemi-toolkit-ops==0.3.0

6 changes: 5 additions & 1 deletion docs/potentials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,11 @@ Rather than having all 3 of these energy contributions returned by the core netw


[potential.postprocessing_parameter.per_system_vdw_energy]
maximum_interaction_radius = "10.0 angstrom"
maximum_interaction_radius = "10.0 angstrom" # this will only take effect when d3_engine is set to "nvalchemiops"
# otherwise the "tad-dftd3" will handle neighbor list internally
parameter_set: str = "wB97M-D3(BJ)"
d3_engine = "nvalchemiops"
d3_parameters_path = "None"

# this will be added to the per_system_energy that results from the `per_atom_energy` reduction operation
[potential.postprocessing_parameter.sum_per_system_energy]
Expand Down
4 changes: 4 additions & 0 deletions modelforge/data/dftd3_parameters/dftd3_parameters.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dftd3_parameters_0:
file_name: "dftd3_parameters_0.pt"
generation_date: "2026-02-23"
original_url: "https://www.chemie.uni-bonn.de/grimme/de/software/dft-d3/dftd3.tgz"
Binary file not shown.
3 changes: 3 additions & 0 deletions modelforge/potential/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ class DispersionPotential(ParametersBase):
# note maximum interaction radius should be passed as a string with units or unit.Quantity;
# it will be converted to float in appropriate unit system
maximum_interaction_radius: float
parameter_set: str = "wB97M-D3(BJ)"
d3_engine: str = "nvalchemiops"
d3_parameters_path: str = "None"

converted_units = field_validator(
"maximum_interaction_radius",
Expand Down
49 changes: 26 additions & 23 deletions modelforge/potential/potential.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class PostProcessing(torch.nn.Module):

def __init__(
self,
postprocessing_parameter: Dict[str, Dict[str, bool]],
postprocessing_parameter: Dict[str, Dict[str, Any]],
dataset_statistic: Dict[str, Dict[str, float]],
):
"""
Expand Down Expand Up @@ -215,6 +215,15 @@ def __init__(
],
length_conversion_factor=length_conversion_factor,
energy_conversion_factor=energy_conversion_factor,
parameter_set=postprocessing_parameter["per_system_vdw_energy"][
"parameter_set"
],
d3_engine=postprocessing_parameter["per_system_vdw_energy"][
"d3_engine"
],
d3_parameters_path=postprocessing_parameter[
"per_system_vdw_energy"
]["d3_parameters_path"],
)
)
self._registered_properties.append("per_system_vdw_energy")
Expand Down Expand Up @@ -315,9 +324,6 @@ def __init__(
Forward pass for the potential model, computing energy and forces that accepts individual tensors rather than NNPInput class, necessary for JIT compiled model.
forward(input_data: NNPInput) -> Dict[str, torch.Tensor]
Forward pass for the potential model, computing energy and forces.



"""

super().__init__()
Expand All @@ -328,13 +334,14 @@ def __init__(
)
# note cannot jit compile the dispersion interactions as tad-dftd3 is not compatible with torchscript
if "per_system_vdw_energy" in postprocessing._registered_properties:
# double check if nvalchemiops works with JIT
log.warning(
"JIT compiling the postprocessing module with vdw interactions will not work."
"JIT compiling the postprocessing module with vdw interactions will not work if using tad-dftd3."
)
log.warning("tad-dftd3 packaged is not compatible with torchscript.")
log.warning(
"The tad-DFTD3 packaged used is not compatible with torchscript."
"Use nvalchemiops as the DFTD3 engine or disable JIT compilation by setting jit=False."
Comment thread
MarshallYan marked this conversation as resolved.
)
log.warning("Disabling JIT compilation by setting jit=False.")

self.postprocessing = (
torch.jit.script(postprocessing) if jit else postprocessing
Expand Down Expand Up @@ -431,13 +438,12 @@ def _add_pairlist(
core_output["local_d_ij"] = pairlist_output.local_cutoff.d_ij
core_output["local_r_ij"] = pairlist_output.local_cutoff.r_ij

# this is commented out for now, as the vdw energy is calculated via
# DFTD3 which handles pair calculations internally
# If we have other vdw implementations, we can uncomment this
# if "per_system_vdw_energy" in self.postprocessing._registered_properties:
# core_output["vdw_pair_indices"] = pairlist_output.vdw_cutoff.pair_indices
# core_output["vdw_d_ij"] = pairlist_output.vdw_cutoff.d_ij
# core_output["vdw_r_ij"] = pairlist_output.vdw_cutoff.r_ij
if (
"per_system_vdw_energy" in self.postprocessing._registered_properties
): # FIXME: no need when running tad-dftd3
core_output["vdw_pair_indices"] = pairlist_output.vdw_cutoff.pair_indices
core_output["vdw_d_ij"] = pairlist_output.vdw_cutoff.d_ij
core_output["vdw_r_ij"] = pairlist_output.vdw_cutoff.r_ij

if (
"per_system_electrostatic_energy"
Expand Down Expand Up @@ -725,9 +731,9 @@ def setup_potential(
# - local_cutoff is the maximum interaction radius for the NNP core network (i.e., the local interaction radius)
# this is always required.
# - vdw_cutoff is the cutoff for the van der Waals interactions, which is only required in the vdw interactions are
# included as a post processing step.
# included as a post-processing step.
# - electrostatic_cutoff is the cutoff for the electrostatic interactions, which is only required in the electrostatic
# interactions are included as a post processing step.
# interactions are included as a post-processing step.
#
# note zbl potential does not require a unique cutoff definition; it will use local cutoff and then calculates
# the zbl potential based on the radii of the two atoms in the pair.
Expand All @@ -744,7 +750,6 @@ def setup_potential(
)
use_electrostatic_cutoff = True

# note vdw isn't implemented yet, but we can add it later
if "per_system_vdw_energy" in postprocessing._registered_properties:
vdw_cutoff = (
potential_parameter.postprocessing_parameter.per_system_vdw_energy.maximum_interaction_radius
Expand All @@ -756,13 +761,12 @@ def setup_potential(
if use_training_mode_neighborlist:
from modelforge.potential.neighbors import NeighborListForTraining

# note vdw_cutoff is not being used as this is handled internally by the DFTD3 implementation
neighborlist = NeighborListForTraining(
local_cutoff=local_cutoff,
# vdw_cutoff=vdw_cutoff,
vdw_cutoff=vdw_cutoff,
electrostatic_cutoff=electrostatic_cutoff,
local_only_unique_pairs=only_unique_pairs,
# use_vdw_cutoff=use_vdw_cutoff,
use_vdw_cutoff=use_vdw_cutoff,
use_electrostatic_cutoff=use_electrostatic_cutoff,
)
else:
Expand All @@ -772,14 +776,13 @@ def setup_potential(

from modelforge.potential.neighbors import NeighborlistForInference

# note vdw_cutoff is not being used as this is handled internally by the DFTD3 implementation
neighborlist = NeighborlistForInference(
local_cutoff=local_cutoff,
# vdw_cutoff=vdw_cutoff,
vdw_cutoff=vdw_cutoff,
electrostatic_cutoff=electrostatic_cutoff,
displacement_function=displacement_function,
local_only_unique_pairs=only_unique_pairs,
# use_vdw_cutoff=use_vdw_cutoff,
use_vdw_cutoff=use_vdw_cutoff,
use_electrostatic_cutoff=use_electrostatic_cutoff,
)
# we can set the strategy here before passing this to the Potential
Expand Down
Loading
Loading