diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dee3f41f3..5fdacb163 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,7 +10,7 @@ ci: repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.15.21 + rev: v0.15.22 hooks: # Run the linter. - id: ruff diff --git a/.readthedocs.yml b/.readthedocs.yml index bcc8131b9..27fc74fc1 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -5,9 +5,9 @@ formats: conda: environment: docs/docs-env.yml build: - os: ubuntu-20.04 + os: ubuntu-24.04 tools: - python: "mambaforge-4.10" + python: "mambaforge-latest" sphinx: builder: html configuration: docs/conf.py diff --git a/docs/conf.py b/docs/conf.py index 0e7c99acf..a249a7cf5 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -158,8 +158,8 @@ # built documents. # -version = "1.3.0" -release = "1.3.0" +version = "1.4.0" +release = "1.4.0" # The language for content autogenerated by Sphinx. Refer to documentation diff --git a/mbuild/__init__.py b/mbuild/__init__.py index 4b9d5f3e0..7213fbfbb 100644 --- a/mbuild/__init__.py +++ b/mbuild/__init__.py @@ -18,7 +18,7 @@ from mbuild.port import Port from mbuild.recipes import recipes -__version__ = "1.3.1" +__version__ = "1.4.0" __date__ = "2025-11-10" diff --git a/mbuild/conversion.py b/mbuild/conversion.py index cdaf7ec31..9ce0b3c4b 100644 --- a/mbuild/conversion.py +++ b/mbuild/conversion.py @@ -493,6 +493,54 @@ def load_file( return compound +def from_coxeter(shape, compound=None, ref_length=1, element=None, name=None): + """Backend-specific loading function for Coxeter. + + Vertices are placed as particles and edges become bonds. The shape is + scaled so that its longest edge has length ``ref_length``, independent of + coxeter's native (unit-volume / unit-area) normalization. + + Parameters + ---------- + shape : coxeter.shapes + Any member of coxeter.shapes that exposes ``vertices`` and ``edges``. + compound : mb.Compound, optional, default=None + Host mb.Compound to load into. A new one is created if left as ``None``. + ref_length : float, optional, default=1 + Target length of the longest edge, in the compound's units. + element : str, optional, default=None + The element symbol that sets the particle type for the particles. + If None, a generic bead-type is used. + name : str, optional, default="X" + Sets the particle name, but not the element. + Use this instead of ``element`` for non-atomistic particles. + """ + if compound is None: + compound = mb.Compound() + + scale = ref_length / shape.edge_lengths.max() + + particles = [] + for v in shape.vertices: + p = mb.Compound(pos=np.asarray(v) * scale) + if element: + p.element = element_from_symbol(element) + if not name: + p.name = element + else: + p.name = name + elif name: + p.name = name + compound.add(p) + particles.append(p) + + for edge in shape.edges: + p1 = particles[int(edge[0])] + p2 = particles[int(edge[1])] + compound.add_bond(particle_pair=(p1, p2)) + return compound + + def from_parmed( structure, compound=None, coords_only=False, infer_hierarchy=True, **kwargs ): diff --git a/mbuild/packing.py b/mbuild/packing.py index 7d1b8dad2..1f29ce89c 100644 --- a/mbuild/packing.py +++ b/mbuild/packing.py @@ -1196,15 +1196,15 @@ def _run_packmol(input_text, filled_xyz, temp_file, packmol_file): ): shutil.copyfileobj(inp_file, new_file) - proc = Popen( - f"{PACKMOL} < {packmol_inp.name}", - stdin=PIPE, - stdout=PIPE, - stderr=PIPE, - universal_newlines=True, - shell=True, - ) - out, err = proc.communicate() + with open(packmol_inp.name) as inp_file: + proc = Popen( + [PACKMOL], + stdin=inp_file, + stdout=PIPE, + stderr=PIPE, + universal_newlines=True, + ) + out, err = proc.communicate() if "WITHOUT PERFECT PACKING" in out: logger.warning( diff --git a/mbuild/periodic_kdtree.py b/mbuild/periodic_kdtree.py index 0e7a0c098..8eb392766 100644 --- a/mbuild/periodic_kdtree.py +++ b/mbuild/periodic_kdtree.py @@ -383,7 +383,7 @@ def query_ball_point(self, x, r, p=2.0, eps=0): return self.__query_ball_point(x, r, p, eps) else: retshape = x.shape[:-1] - result = np.empty(retshape, dtype=np.object) + result = np.empty(retshape, dtype=object) for c in np.ndindex(retshape): result[c] = self.__query_ball_point(x[c], r, p, eps) return result diff --git a/pyproject.toml b/pyproject.toml index f4832fa20..71cc17e21 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ classifiers=[ "Operating System :: MacOS", ] urls = {Homepage = "https://github.com/mosdef-hub/mbuild"} -requires-python = ">=3.10" +requires-python = ">=3.11" dynamic = ["version"] [tool.setuptools] diff --git a/setup.cfg b/setup.cfg index 001d8110e..4731328f8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.3.0 +current_version = 1.4.0 commit = True tag = True message = Bump to version {new_version}