Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add packmol_args parameter to packing fucntions. Allows user to give additional commands to PACKMOL. #787

Merged
merged 26 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e072103
added packmol_args parameter to each packing function; appends to PAC…
chrisjonesBSU Aug 20, 2020
727d1bf
fixed variable error. Create separate variable to store addl packmol …
chrisjonesBSU Aug 20, 2020
a81f9f4
added doc strings, unit test for packmol_args
chrisjonesBSU Aug 24, 2020
deb4343
added defaults dict, beginning of function to parse through
chrisjonesBSU Oct 15, 2020
77b5b33
merge with upstream, fix conflicts
chrisjonesBSU May 7, 2024
b4f674e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 7, 2024
e67b3fc
fix variable name typo
chrisjonesBSU May 7, 2024
add1f85
fix unit test
chrisjonesBSU May 7, 2024
5db9a30
test all packing methods with packmol args
chrisjonesBSU May 7, 2024
04215cb
remove unused variables in tests
chrisjonesBSU May 7, 2024
6170db3
add method to check args, add unit tests
chrisjonesBSU May 8, 2024
880e626
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 8, 2024
4b27d2b
add test for warnings
chrisjonesBSU May 8, 2024
de43291
add test for warnings
chrisjonesBSU May 8, 2024
0ef57ec
remove remaining conflict message
chrisjonesBSU May 8, 2024
4c18914
fix conflicts, move check args func under if statement
chrisjonesBSU May 8, 2024
e91d14d
clean up arg dict parsing
chrisjonesBSU May 8, 2024
bca1498
remove use_short_tol from test so Windows can pass
chrisjonesBSU May 8, 2024
19d5758
Merge branch 'main' of github.com:mosdef-hub/mbuild into feat/packmol…
chrisjonesBSU May 10, 2024
5309c2b
fix error handling in tests
chrisjonesBSU May 20, 2024
a112de5
update doc strings
chrisjonesBSU May 23, 2024
6531cf4
remove vague test for warning
chrisjonesBSU May 29, 2024
61370b7
fix failing tests
chrisjonesBSU May 29, 2024
cfa78b4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 29, 2024
80e192f
Merge and fix conflicts
chrisjonesBSU Jun 3, 2024
efc1c1c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 3, 2024
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
115 changes: 103 additions & 12 deletions mbuild/packing.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,25 @@
output {1}
seed {2}
sidemax {3}
{4}
"""

PACKMOL_SOLUTE = """
structure {0}
number 1
center
fixed {1:.3f} {2:.3f} {3:.3f} 0. 0. 0.
end structure
"""

PACKMOL_BOX = """
structure {0}
number {1:d}
inside box {2:.3f} {3:.3f} {4:.3f} {5:.3f} {6:.3f} {7:.3f}
{8}
end structure
"""

PACKMOL_SPHERE = """
structure {0}
number {1:d}
Expand All @@ -56,6 +60,20 @@
constrain_rotation z 0. 0.
"""

packmol_default_args = {"tolerance": 0.2, "seed": 12345}
Fixed Show fixed Hide fixed


def combine_packmol_args(default_args, custom_args):

# List of all available packmol_inputs
packmol_inputs = []
Fixed Show fixed Hide fixed

#

# Parse through custom args first

# Combine into single dict


def fill_box(
compound,
Expand All @@ -71,6 +89,7 @@
fix_orientation=False,
temp_file=None,
update_port_locations=False,
packmol_args=None,
):
"""Fill a box with an `mbuild.compound` or `Compound` s using PACKMOL.

Expand Down Expand Up @@ -130,8 +149,19 @@
temp_file : str, default=None
File name to write PACKMOL raw output to.
update_port_locations : bool, default=False
After packing, port locations can be updated, but since compounds can be
rotated, port orientation may be incorrect.
After packing, port locations can be updated, but since compounds
can be rotated, port orientation may be incorrect.
packmol_args : dict
Dictionary where the key, value pairs are options and their
corresponding keyword arguments for PACKMOL. Some PACKMOL options
do not require a specified keyword. In this case, the value in
the dictionary should be an empty string e.g. {'movebadrandom':""}
These commands are placed at the header of the PACKMOL input file
and therefore applied to all structures. NOTE: The PACKMOL options
for seed and tolerance are specified by the function parameters
seed and overlap.
Other command options can be found in the PACKMOL userguide:
http://www.ime.unicamp.br/~martinez/packmol/userguide.shtml

Returns
-------
Expand Down Expand Up @@ -231,14 +261,20 @@
box_maxs = [a_max - (edge * 10) for a_max in box_maxs]
box_mins = [a_min + (edge * 10) for a_min in box_mins]

# generate string of addl. packmol inputs given in packmol_args
packmol_commands = ""
if packmol_args:
for arg in packmol_args:
packmol_commands += "{} {} \n".format(arg, packmol_args[arg])

# Build the input file for each compound and call packmol.
filled_xyz = _new_xyz_file()

# create a list to contain the file handles for the compound temp files
compound_xyz_list = list()
try:
input_text = PACKMOL_HEADER.format(
overlap, filled_xyz.name, seed, sidemax * 10
overlap, filled_xyz.name, seed, sidemax * 10, packmol_commands
)
for comp, m_compounds, rotate in zip(
compound, n_compounds, fix_orientation
Expand Down Expand Up @@ -291,6 +327,7 @@
fix_orientation=False,
temp_file=None,
update_port_locations=False,
packmol_args=None,
):
"""Fill a region of a box with `mbuild.Compound` (s) using PACKMOL.

Expand Down Expand Up @@ -327,8 +364,19 @@
temp_file : str, default=None
File name to write PACKMOL raw output to.
update_port_locations : bool, default=False
After packing, port locations can be updated, but since compounds can be
rotated, port orientation may be incorrect.
After packing, port locations can be updated, but since compounds
can be rotated, port orientation may be incorrect.
packmol_args : dict
Dictionary where the key, value pairs are options and their
corresponding keyword arguments for PACKMOL. Some PACKMOL options
do not require a specified keyword. In this case, the value in
the dictionary should be an empty string e.g. {'movebadrandom':""}
These commands are placed at the header of the PACKMOL input file
and therefore applied to all structures. NOTE: The PACKMOL options
for seed and tolerance are specified by the function parameters
seed and overlap.
Other command options can be found in the PACKMOL userguide:
http://www.ime.unicamp.br/~martinez/packmol/userguide.shtml

Returns
-------
Expand Down Expand Up @@ -407,14 +455,20 @@
# In angstroms for packmol.
overlap *= 10

# generate string of addl. packmol inputs given in packmol_args
packmol_commands = ""
if packmol_args:
for arg in packmol_args:
packmol_commands += "{} {} \n".format(arg, packmol_args[arg])

# Build the input file and call packmol.
filled_xyz = _new_xyz_file()

# List to hold file handles for the temporary compounds
compound_xyz_list = list()
try:
input_text = PACKMOL_HEADER.format(
overlap, filled_xyz.name, seed, sidemax * 10
overlap, filled_xyz.name, seed, sidemax * 10, packmol_commands
)
for comp, m_compounds, rotate, items_n in zip(
compound, n_compounds, fix_orientation, container
Expand Down Expand Up @@ -475,6 +529,7 @@
fix_orientation=False,
temp_file=None,
update_port_locations=False,
packmol_args=None,
):
"""Fill a sphere with a compound using PACKMOL.

Expand Down Expand Up @@ -518,8 +573,19 @@
temp_file : str, default=None
File name to write PACKMOL raw output to.
update_port_locations : bool, default=False
After packing, port locations can be updated, but since compounds can be
rotated, port orientation may be incorrect.
After packing, port locations can be updated, but since compounds
can be rotated, port orientation may be incorrect.
packmol_args : dict
Dictionary where the key, value pairs are options and their
corresponding keyword arguments for PACKMOL. Some PACKMOL options
do not require a specified keyword. In this case, the value in
the dictionary should be an empty string e.g. {'movebadrandom':""}
These commands are placed at the header of the PACKMOL input file
and therefore applied to all structures. NOTE: The PACKMOL options
for seed and tolerance are specified by the function parameters
seed and overlap.
Other command options can be found in the PACKMOL userguide:
http://www.ime.unicamp.br/~martinez/packmol/userguide.shtml

Returns
-------
Expand Down Expand Up @@ -613,14 +679,20 @@
radius *= 10
overlap *= 10

# generate string of addl. packmol inputs given in packmol_args
packmol_commands = ""
if packmol_args:
for arg in packmol_args:
packmol_commands += "{} {} \n".format(arg, packmol_args[arg])

# Build the input file for each compound and call packmol.
filled_xyz = _new_xyz_file()

# List to hold file handles for the temporary compounds
compound_xyz_list = list()
try:
input_text = PACKMOL_HEADER.format(
overlap, filled_xyz.name, seed, sidemax * 10
overlap, filled_xyz.name, seed, sidemax * 10, packmol_commands
)
for comp, m_compounds, rotate in zip(
compound, n_compounds, fix_orientation
Expand Down Expand Up @@ -670,6 +742,7 @@
temp_file=None,
update_port_locations=False,
center_solute=True,
packmol_args=None,
):
"""Solvate a compound in a box of solvent using PACKMOL.

Expand Down Expand Up @@ -701,10 +774,21 @@
temp_file : str, default=None
File name to write PACKMOL raw output to.
update_port_locations : bool, default=False
After packing, port locations can be updated, but since compounds can be
rotated, port orientation may be incorrect.
After packing, port locations can be updated, but since compounds
can be rotated, port orientation may be incorrect.
center_solute : bool, optional, default=True
Move solute center of mass to the center of the `mb.Box` used.
packmol_args : dict
Dictionary where the key, value pairs are options and their
corresponding keyword arguments for PACKMOL. Some PACKMOL options
do not require a specified keyword. In this case, the value in
the dictionary should be an empty string e.g. {'movebadrandom':""}
These commands are placed at the header of the PACKMOL input file
and therefore applied to all structures. NOTE: The PACKMOL options
for seed and tolerance are specified by the function parameters
seed and overlap.
Other command options can be found in the PACKMOL userguide:
http://www.ime.unicamp.br/~martinez/packmol/userguide.shtml

Returns
-------
Expand Down Expand Up @@ -735,6 +819,13 @@
# Apply edge buffer
box_maxs = np.subtract(box_maxs, edge * 10)
box_mins = np.add(box_mins, edge * 10)

# generate string of addl. packmol inputs given in packmol_args
packmol_commands = ""
if packmol_args:
for arg in packmol_args:
packmol_commands += "{} {} \n".format(arg, packmol_args[arg])

# Build the input file for each compound and call packmol.
solvated_xyz = _new_xyz_file()
solute_xyz = _new_xyz_file()
Expand All @@ -744,7 +835,7 @@
try:
solute.save(solute_xyz.name, overwrite=True)
input_text = PACKMOL_HEADER.format(
overlap, solvated_xyz.name, seed, sidemax * 10
overlap, solvated_xyz.name, seed, sidemax * 10, packmol_commands
) + PACKMOL_SOLUTE.format(solute_xyz.name, *center_solute.tolist())

for solv, m_solvent, rotate in zip(solvent, n_solvent, fix_orientation):
Expand Down
66 changes: 66 additions & 0 deletions mbuild/tests/test_packing.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,72 @@
with pytest.warns(UserWarning):
mb.fill_box(h2o, n_compounds=10, box=[1, 1, 1], overlap=10)

def test_packmol_args(self, h2o):
try:
chrisjonesBSU marked this conversation as resolved.
Show resolved Hide resolved
filled = mb.fill_box(
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
h2o,
n_compounds=2,
box=[0.1, 0.1, 0.1],
packmol_args={"maxit": 10, "movebadrandom": "", "nloop": 100},
)
except RuntimeError:
with open("log.txt", "r") as logfile:
assert "(movebadrandom)" in logfile.read()
logfile.seek(0)
assert (
"User defined GENCAN number of iterations: 10"
in logfile.read()
)

try:
mb.fill_region(
h2o,
10,
[[2, 2, 2, 4, 4, 4]],
bounds=[[2, 2, 2, 4, 4, 4]],
packmol_args={"maxit": 10, "movebadrandom": "", "nloop": 100},
)
except RuntimeError:
with open("log.txt", "r") as logfile:
assert "(movebadrandom)" in logfile.read()
logfile.seek(0)
assert (
"User defined GENCAN number of iterations: 10"
in logfile.read()
)

try:
filled = mb.fill_sphere(
Fixed Show fixed Hide fixed
h2o,
n_compounds=2,
sphere=[3, 3, 3, 1.5],
packmol_args={"maxit": 10, "movebadrandom": "", "nloop": 100},
)
except RuntimeError:
with open("log.txt", "r") as logfile:
assert "(movebadrandom)" in logfile.read()
logfile.seek(0)
assert (
"User defined GENCAN number of iterations: 10"
in logfile.read()
)
try:
mb.solvate(
solute=h2o,
solvent=[h2o],
n_solvent=[10],
box=[2, 2, 2],
packmol_args={"maxit": 15, "movebadrandom": "", "nloop": 100},
)
except RuntimeError:
with open("log.txt", "r") as logfile:
assert "(movebadrandom)" in logfile.read()
logfile.seek(0)
assert (
"User defined GENCAN number of iterations: 15"
in logfile.read()
)

def test_rotate(self, h2o):
filled = mb.fill_box(h2o, 2, box=[1, 1, 1], fix_orientation=True)
w0 = filled.xyz[:3]
Expand Down
Loading