Skip to content

Commit

Permalink
Added new to_hoomd method (#212)
Browse files Browse the repository at this point in the history
* Added new to_hoomd method

* Updated changelog and credits

* Removed working tempfiles and rolled back bumpversion

* Added to_json method to base class

* Added mapping functions to utils

* Migrated to_hoomd functions to use internal to_json method

* Updated tests

* Fixed capitalization errors

* Added more detail to return descriptor

* Updated credits

* Updated explanation for centering shapes in to_hoomd
  • Loading branch information
janbridley authored Feb 20, 2024
1 parent 6dee178 commit 9652b05
Show file tree
Hide file tree
Showing 16 changed files with 410 additions and 5 deletions.
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.
* 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
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

0 comments on commit 9652b05

Please sign in to comment.