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 all 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
250 changes: 238 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 @@ -57,6 +61,43 @@
"""


def check_packmol_args(custom_args):
# List of all available packmol_inputs.
# Only file-level arguments can be passed.
allowed_args = [
"maxit", # int
"nloop", # int
"fbins", # float
"discale", # float
"movefrac", # float
"avoid_overlap", # On/Off (empty string "" is on)
"precision", # float
"movebadrandom", # On/off (empty string "" is on)
"use_short_tol", # On/off (empty string "" is on)
"short_tol_dist", # float
"short_tol_scale", # float
"tolerance",
"seed",
"sidemax",
]
default_args = ["tolerance", "seed", "sidemax"]
for key in custom_args:
if key not in allowed_args:
raise ValueError(
f"PACKMOL argument {key} is not usable in `packmol_args`. "
f"Availble arguments that can be set are {allowed_args}."
"Only file-level arguments can be set with `packmol_args`."
"See https://m3g.github.io/packmol/userguide.shtml#run"
)
if key in default_args:
warnings.warn(
f"The PACKMOL argument {key} was passed to `packmol_args`, "
"but should be set using the corresponding function parameters. "
"The value passed to the function will be used. "
"See the function's doc strings for more information."
)


def fill_box(
compound,
n_compounds=None,
Expand All @@ -71,6 +112,7 @@ def fill_box(
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 +172,46 @@ def fill_box(
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

Notes
-----
The packmol_args parameter is designed to only accept file-level
PACKMOL arguments, as opposed to molecule level arguments.

The allowed arguments include the following:

"maxit", # int
"nloop", # int
"fbins", # float
"discale", # float
"movefrac", # float
"avoid_overlap", # On/Off (empty string "" is on)
"precision", # float
"movebadrandom", # On/off (empty string "" is on)
"use_short_tol", # On/off (empty string "" is on)
"short_tol_dist", # float
"short_tol_scale", # float

The following PACKMOL arguments should be specified
by the mbuild.packing method's parameters:

"tolerance", "seed", "sidemax"

See the PACKMOL documentation for detailed explanations of these arguments:
http://www.ime.unicamp.br/~martinez/packmol/userguide.shtml

Returns
-------
Expand Down Expand Up @@ -231,14 +311,21 @@ def fill_box(
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:
check_packmol_args(packmol_args)
for arg, val in packmol_args.items():
packmol_commands += f"{arg} {val} \n"

# 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 +378,7 @@ def fill_region(
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 +415,46 @@ def fill_region(
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

Notes
-----
The packmol_args parameter is designed to only accept file-level
PACKMOL arguments, as opposed to molecule level arguments.

The allowed arguments include the following:

"maxit", # int
"nloop", # int
"fbins", # float
"discale", # float
"movefrac", # float
"avoid_overlap", # On/Off (empty string "" is on)
"precision", # float
"movebadrandom", # On/off (empty string "" is on)
"use_short_tol", # On/off (empty string "" is on)
"short_tol_dist", # float
"short_tol_scale", # float

The following PACKMOL arguments should be specified
by the mbuild.packing method's parameters:

"tolerance", "seed", "sidemax"

See the PACKMOL documentation for detailed explanations of these arguments:
http://www.ime.unicamp.br/~martinez/packmol/userguide.shtml

Returns
-------
Expand Down Expand Up @@ -407,14 +533,21 @@ def fill_region(
# In angstroms for packmol.
overlap *= 10

# generate string of addl. packmol inputs given in packmol_args
packmol_commands = ""
if packmol_args:
check_packmol_args(packmol_args)
for arg, val in packmol_args.items():
packmol_commands += f"{arg} {val} \n"

# 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 +608,7 @@ def fill_sphere(
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 +652,46 @@ def fill_sphere(
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

Notes
-----
The packmol_args parameter is designed to only accept file-level
PACKMOL arguments, as opposed to molecule level arguments.

The allowed arguments include the following:

"maxit", # int
"nloop", # int
"fbins", # float
"discale", # float
"movefrac", # float
"avoid_overlap", # On/Off (empty string "" is on)
"precision", # float
"movebadrandom", # On/off (empty string "" is on)
"use_short_tol", # On/off (empty string "" is on)
"short_tol_dist", # float
"short_tol_scale", # float

The following PACKMOL arguments should be specified
by the mbuild.packing method's parameters:

"tolerance", "seed", "sidemax"

See the PACKMOL documentation for detailed explanations of these arguments:
http://www.ime.unicamp.br/~martinez/packmol/userguide.shtml

Returns
-------
Expand Down Expand Up @@ -613,14 +785,21 @@ def fill_sphere(
radius *= 10
overlap *= 10

# generate string of addl. packmol inputs given in packmol_args
packmol_commands = ""
if packmol_args:
check_packmol_args(packmol_args)
for arg, val in packmol_args.items():
packmol_commands += f"{arg} {val} \n"

# 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 +849,7 @@ def solvate(
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 +881,48 @@ def solvate(
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

Notes
-----
The packmol_args parameter is designed to only accept file-level
PACKMOL arguments, as opposed to molecule level arguments.

The allowed arguments include the following:

"maxit", # int
"nloop", # int
"fbins", # float
"discale", # float
"movefrac", # float
"avoid_overlap", # On/Off (empty string "" is on)
"precision", # float
"movebadrandom", # On/off (empty string "" is on)
"use_short_tol", # On/off (empty string "" is on)
"short_tol_dist", # float
"short_tol_scale", # float

The following PACKMOL arguments should be specified
by the mbuild.packing method's parameters:

"tolerance", "seed", "sidemax"

See the PACKMOL documentation for detailed explanations of these arguments:
http://www.ime.unicamp.br/~martinez/packmol/userguide.shtml

Returns
-------
Expand Down Expand Up @@ -735,6 +953,14 @@ def solvate(
# 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:
check_packmol_args(packmol_args)
chrisjonesBSU marked this conversation as resolved.
Show resolved Hide resolved
for arg, val in packmol_args.items():
packmol_commands += f"{arg} {val} \n"

# Build the input file for each compound and call packmol.
solvated_xyz = _new_xyz_file()
solute_xyz = _new_xyz_file()
Expand All @@ -744,7 +970,7 @@ def solvate(
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
Loading
Loading