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

Added new to_hoomd method #212

Merged
merged 12 commits into from
Feb 20, 2024
1 change: 1 addition & 0 deletions ChangeLog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Added
- ``simplices``, ``equations``, and ``face_centroids`` properties for the
ConvexPolyhedron class.
- Additional pytests for surface area, volume, centroid, moment of inertia, and equations properties.
- Added ``to_hoomd`` export method for use with simulation tools

Changed
~~~~~~~
Expand Down
1 change: 1 addition & 0 deletions Credits.rst
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ Jen Bradley
* Added ``simplices``, ``equations``, and ``face_centroids`` properties to the
ConvexPolyhedron class.
* Optimized pytest configurations for more efficient use of local and remote resources.
* Added ``to_json`` and ``to_hoomd`` export methods.

Domagoj Fijan

Expand Down
24 changes: 24 additions & 0 deletions coxeter/shapes/base_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,30 @@ def to_plato_scene(self, backend="matplotlib", scene=None, scene_kwargs=None):
scene.add_primitive(prim)
return scene

def to_json(self, attributes: list):
"""Get a JSON-serializable subset of shape properties.

Args:
attributes (list):
List of attributes to export. Each element must be a valid attribute
of the class.

Returns
-------
dict
A dict containing the requested attributes.

Raises
------
AttributeError:
If any keys in the input list are invalid.
"""
export = {}
for attribute in attributes:
# If an invalid key is passed, this will raise an attribute error
export.update({attribute: getattr(self, attribute)})
return export


class Shape2D(Shape):
"""An abstract representation of a shape in 2 dimensions."""
Expand Down
35 changes: 35 additions & 0 deletions coxeter/shapes/convex_spheropolygon.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .base_classes import Shape2D
from .convex_polygon import ConvexPolygon, _is_convex
from .polygon import _align_points_by_normal
from .utils import _hoomd_dict_mapping, _map_dict_keys


class ConvexSpheropolygon(Shape2D):
Expand Down Expand Up @@ -267,3 +268,37 @@ def _plato_primitive(self, backend):
vertices=verts[:, :2],
radius=self.radius,
)

def to_hoomd(self):
"""Get a JSON-serializable subset of ConvexSpheropolygon properties.

The JSON-serializable output of the to_hoomd method can be directly imported
into data management tools like signac. This data can then be queried for use in
HOOMD simulations. Key naming matches HOOMD integrators: for example, the
moment_inertia key links to data from coxeter's inertia_tensor. Stored values
are based on the shape with its centroid at the origin.

For a ConvexSpheropolygon, the following properties are stored:

* vertices (list(list)):
The vertices of the shape.
janbridley marked this conversation as resolved.
Show resolved Hide resolved
* centroid (list(float))
The centroid of the shape.
This is set to [0,0,0] per HOOMD's spec.
* sweep_radius (float):
The rounding radius of the shape.
* area (float)
The area of the shape.

Returns
-------
dict
Dict containing a subset of shape properties required for HOOMD function.
"""
old_centroid = self._polygon.centroid
data = self.to_json(["vertices", "radius", "area"])
hoomd_dict = _map_dict_keys(data, key_mapping=_hoomd_dict_mapping)
hoomd_dict["centroid"] = [0, 0, 0]

self._polygon.centroid = old_centroid
return hoomd_dict
36 changes: 36 additions & 0 deletions coxeter/shapes/convex_spheropolyhedron.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from .base_classes import Shape3D
from .convex_polyhedron import ConvexPolyhedron
from .utils import _hoomd_dict_mapping, _map_dict_keys


class ConvexSpheropolyhedron(Shape3D):
Expand Down Expand Up @@ -328,3 +329,38 @@ def _plato_primitive(self, backend):
vertices=self.vertices,
radius=self.radius,
)

def to_hoomd(self):
"""Get a JSON-serializable subset of ConvexSpheropolyhedron properties.

The JSON-serializable output of the to_hoomd method can be directly imported
into data management tools like signac. This data can then be queried for use in
HOOMD simulations. Key naming matches HOOMD integrators: for example, the
moment_inertia key links to data from coxeter's inertia_tensor. Stored values
are based on the shape with its centroid at the origin.

For a ConvexSpheropolyhedron, the following properties are stored:

* vertices (list(list)):
The vertices of the shape.
* centroid (list(float))
The centroid of the shape.
This is set to [0,0,0] per HOOMD's spec.
* sweep_radius (float):
The rounding radius of the shape.
* volume (float)
The volume of the shape.

Returns
-------
dict
Dict containing a subset of shape properties required for HOOMD function.
"""
old_centroid = self._polyhedron.centroid
self._polyhedron.centroid = np.array([0, 0, 0])
data = self.to_json(["vertices", "radius", "volume"])
hoomd_dict = _map_dict_keys(data, key_mapping=_hoomd_dict_mapping)
hoomd_dict["centroid"] = [0, 0, 0]

self._polyhedron.centroid = old_centroid
DomFijan marked this conversation as resolved.
Show resolved Hide resolved
return hoomd_dict
40 changes: 39 additions & 1 deletion coxeter/shapes/ellipsoid.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from .base_classes import Shape3D
from .sphere import Sphere
from .utils import translate_inertia_tensor
from .utils import _hoomd_dict_mapping, _map_dict_keys, translate_inertia_tensor


class Ellipsoid(Shape3D):
Expand Down Expand Up @@ -225,3 +225,41 @@ def __repr__(self):
f"coxeter.shapes.Ellipsoid(a={self.a}, b={self.b}, c={self.c}, "
f"center={self.centroid.tolist()})"
)

def to_hoomd(self):
"""Get a JSON-serializable subset of Ellipsoid properties.

The JSON-serializable output of the to_hoomd method can be directly imported
into data management tools like signac. This data can then be queried for use in
HOOMD simulations. Key naming matches HOOMD integrators: for example, the
moment_inertia key links to data from coxeter's inertia_tensor. Stored values
are based on the shape with its centroid at the origin.

For an Ellipsoid, the following properties are stored:

* a (float):
half axis of ellipsoid in the x direction
* b (float):
half axis of ellipsoid in the y direction
* c (float):
half axis of ellipsoid in the z direction
* centroid (list(float))
The centroid of the shape.
This is set to [0,0,0] per HOOMD's spec.
* volume (float)
The volume of the shape.
* moment_inertia (list(list))
The shape's inertia tensor.

Returns
-------
dict
Dict containing a subset of shape properties required for HOOMD function.
"""
old_centroid = self.centroid
self.centroid = np.array([0, 0, 0])
data = self.to_json(["a", "b", "c", "centroid", "volume", "inertia_tensor"])
hoomd_dict = _map_dict_keys(data, key_mapping=_hoomd_dict_mapping)

self.centroid = old_centroid
return hoomd_dict
45 changes: 44 additions & 1 deletion coxeter/shapes/polygon.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@
from ..extern.polytri import polytri
from .base_classes import Shape2D
from .circle import Circle
from .utils import _generate_ax, rotate_order2_tensor, translate_inertia_tensor
from .utils import (
_generate_ax,
_hoomd_dict_mapping,
_map_dict_keys,
rotate_order2_tensor,
translate_inertia_tensor,
)

try:
import miniball
Expand Down Expand Up @@ -761,3 +767,40 @@ def _plato_primitive(self, backend):
colors=np.array([[0.5, 0.5, 0.5, 1]]),
vertices=verts[:, :2],
)

def to_hoomd(self):
"""Get a JSON-serializable subset of Polygon properties.

The JSON-serializable output of the to_hoomd method can be directly imported
into data management tools like signac. This data can then be queried for use in
HOOMD simulations. Key naming matches HOOMD integrators: for example, the
moment_inertia key links to data from coxeter's inertia_tensor. Stored values
are based on the shape with its centroid at the origin.

For a Polygon or ConvexPolygon, the following properties are stored:

* vertices (list(list)):
The vertices of the shape.
* centroid (list(float))
The centroid of the shape.
This is set to [0,0,0] per HOOMD's spec.
* sweep_radius (float):
The rounding radius of the shape (0.0).
* area (float)
The area of the shape.
* moment_inertia (list(list))
The shape's inertia tensor.

Returns
-------
dict
Dict containing a subset of shape properties required for HOOMD function.
"""
old_centroid = self.centroid
self.centroid = np.array([0, 0, 0])
data = self.to_json(["vertices", "centroid", "area", "inertia_tensor"])
hoomd_dict = _map_dict_keys(data, key_mapping=_hoomd_dict_mapping)
hoomd_dict["sweep_radius"] = 0.0

self.centroid = old_centroid
return hoomd_dict
49 changes: 48 additions & 1 deletion coxeter/shapes/polyhedron.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@
from .convex_polygon import ConvexPolygon, _is_convex
from .polygon import Polygon, _is_simple
from .sphere import Sphere
from .utils import _generate_ax, _set_3d_axes_equal, translate_inertia_tensor
from .utils import (
_generate_ax,
_hoomd_dict_mapping,
_map_dict_keys,
_set_3d_axes_equal,
translate_inertia_tensor,
)

try:
import miniball
Expand Down Expand Up @@ -973,3 +979,44 @@ def _plato_primitive(self, backend):
indices=self.faces,
shape_colors=np.array([[0.5, 0.5, 0.5, 1]]),
)

def to_hoomd(self):
"""Get a JSON-serializable subset of Polyhedron properties.

The JSON-serializable output of the to_hoomd method can be directly imported
into data management tools like signac. This data can then be queried for use in
HOOMD simulations. Key naming matches HOOMD integrators: for example, the
moment_inertia key links to data from coxeter's inertia_tensor. Stored values
are based on the shape with its centroid at the origin.

For a Polyhedron or ConvexPolyhedron, the following properties are stored:

* vertices (list(list)):
The vertices of the shape.
* faces (list(list)):
The faces of the shape.
* centroid (list(float))
The centroid of the shape.
This is set to [0,0,0] per HOOMD's spec.
* sweep_radius (float):
The rounding radius of the shape (0.0).
* volume (float)
The volume of the shape.
* moment_inertia (list(list))
The shape's inertia tensor.

Returns
-------
dict
Dict containing a subset of shape properties required for HOOMD function.
"""
old_centroid = self.centroid
self.centroid = np.array([0, 0, 0])
data = self.to_json(
["vertices", "faces", "centroid", "volume", "inertia_tensor"]
)
hoomd_dict = _map_dict_keys(data, key_mapping=_hoomd_dict_mapping)
hoomd_dict["sweep_radius"] = 0.0

self.centroid = old_centroid
return hoomd_dict
48 changes: 47 additions & 1 deletion coxeter/shapes/sphere.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import numpy as np

from .base_classes import Shape3D
from .utils import translate_inertia_tensor
from .utils import _hoomd_dict_mapping, _map_dict_keys, translate_inertia_tensor


class Sphere(Shape3D):
Expand Down Expand Up @@ -68,6 +68,18 @@ def radius(self, value):
else:
raise ValueError("Radius must be greater than zero.")

@property
def diameter(self):
"""float: Get or set the radius of the sphere."""
return 2 * self._radius

@diameter.setter
def diameter(self, value):
if value > 0:
self._radius = value / 2
else:
raise ValueError("Diameter must be greater than zero.")

def _rescale(self, scale):
"""Multiply length scale.

Expand Down Expand Up @@ -202,3 +214,37 @@ def _plato_primitive(self, backend):
colors=np.array([[0.5, 0.5, 0.5, 1]]),
radii=[self.radius],
)

def to_hoomd(self):
"""Get a dict of JSON-serializable subset of Sphere properties.

The JSON-serializable output of the to_hoomd method can be directly imported
into data management tools like signac. This data can then be queried for use in
HOOMD simulations. Key naming matches HOOMD integrators: for example, the
moment_inertia key links to data from coxeter's inertia_tensor. Stored values
are based on the shape with its centroid at the origin.

For a Sphere, the following properties are stored:

* diameter (float):
The diameter of the sphere, equal to twice the radius.
* centroid (list(float))
The centroid of the shape.
This is set to [0,0,0] per HOOMD's spec.
* volume (float)
The volume of the shape.
* moment_inertia (list(list))
The shape's inertia tensor.

Returns
-------
dict
Dict containing a subset of shape properties required for HOOMD function.
"""
old_centroid = self.centroid
self.centroid = np.array([0, 0, 0])
data = self.to_json(["diameter", "centroid", "volume", "inertia_tensor"])
hoomd_dict = _map_dict_keys(data, key_mapping=_hoomd_dict_mapping)

self.centroid = old_centroid
return hoomd_dict
Loading