From 9be2fce1a3630b52542c0b72023a6e4a648dc3a9 Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Wed, 6 Mar 2024 23:37:21 -0700 Subject: [PATCH 01/13] add dict entry for periodic impropers --- environment-dev.yml | 4 ++-- gmso/external/convert_hoomd.py | 44 ++++++++++++++++++++++++++++------ gmso/tests/test_hoomd.py | 5 ++-- 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/environment-dev.yml b/environment-dev.yml index 425d7d8cb..9afed2a7d 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -2,7 +2,7 @@ name: gmso-dev channels: - conda-forge dependencies: - - python>=3.8 + - python<3.12 - boltons - numpy - sympy @@ -12,7 +12,7 @@ dependencies: - pydantic>=2 - networkx - pytest - - mbuild>=0.11.0 + - mbuild>=0.17.0 - openbabel>=3.0.0 - foyer>=0.11.3 - forcefield-utilities>=0.2.1 diff --git a/gmso/external/convert_hoomd.py b/gmso/external/convert_hoomd.py index d404012d5..2f1ad9c98 100644 --- a/gmso/external/convert_hoomd.py +++ b/gmso/external/convert_hoomd.py @@ -43,6 +43,8 @@ "mass": u.g / u.mol, # aka amu } +hoomd_version = hoomd.version.version.split(".") + def to_gsd_snapshot( top, @@ -678,6 +680,7 @@ def _validate_compatibility(top): harmonic_bond_potential = templates["HarmonicBondPotential"] harmonic_angle_potential = templates["HarmonicAnglePotential"] periodic_torsion_potential = templates["PeriodicTorsionPotential"] + harmonic_torsion_potential = templates["HarmonicTorsionPotential"] opls_torsion_potential = templates["OPLSTorsionPotential"] rb_torsion_potential = templates["RyckaertBellemansTorsionPotential"] accepted_potentials = ( @@ -685,6 +688,7 @@ def _validate_compatibility(top): harmonic_bond_potential, harmonic_angle_potential, periodic_torsion_potential, + harmonic_torsion_potential, opls_torsion_potential, rb_torsion_potential, ) @@ -1120,7 +1124,6 @@ def _parse_dihedral_forces( }, } - hoomd_version = hoomd.version.version.split(".") if int(hoomd_version[0]) >= 4 or ( int(hoomd_version[0]) == 3 and int(hoomd_version[1]) >= 8 ): @@ -1307,12 +1310,24 @@ def _parse_improper_forces( base_units, ) - itype_group_map = { - "HarmonicImproperPotenial": { - "container": hoomd.md.improper.Harmonic, - "parser": _parse_harmonic_improper, - }, - } + if int(hoomd_version[0]) >= 4 and int(hoomd_version[1]) >= 5: + itype_group_map = { + "HarmonicImproperPotenial": { + "container": hoomd.md.improper.Harmonic, + "parser": _parse_harmonic_improper, + }, + "PeriodicImproperPotenial": { + "container": hoomd.md.improper.Periodic, + "parser": _parse_periodic_improper, + }, + } + else: + itype_group_map = { + "HarmonicImproperPotenial": { + "container": hoomd.md.improper.Harmonic, + "parser": _parse_harmonic_improper, + }, + } improper_forces = list() for group in groups: @@ -1338,6 +1353,21 @@ def _parse_harmonic_improper( return container +def _parse_periodic_improper( + container, + itypes, +): + for itype in itypes: + member_types = sort_by_classes(itype) + container.params["-".join(member_types)] = { + "k": itype.parameters["k"], + "chi0": itype.parameters["phi_eq"], + "n": itype.parameters["n"], + "d": itype.parameters["d"], + } + return container + + def _validate_base_units(base_units, top, auto_scale, potential_types=None): """Validate the provided base units, infer units (based on top's positions and masses) if none is provided.""" if base_units and auto_scale: diff --git a/gmso/tests/test_hoomd.py b/gmso/tests/test_hoomd.py index 274965b97..6f3c64701 100644 --- a/gmso/tests/test_hoomd.py +++ b/gmso/tests/test_hoomd.py @@ -410,8 +410,9 @@ def test_gaff_sim(self, gaff_forcefield): "energy": u.kJ / u.mol, } ethanol = mb.load("CCO", smiles=True) - ethanol.box = mb.Box([5, 5, 5]) - top = ethanol.to_gmso() + benzene = mb.load("c1ccccc1", smiles=True) + benzene.box = mb.Box([5, 5, 5]) + top = benzene.to_gmso() parameterized_top = apply( top, gaff_forcefield, identify_connections=True ) From cd2ce5163b4ea24b2ce683f0778a2662c69e959d Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Fri, 8 Mar 2024 09:44:11 -0700 Subject: [PATCH 02/13] add sign factor (d) to Periodic Improper --- gmso/lib/jsons/PeriodicImproperPotential.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gmso/lib/jsons/PeriodicImproperPotential.json b/gmso/lib/jsons/PeriodicImproperPotential.json index f945c8fec..01562c4de 100644 --- a/gmso/lib/jsons/PeriodicImproperPotential.json +++ b/gmso/lib/jsons/PeriodicImproperPotential.json @@ -1,10 +1,11 @@ { "name": "PeriodicImproperPotential", - "expression": "k * (1 + cos(n * phi - phi_eq))", + "expression": "k * (1 + d * cos(n * phi - phi_eq))", "independent_variables": "phi", "expected_parameters_dimensions": { "k": "energy", "n": "dimensionless", - "phi_eq": "angle" + "phi_eq": "angle", + "d": "dimensionless" } } From e08f9d5203780922a2f835cdc387542a5bd8de58 Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Fri, 8 Mar 2024 12:12:40 -0700 Subject: [PATCH 03/13] Change key name to match GAFF, hard code d = 1 --- gmso/external/convert_hoomd.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gmso/external/convert_hoomd.py b/gmso/external/convert_hoomd.py index 2f1ad9c98..b14c8f7df 100644 --- a/gmso/external/convert_hoomd.py +++ b/gmso/external/convert_hoomd.py @@ -1312,18 +1312,18 @@ def _parse_improper_forces( if int(hoomd_version[0]) >= 4 and int(hoomd_version[1]) >= 5: itype_group_map = { - "HarmonicImproperPotenial": { + "HarmonicImproperPotential": { "container": hoomd.md.improper.Harmonic, "parser": _parse_harmonic_improper, }, - "PeriodicImproperPotenial": { + "PeriodicTorsionPotential": { "container": hoomd.md.improper.Periodic, "parser": _parse_periodic_improper, }, } else: itype_group_map = { - "HarmonicImproperPotenial": { + "HarmonicImproperPotential": { "container": hoomd.md.improper.Harmonic, "parser": _parse_harmonic_improper, }, @@ -1363,7 +1363,7 @@ def _parse_periodic_improper( "k": itype.parameters["k"], "chi0": itype.parameters["phi_eq"], "n": itype.parameters["n"], - "d": itype.parameters["d"], + "d": 1, } return container From 0cd676ddf2e4e0ec7792e76a9f9d0940e4b19523 Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Fri, 8 Mar 2024 12:20:25 -0700 Subject: [PATCH 04/13] remove d param from template --- gmso/lib/jsons/PeriodicImproperPotential.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gmso/lib/jsons/PeriodicImproperPotential.json b/gmso/lib/jsons/PeriodicImproperPotential.json index 01562c4de..87ca07b30 100644 --- a/gmso/lib/jsons/PeriodicImproperPotential.json +++ b/gmso/lib/jsons/PeriodicImproperPotential.json @@ -5,7 +5,6 @@ "expected_parameters_dimensions": { "k": "energy", "n": "dimensionless", - "phi_eq": "angle", - "d": "dimensionless" + "phi_eq": "angle" } } From 8965e68704dd49dd6e087177d35b1e3c79335337 Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Fri, 8 Mar 2024 12:21:39 -0700 Subject: [PATCH 05/13] Remove d from expression --- gmso/lib/jsons/PeriodicImproperPotential.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gmso/lib/jsons/PeriodicImproperPotential.json b/gmso/lib/jsons/PeriodicImproperPotential.json index 87ca07b30..f945c8fec 100644 --- a/gmso/lib/jsons/PeriodicImproperPotential.json +++ b/gmso/lib/jsons/PeriodicImproperPotential.json @@ -1,6 +1,6 @@ { "name": "PeriodicImproperPotential", - "expression": "k * (1 + d * cos(n * phi - phi_eq))", + "expression": "k * (1 + cos(n * phi - phi_eq))", "independent_variables": "phi", "expected_parameters_dimensions": { "k": "energy", From 75aba937820a641b56096de905ac8edeaa268e52 Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Fri, 8 Mar 2024 13:19:10 -0700 Subject: [PATCH 06/13] change d from int to float --- gmso/external/convert_hoomd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gmso/external/convert_hoomd.py b/gmso/external/convert_hoomd.py index b14c8f7df..c6bfcd96b 100644 --- a/gmso/external/convert_hoomd.py +++ b/gmso/external/convert_hoomd.py @@ -1363,7 +1363,7 @@ def _parse_periodic_improper( "k": itype.parameters["k"], "chi0": itype.parameters["phi_eq"], "n": itype.parameters["n"], - "d": 1, + "d": 1.0, } return container From d987099499027a7d77d6d96940a3b1999c9edd99 Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Wed, 3 Apr 2024 14:02:17 -0600 Subject: [PATCH 07/13] update python version, remove ethanol from unit test --- environment-dev.yml | 2 +- environment.yml | 2 +- gmso/tests/test_hoomd.py | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/environment-dev.yml b/environment-dev.yml index 9afed2a7d..dd2aba9b8 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -2,7 +2,7 @@ name: gmso-dev channels: - conda-forge dependencies: - - python<3.12 + - python=>3.8, <3.12 - boltons - numpy - sympy diff --git a/environment.yml b/environment.yml index 85a309123..559cb5df0 100644 --- a/environment.yml +++ b/environment.yml @@ -2,7 +2,7 @@ name: gmso channels: - conda-forge dependencies: - - python>=3.8 + - python>=3.8, <3.12 - boltons - numpy - sympy diff --git a/gmso/tests/test_hoomd.py b/gmso/tests/test_hoomd.py index 6f3c64701..99c173749 100644 --- a/gmso/tests/test_hoomd.py +++ b/gmso/tests/test_hoomd.py @@ -409,7 +409,6 @@ def test_gaff_sim(self, gaff_forcefield): "length": u.nm, "energy": u.kJ / u.mol, } - ethanol = mb.load("CCO", smiles=True) benzene = mb.load("c1ccccc1", smiles=True) benzene.box = mb.Box([5, 5, 5]) top = benzene.to_gmso() From 85337464b584f5802349d8b3487cff66d0eae499 Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Fri, 5 Apr 2024 14:06:42 -0600 Subject: [PATCH 08/13] if wild card in member classes, use member types instead --- gmso/external/convert_hoomd.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gmso/external/convert_hoomd.py b/gmso/external/convert_hoomd.py index c6bfcd96b..7a38f497f 100644 --- a/gmso/external/convert_hoomd.py +++ b/gmso/external/convert_hoomd.py @@ -22,7 +22,11 @@ ) from gmso.utils.geometry import coord_shift from gmso.utils.io import has_gsd, has_hoomd -from gmso.utils.sorting import sort_by_classes, sort_connection_members +from gmso.utils.sorting import ( + sort_by_classes, + sort_by_types, + sort_connection_members, +) from gmso.utils.units import convert_params_units if has_gsd: @@ -1359,6 +1363,9 @@ def _parse_periodic_improper( ): for itype in itypes: member_types = sort_by_classes(itype) + # If wild card in class, sort by types instead + if "*" in member_types: + member_types = sort_by_types(itype) container.params["-".join(member_types)] = { "k": itype.parameters["k"], "chi0": itype.parameters["phi_eq"], From 3f17683a357087c9c63d745091cb8b08db5c63c3 Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Fri, 5 Apr 2024 14:21:38 -0600 Subject: [PATCH 09/13] use wildcard check for all forcefield writers --- gmso/external/convert_hoomd.py | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/gmso/external/convert_hoomd.py b/gmso/external/convert_hoomd.py index 7a38f497f..5c64517f4 100644 --- a/gmso/external/convert_hoomd.py +++ b/gmso/external/convert_hoomd.py @@ -1001,8 +1001,11 @@ def _parse_harmonic_bond( ): for btype in btypes: # TODO: Unit conversion - member_classes = sort_by_classes(btype) - container.params["-".join(member_classes)] = { + members = sort_by_classes(btype) + # If wild card in class, sort by types instead + if "*" in members: + members = sort_by_types(btype) + container.params["-".join(members)] = { "k": btype.parameters["k"], "r0": btype.parameters["r_eq"], } @@ -1071,8 +1074,11 @@ def _parse_harmonic_angle( agtypes, ): for agtype in agtypes: - member_classes = sort_by_classes(agtype) - container.params["-".join(member_classes)] = { + members = sort_by_classes(agtype) + # If wild card in class, sort by types instead + if "*" in members: + members = sort_by_types(atype) + container.params["-".join(members)] = { "k": agtype.parameters["k"], "t0": agtype.parameters["theta_eq"], } @@ -1349,7 +1355,10 @@ def _parse_harmonic_improper( itypes, ): for itype in itypes: - member_types = sort_by_classes(itype) + members = sort_by_classes(itype) + # If wild card in class, sort by types instead + if "*" in members: + members = sort_by_types(itype) container.params["-".join(member_types)] = { "k": itype.parameters["k"], "chi0": itype.parameters["phi_eq"], # diff nomenclature? @@ -1362,11 +1371,11 @@ def _parse_periodic_improper( itypes, ): for itype in itypes: - member_types = sort_by_classes(itype) + members = sort_by_classes(itype) # If wild card in class, sort by types instead - if "*" in member_types: - member_types = sort_by_types(itype) - container.params["-".join(member_types)] = { + if "*" in members: + members = sort_by_types(itype) + container.params["-".join(members)] = { "k": itype.parameters["k"], "chi0": itype.parameters["phi_eq"], "n": itype.parameters["n"], From fea56406154ba46c3f5373e049caf47be3f91d2d Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Fri, 5 Apr 2024 14:26:51 -0600 Subject: [PATCH 10/13] fix typo in env files --- environment-dev.yml | 2 +- environment.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/environment-dev.yml b/environment-dev.yml index dd2aba9b8..1cfa001dc 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -2,7 +2,7 @@ name: gmso-dev channels: - conda-forge dependencies: - - python=>3.8, <3.12 + - python >=3.8, <3.12 - boltons - numpy - sympy diff --git a/environment.yml b/environment.yml index 559cb5df0..9612f8570 100644 --- a/environment.yml +++ b/environment.yml @@ -2,7 +2,7 @@ name: gmso channels: - conda-forge dependencies: - - python>=3.8, <3.12 + - python >=3.8, <3.12 - boltons - numpy - sympy From a42748e4a60649c3179c6db52bf9898e4ae371b9 Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Fri, 5 Apr 2024 14:49:43 -0600 Subject: [PATCH 11/13] Fix variable name. --- gmso/external/convert_hoomd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gmso/external/convert_hoomd.py b/gmso/external/convert_hoomd.py index 5c64517f4..419115485 100644 --- a/gmso/external/convert_hoomd.py +++ b/gmso/external/convert_hoomd.py @@ -1077,7 +1077,7 @@ def _parse_harmonic_angle( members = sort_by_classes(agtype) # If wild card in class, sort by types instead if "*" in members: - members = sort_by_types(atype) + members = sort_by_types(agtype) container.params["-".join(members)] = { "k": agtype.parameters["k"], "t0": agtype.parameters["theta_eq"], From 4497a3c965bec5a68ac48fb7853d53c6a85bf264 Mon Sep 17 00:00:00 2001 From: chrisjonesbsu Date: Mon, 15 Apr 2024 11:11:24 -0600 Subject: [PATCH 12/13] use .get() for d parameter --- gmso/external/convert_hoomd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gmso/external/convert_hoomd.py b/gmso/external/convert_hoomd.py index 419115485..ab7d937fe 100644 --- a/gmso/external/convert_hoomd.py +++ b/gmso/external/convert_hoomd.py @@ -1379,7 +1379,7 @@ def _parse_periodic_improper( "k": itype.parameters["k"], "chi0": itype.parameters["phi_eq"], "n": itype.parameters["n"], - "d": 1.0, + "d": itype.parameters.get("d", 1.0), } return container From 62f1e9fb0fdf5fe612ab23b8f44bffea8c79242d Mon Sep 17 00:00:00 2001 From: chrisjonesbsu Date: Thu, 16 May 2024 10:46:16 -0600 Subject: [PATCH 13/13] change box size and seed for packing in test --- gmso/tests/test_convert_mbuild.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/gmso/tests/test_convert_mbuild.py b/gmso/tests/test_convert_mbuild.py index a8bf2c159..ef3f0e918 100644 --- a/gmso/tests/test_convert_mbuild.py +++ b/gmso/tests/test_convert_mbuild.py @@ -193,9 +193,9 @@ def test_custom_groups_from_compound(self): mb_cpd3 = mb.load("O", smiles=True) mb_cpd3.name = "O" - filled_box1 = mb.fill_box([mb_cpd1, mb_cpd2], n_compounds=[2, 2], box=[1, 1, 1]) + filled_box1 = mb.fill_box([mb_cpd1, mb_cpd2], n_compounds=[2, 2], box=[5, 5, 5]) filled_box1.name = "box1" - filled_box2 = mb.fill_box(mb_cpd3, n_compounds=2, box=[1, 1, 1]) + filled_box2 = mb.fill_box(mb_cpd3, n_compounds=2, box=[5, 5, 5]) filled_box2.name = "box2" top_box = mb.Compound() @@ -222,7 +222,9 @@ def test_custom_groups_from_compound(self): def test_single_custom_group(self): mb_cpd1 = mb.Compound(name="_CH4") mb_cpd2 = mb.Compound(name="_CH3") - filled_box = mb.fill_box([mb_cpd1, mb_cpd2], n_compounds=[2, 2], box=[1, 1, 1]) + filled_box = mb.fill_box( + [mb_cpd1, mb_cpd2], n_compounds=[2, 2], box=[5, 5, 5], seed=20 + ) filled_box.name = "box1" top = from_mbuild(filled_box, custom_groups=filled_box.name) @@ -235,7 +237,9 @@ def test_single_custom_group(self): def test_bad_custom_groups_from_compound(self): mb_cpd1 = mb.Compound(name="_CH4") mb_cpd2 = mb.Compound(name="_CH3") - filled_box = mb.fill_box([mb_cpd1, mb_cpd2], n_compounds=[2, 2], box=[1, 1, 1]) + filled_box = mb.fill_box( + [mb_cpd1, mb_cpd2], n_compounds=[2, 2], box=[5, 5, 5], seed=13 + ) with pytest.warns(Warning): from_mbuild(filled_box, custom_groups=["_CH4", "_CH3", "_CH5"])