Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
2 changes: 2 additions & 0 deletions environment-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ dependencies:
- ipywidgets
- ele >= 0.2.0
- pre-commit
- pip:
- git+https://github.com/mosdef-hub/molbox.git#egg=molbox
65 changes: 55 additions & 10 deletions gmso/core/box.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import numpy as np
import unyt as u
from molbox import Box as MolBox
from unyt.array import allclose_units


Expand All @@ -22,7 +23,6 @@ def _validate_lengths(lengths):

lengths *= input_unit
lengths.convert_to_units(u.nm)

if np.any(
np.less(
lengths,
Expand Down Expand Up @@ -117,30 +117,75 @@ class Box(object):

"""

def __init__(self, lengths, angles=None):
def __init__(self, lengths, angles=None, precision=None):
"""Construct a `Box` based on lengths and angles."""
self._lengths = _validate_lengths(lengths)
self._angles = _validate_angles(angles)
print(lengths, angles)
lengths = _validate_lengths(lengths)
angles = _validate_angles(angles)
print(lengths, angles)
precision = int(precision or 6)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this set precision to 6 if you cant typecast precision to an int?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it does because you have handled that in Molbox.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah true, that makes sense.

self._box = MolBox(
lengths=lengths.value, angles=angles.value, precision=precision
)

@property
def lengths(self):
"""Return edge lengths of the box."""
return self._lengths
return self._box.lengths * u.nm

@property
def angles(self):
"""Return angles of the box."""
return self._angles
return self._box.angles * u.degree

@lengths.setter
def lengths(self, lengths):
"""Set the lengths of the box."""
self._lengths = _validate_lengths(lengths)
lengths = _validate_lengths(lengths).value
self._set_internal_box_vectors(lengths=lengths)

@angles.setter
def angles(self, angles):
"""Set the angles of the box."""
self._angles = _validate_angles(angles)
angles = _validate_angles(angles).value
self._set_internal_box_vectors(angles=angles)

@property
def precision(self):
"""Amount of decimals to represent floating point values."""
return self._box._precision

@precision.setter
def precision(self, precision):
"""Decimal point precision(default=16)."""
self._box.precision = precision

def _set_internal_box_vectors(self, lengths=None, angles=None):
from molbox.box import _lengths_angles_to_vectors

if angles is None:
angles = self.angles.value
if lengths is None:
lengths = self.lengths.value

self._box._vectors = _lengths_angles_to_vectors(
lengths, angles, self._box.precision
)

(
Lx,
Ly,
Lz,
xy,
xz,
yz,
) = self._box._from_vecs_to_lengths_tilt_factors()
self._box._Lx = Lx
self._box._Ly = Ly
self._box._Lz = Lz
self._box._xy = xy
self._box._xz = xz
self._box._yz = yz

def _unit_vectors_from_angles(self):
"""Return unit vectors describing prism from angles."""
Expand Down Expand Up @@ -173,7 +218,7 @@ def _unit_vectors_from_angles(self):

def get_vectors(self):
"""Return the vectors of the box."""
return (self._lengths * self.get_unit_vectors().T).T
return (self.lengths * self.get_unit_vectors().T).T

def get_unit_vectors(self):
"""Return the normalized vectors of the box."""
Expand All @@ -182,7 +227,7 @@ def get_unit_vectors(self):
def __repr__(self):
"""Return formatted representation of the box."""
return "Box(a={}, b={}, c={}, alpha={}, beta={}, gamma={})".format(
*self._lengths, *self._angles
*self.lengths, *self.angles
)

def __eq__(self, other):
Expand Down
14 changes: 6 additions & 8 deletions gmso/formats/lammpsdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,20 +100,18 @@ def write_lammpsdata(topology, filename, atom_style="full"):
atol=1e-8,
):
warnings.warn("Orthorhombic box detected")
box.lengths.convert_to_units(u.angstrom)
lengths = box.lengths.to(u.angstrom)
for i, dim in enumerate(["x", "y", "z"]):
data.write(
"{0:.6f} {1:.6f} {2}lo {2}hi\n".format(
0, box.lengths.value[i], dim
0, lengths.value[i], dim
)
)
else:
warnings.warn("Non-orthorhombic box detected")
box.lengths.convert_to_units(u.angstrom)
box.angles.convert_to_units(u.radian)
vectors = box.get_vectors()
a, b, c = box.lengths
alpha, beta, gamma = box.angles
vectors = box.get_vectors().to(u.dimensionless * u.angstrom)
a, b, c = box.lengths.to(u.angstrom)
alpha, beta, gamma = box.angles.to(u.radian)

lx = a
xy = b * np.cos(gamma)
Expand Down Expand Up @@ -372,7 +370,7 @@ def read_lammpsdata(

# Validate 'unit_style'
if unit_style not in ["real"]:
raiseValueError(
raise ValueError(
'Unit Style "{}" is invalid or is not currently supported'.format(
unit_style
)
Expand Down
6 changes: 4 additions & 2 deletions gmso/tests/test_box.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import numpy as np
import pytest
import unyt as u
from molbox.box import BoxError
from unyt.testing import assert_allclose_units

from gmso.core.box import Box
Expand All @@ -25,7 +26,7 @@ def test_bad_lengths(self, lengths, angles):
Box(lengths=lengths, angles=angles)

def test_build_2D_Box(self):
with pytest.warns(UserWarning):
with pytest.raises(BoxError):
Box(lengths=u.nm * [4, 4, 0])

def test_dtype(self, box):
Expand All @@ -47,7 +48,8 @@ def test_angles_setter(self, lengths, angles):
box = Box(lengths=lengths, angles=u.degree * np.ones(3))
angles *= u.degree
box.angles = angles
assert (box.angles == angles).all()
print(angles, box.angles)
assert u.allclose_units(angles, box.angles, rtol=10 ** (-box.precision))

@pytest.mark.parametrize("lengths", [[3, 3, 3], [4, 4, 4], [4, 6, 4]])
def test_setters_with_lists(self, lengths):
Expand Down
12 changes: 3 additions & 9 deletions gmso/tests/test_lammps.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,8 @@ def test_read_lammps_triclinic(self, typed_ar_system):

read = read_lammpsdata("data.triclinic")
assert_allclose_units(
read.box.lengths,
u.unyt_array([1, 1, 1], u.nm),
rtol=1e-5,
atol=1e-8,
read.box.lengths, u.unyt_array([1.0, 1.0, 1.0], u.nm)
)
assert_allclose_units(
read.box.angles,
u.unyt_array([60, 90, 120], u.degree),
rtol=1e-5,
atol=1e-8,
assert u.allclose_units(
read.box.angles, u.unyt_array([60, 90, 120], u.degree)
)