Skip to content

Conversation

@shehan807
Copy link
Contributor

@shehan807 shehan807 commented Feb 6, 2025

Summary

  • implements DynamicOpenMMFlowMaker in src/atomate2/openmm/flows/dynamic.py
  • implements default_should_continue functions in src/atomate2/openmm/flows/dynamic.py
  • implements test_dynamic_flow_maker in tests/openmm_md/flows/test_dynamic.py

This PR resolves the final enhancement proposed in #1102. Currently, subclasses to BaseOpenMMMaker include EnergyMinimizationMaker, NPTMaker, NVTMaker, and TempChangeMaker. This PR adds the DynamicOpenMMFlowMaker class, suitable for high-throughput classical MD workflows. Equilibration timescales are highly system- and model-dependent for condensed-phase systems even with notable structural or compositional similarities (see ionic liquids, polymers, etc.). Now there is support for on-the-fly OpenMM trajectory propagation. Below is a simple water equilibration:

from atomate2.openff.core import generate_interchange
from atomate2.openff.utils import create_mol_spec
from atomate2.openmm.flows.core import DynamicOpenMMFlowMaker, default_should_continue
from atomate2.openmm.jobs.core import NPTMaker
from jobflow import Flow, run_locally
from functools import partial

mol_specs_dicts = [
    {"smiles": "O", "count": 500, "name": "HOH"}
]

water_interchange_job = generate_interchange(mol_specs_dicts, 1.1)
interchange = water_interchange_job.output.interchange
prev_dir = water_interchange_job.output.dir_name

should_continue = partial(
            default_should_continue,
            physical_property="potential_energy",
            threshold=1e-3,
            )
should_continue.__name__ = "should_continue"

dynamic_flow_maker = DynamicOpenMMFlowMaker(
    name="test dynamic equilibration",
    tags=["test"],
    maker=
        NPTMaker(n_steps=300, pressure=1.0, state_interval=10, traj_interval=10),
    max_stages=15,
    should_continue=should_continue,
)

production_flow = dynamic_flow_maker.make(interchange)

response_dict = run_locally(Flow([water_interchange_job, production_flow]))

Based on default_should_continue, equilibration is deemed complete once the potential energy vs time's rate of change plateaus. A new NPTMaker is instantiated dynamically, creating equilibration stages. The water test case below, the simulation converges once the decay rate falls below the threshold=1e-3:

DynamicOpenMMFlowMaker Job Logs Output
2025-02-05 20:30:24,757 INFO Started executing jobs locally
2025-02-05 20:30:24,779 INFO Starting job - generate_interchange (29bdf1d3-1813-42e9-8afb-6548a177d0f3)
2025-02-05 20:30:28,736 INFO Finished job - generate_interchange (29bdf1d3-1813-42e9-8afb-6548a177d0f3)
2025-02-05 20:30:28,736 INFO Starting job - npt simulation (7da170ab-73f9-48f0-a3ea-b17ea50ac311)
2025-02-05 20:30:48,497 INFO Finished job - npt simulation (7da170ab-73f9-48f0-a3ea-b17ea50ac311)
2025-02-05 20:30:48,497 INFO Starting job - default_should_continue (3fee7518-da5a-4ce4-918e-9770479ffa0b)
2025-02-05 20:30:48,528 INFO Finished job - default_should_continue [Stage 0, decay_rate=2.058e-02-> should_continue=True] (3fee7518-da5a-4ce4-918e-9770479ffa0b)
2025-02-05 20:30:48,529 INFO Starting job - test dynamic equilibration (de41f8be-65e6-4acb-a001-b7afe5d9685f)
2025-02-05 20:30:48,589 INFO Finished job - test dynamic equilibration (de41f8be-65e6-4acb-a001-b7afe5d9685f)
2025-02-05 20:30:48,631 INFO Starting job - npt simulation (124357d5-088b-41e5-8d9a-80196220324e)
2025-02-05 20:31:07,324 INFO Finished job - npt simulation (124357d5-088b-41e5-8d9a-80196220324e)
2025-02-05 20:31:07,324 INFO Starting job - default_should_continue (e246a6d1-6771-49ee-9c24-522e64f05be3)
2025-02-05 20:31:07,377 INFO Finished job - default_should_continue [Stage 1, decay_rate=1.684e-02-> should_continue=True] (e246a6d1-6771-49ee-9c24-522e64f05be3)
2025-02-05 20:31:07,377 INFO Starting job - test dynamic equilibration (a62f7b01-2c2d-49cd-80a7-e8873bab3baa)
2025-02-05 20:31:07,502 INFO Finished job - test dynamic equilibration (a62f7b01-2c2d-49cd-80a7-e8873bab3baa)
2025-02-05 20:31:07,586 INFO Starting job - npt simulation (67b1dea2-cbc8-4a9e-a439-bb7ccab1874c)
2025-02-05 20:31:22,555 INFO Finished job - npt simulation (67b1dea2-cbc8-4a9e-a439-bb7ccab1874c)
2025-02-05 20:31:22,556 INFO Starting job - default_should_continue (f0487f1d-cb81-4767-9bcc-4b1d2f973991)
2025-02-05 20:31:22,634 INFO Finished job - default_should_continue [Stage 2, decay_rate=8.804e-03-> should_continue=True] (f0487f1d-cb81-4767-9bcc-4b1d2f973991)
2025-02-05 20:31:22,634 INFO Starting job - test dynamic equilibration (39354898-4a3b-4531-afa9-79feb72137d5)
2025-02-05 20:31:22,826 INFO Finished job - test dynamic equilibration (39354898-4a3b-4531-afa9-79feb72137d5)
2025-02-05 20:31:22,952 INFO Starting job - npt simulation (2560957b-8bf9-49b9-976a-94c0b7bbaea8)
2025-02-05 20:31:33,915 INFO Finished job - npt simulation (2560957b-8bf9-49b9-976a-94c0b7bbaea8)
2025-02-05 20:31:33,915 INFO Starting job - default_should_continue (ea5e34e6-6860-474e-b028-c8db3035a358)
2025-02-05 20:31:34,017 INFO Finished job - default_should_continue [Stage 3, decay_rate=9.786e-03-> should_continue=True] (ea5e34e6-6860-474e-b028-c8db3035a358)
2025-02-05 20:31:34,017 INFO Starting job - test dynamic equilibration (f91e740b-9d4d-472d-a24d-6bcaa0ee3539)
2025-02-05 20:31:34,274 INFO Finished job - test dynamic equilibration (f91e740b-9d4d-472d-a24d-6bcaa0ee3539)
2025-02-05 20:31:34,441 INFO Starting job - npt simulation (1c3665c5-a24f-445c-85b3-d30fdb32cccb)
2025-02-05 20:31:52,361 INFO Finished job - npt simulation (1c3665c5-a24f-445c-85b3-d30fdb32cccb)
2025-02-05 20:31:52,363 INFO Starting job - default_should_continue (dbbccd92-e776-42fc-a5f0-1ba83c010e0f)
2025-02-05 20:31:52,494 INFO Finished job - default_should_continue [Stage 4, decay_rate=2.352e-03-> should_continue=True] (dbbccd92-e776-42fc-a5f0-1ba83c010e0f)
2025-02-05 20:31:52,495 INFO Starting job - test dynamic equilibration (6e23bc46-3c4e-4a48-8fea-e7affd505ad9)
2025-02-05 20:31:52,832 INFO Finished job - test dynamic equilibration (6e23bc46-3c4e-4a48-8fea-e7affd505ad9)
2025-02-05 20:31:53,049 INFO Starting job - npt simulation (951b6764-52a6-4478-80b1-15ca6d551d05)
2025-02-05 20:32:10,970 INFO Finished job - npt simulation (951b6764-52a6-4478-80b1-15ca6d551d05)
2025-02-05 20:32:10,970 INFO Starting job - default_should_continue (2f541305-f229-4584-8892-39a6236c25e6)
2025-02-05 20:32:11,121 INFO Finished job - default_should_continue [Stage 5, decay_rate=1.367e-03-> should_continue=True] (2f541305-f229-4584-8892-39a6236c25e6)
2025-02-05 20:32:11,122 INFO Starting job - test dynamic equilibration (e7c6367d-4cb7-4f85-aeee-5d78df896f16)
2025-02-05 20:32:11,513 INFO Finished job - test dynamic equilibration (e7c6367d-4cb7-4f85-aeee-5d78df896f16)
2025-02-05 20:32:11,763 INFO Starting job - npt simulation (f7a41976-0d0f-4c00-90e3-6c7dbd41d34c)
2025-02-05 20:32:22,038 INFO Finished job - npt simulation (f7a41976-0d0f-4c00-90e3-6c7dbd41d34c)
2025-02-05 20:32:22,038 INFO Starting job - default_should_continue (8605a42d-5be2-46d0-a3b8-e1fa44380494)
2025-02-05 20:32:22,216 INFO Finished job - default_should_continue [Stage 6, decay_rate=1.133e-03-> should_continue=True] (8605a42d-5be2-46d0-a3b8-e1fa44380494)
2025-02-05 20:32:22,216 INFO Starting job - test dynamic equilibration (2cd53847-5036-418b-9904-72f280cabcc5)
2025-02-05 20:32:22,681 INFO Finished job - test dynamic equilibration (2cd53847-5036-418b-9904-72f280cabcc5)
2025-02-05 20:32:22,977 INFO Starting job - npt simulation (38a32877-67b3-48ee-8ecf-363e01271d1d)
2025-02-05 20:32:32,793 INFO Finished job - npt simulation (38a32877-67b3-48ee-8ecf-363e01271d1d)
2025-02-05 20:32:32,794 INFO Starting job - default_should_continue (cd6dac8c-c807-4f26-9d88-c7bf342c8b83)
2025-02-05 20:32:32,994 INFO Finished job - default_should_continue [Stage 7, decay_rate=1.753e-03-> should_continue=True] (cd6dac8c-c807-4f26-9d88-c7bf342c8b83)
2025-02-05 20:32:32,995 INFO Starting job - test dynamic equilibration (d2ce998d-1021-416d-b4fc-e5dfcca87450)
2025-02-05 20:32:33,522 INFO Finished job - test dynamic equilibration (d2ce998d-1021-416d-b4fc-e5dfcca87450)
2025-02-05 20:32:33,856 INFO Starting job - npt simulation (9285d6c6-1bb5-4abc-9182-a90ca7e6d77b)
2025-02-05 20:32:43,541 INFO Finished job - npt simulation (9285d6c6-1bb5-4abc-9182-a90ca7e6d77b)
2025-02-05 20:32:43,541 INFO Starting job - default_should_continue (0a77a53d-fb25-448f-ba9e-e837f05a8fb8)
2025-02-05 20:32:43,762 INFO Finished job - default_should_continue [Stage 8, decay_rate=1.658e-03-> should_continue=True] (0a77a53d-fb25-448f-ba9e-e837f05a8fb8)
2025-02-05 20:32:43,762 INFO Starting job - test dynamic equilibration (d52d9fae-c07b-4c9c-89f3-1f70c8c2416c)
2025-02-05 20:32:44,356 INFO Finished job - test dynamic equilibration (d52d9fae-c07b-4c9c-89f3-1f70c8c2416c)
2025-02-05 20:32:44,733 INFO Starting job - npt simulation (929bcdb4-8a42-44aa-94ff-d5db63d9212a)
2025-02-05 20:32:55,190 INFO Finished job - npt simulation (929bcdb4-8a42-44aa-94ff-d5db63d9212a)
2025-02-05 20:32:55,191 INFO Starting job - default_should_continue (87974ece-c302-4fb0-a1ce-23756d576985)
2025-02-05 20:32:55,453 INFO Finished job - default_should_continue [Stage 9, decay_rate=3.946e-04-> should_continue=False] (87974ece-c302-4fb0-a1ce-23756d576985)
2025-02-05 20:32:55,453 INFO Starting job - test dynamic equilibration (601b2f6c-bd98-4e49-bf49-5a0f9f74889d)
2025-02-05 20:32:55,694 INFO Finished job - test dynamic equilibration (601b2f6c-bd98-4e49-bf49-5a0f9f74889d)
2025-02-05 20:32:55,695 INFO Starting job - collect_outputs (601b2f6c-bd98-4e49-bf49-5a0f9f74889d, 2)
2025-02-05 20:32:55,840 INFO Finished job - collect_outputs (601b2f6c-bd98-4e49-bf49-5a0f9f74889d, 2)
2025-02-05 20:32:55,840 INFO Finished executing jobs locally

TODO (if any)

  • I've run pre-commit run --all with only the following issue unresolved
    EDIT: Resolved with Protocol solution (See ShouldContinueProtocol)

Future Work

The scope of this PR is a straightforward, extensible DynamicOpenMMFlowMaker. For more complex workflows, future enhancements would include:

  • Dynamically modifying memory footprint via traj_interval at collect_job
  • Splitting flow termination logic into (a) converged vs. (b) "paused" to enable checkpointing for more seamless handoff ti subsequent (non-dynamic) flows
  • Creating Phase classes to easily stitch together intentionally separate, dynamic flows (i.e., EquilibrationPhase, ProductionPhase, etc.)
  • Extended default_should_continue with broader physical parameter support (e.g., integrate with pymbar, RED, etc.)

Checklist

  • Code is in the standard Python style.
    The easiest way to handle this is to run the following in the correct sequence on
    your local machine. Start with running ruff and ruff format on your new code. This will
    automatically reformat your code to PEP8 conventions and fix many linting issues.
  • Doc strings have been added in the Numpy docstring format.
    Run ruff on your code.
  • Type annotations are highly encouraged. Run mypy to
    type check your code.
  • Tests have been added for any new functionality or bug fixes.
  • All linting and tests pass.

Note that the CI system will run all the above checks. But it will be much more
efficient if you already fix most errors prior to submitting the PR. It is highly
recommended that you use the pre-commit hook provided in the repository. Simply run
pre-commit install and a check will be run prior to allowing commits.

Copy link
Contributor

@orionarcher orionarcher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good so far, just a couple comments

Comment on lines 319 to 320
@dataclass
class DynamicOpenMMFlowMaker(Maker):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about putting this in a folder called dynamic instead of core?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you mean a dynamic.py file in the same flows folder, I agree.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, thats what I meant!

Comment on lines 90 to 91
@openmm_job
def default_should_continue(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test this by itself too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 361 to 370
(
list[OpenMMTaskDocument],
int,
int,
str,
float | None,
float,
float,
)
should_continue: Callable[
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's happening here? very weird lint maybe?

Copy link
Contributor Author

@shehan807 shehan807 Mar 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was unused/redundant code that should've been deleted, thanks! Also, I've fixed the mypy errors using a Protocol, so now all mypy tests pass.

task_docs: list[OpenMMTaskDocument],
stage_index: int,
max_stages: int,
physical_property: str = "potential_energy",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also make this take a callable that acts on a list of task docs, that'd be a bit more flexible that locking in a couple different physical parameters.

Copy link
Contributor Author

@shehan807 shehan807 Mar 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, ideally we want should_continue to solely depend on task_docs. I'd like to think about this some more, since there may be a physical_property not yet included in the Calculation (RMSD, RDFs, etc.), but can still be derived from trajectory information. So I'd propose keeping this as an MVP and generalizing in a future PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me!

@shehan807
Copy link
Contributor Author

thanks @orionarcher, I've addressed all comments + any pre-commit/pytests are working on my end

@orionarcher
Copy link
Contributor

@janosh or @utf could we run CI here too?

Copy link
Contributor

@orionarcher orionarcher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for addressing my comments, I think this looks good.

@shehan807
Copy link
Contributor Author

Thanks @orionarcher and @janosh! At least from my side of things, I don't have any more changes to make, so please let me know if there's anything else you need from my end to merge this and #1111.

@janosh janosh merged commit 9487bf6 into materialsproject:main Mar 28, 2025
18 checks passed
esoteric-ephemera pushed a commit to esoteric-ephemera/atomate2 that referenced this pull request Apr 3, 2025
…sproject#1115)

* created DynamicOpenMMFlowMaker; moved BaseOpenMMMaker import outside of TYPE_CHECKING to use as callable in default_factory

* use of lambda function is more appropriate for default_factory to avoid shared mutable defaults

* added dynamic flow logic and apply_flow_control instace classes; added placeholder should_continue function

* restructured dynamic_flow and removed apply_flow_control

* removed dynamic_collect_outputs

* added and passed DynamicOpenMMFlowMaker tests; fixed dynamic flow logic

* undo incorrect change

* created dynamic.py

* created test_should_continue

* mypy_extensions passes mypy, but adds additional dependency

* mypy_extensions passes mypy, but adds additional dependency

* replaced mypy_extensions with protocol, mypy tests pass.

---------

Co-authored-by: Shehan M Parmar <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants