Source code for gmso.external.convert_mbuild

"""Convert to and from an mbuild.Compound."""
from warnings import warn

import numpy as np
import unyt as u

from gmso.core.atom import Atom
from import Bond
from import Box
from gmso.core.element import (
from gmso.core.subtopology import SubTopology
from gmso.core.topology import Topology
from import has_mbuild

if has_mbuild:
    import mbuild as mb

[docs]def from_mbuild(compound, box=None, search_method=element_by_symbol): """Convert an mbuild.Compound to a gmso.Topology. This conversion makes the following assumptions about the inputted `Compound`: * All positional and box dimension values in compound are in nanometers. * If the `Compound` has 4 or more levels of hierarchy, these are\ compressed to 3 levels of hierarchy in the resulting `Topology`. The\ top level `Compound` becomes the `Topology`, the second level\ Compounds become `SubTopologies`, and each particle becomes a `Site`,\ which are added to their corresponding `SubTopologies`. * Furthermore, `Sites` that do not belong to a sub-`Compound` are\ added to a single-`Site` `SubTopology`. * The box dimension are extracted from `compound.periodicity`. If\ the `compound.periodicity` is `None`, the box lengths are the lengths of\ the bounding box + a 0.5 nm buffer. * Only `Bonds` are added for each bond in the `Compound`. If `Angles`\ and `Dihedrals` are desired in the resulting `Topology`, they must be\ added separately from this function. Parameters ---------- compound : mbuild.Compound mbuild.Compound instance that need to be converted box : mbuild.Box, optional, default=None Box information to be loaded to a gmso.Topology search_method : function, optional, default=element_by_symbol Searching method used to assign element from periodic table to particle site. The information specified in the `search_method` argument is extracted from each `Particle`'s `name` attribute. Valid functions are element_by_symbol, element_by_name, element_by_atomic_number, and element_by_mass, which can be imported from `gmso.core.element' Returns ------- top : gmso.Topology """ msg = "Argument compound is not an mbuild.Compound" assert isinstance(compound, mb.Compound), msg top = Topology() top.typed = False # Keep the name if it is not the default mBuild Compound name if != mb.Compound().name: = site_map = dict() for child in compound.children: if len(child.children) == 0: continue else: subtop = SubTopology( top.add_subtopology(subtop, update=False) for particle in child.particles(): pos =[0] * u.nanometer if particle.element: ele = search_method(particle.element.symbol) else: ele = search_method( site = Atom(, position=pos, element=ele) site_map[particle] = site subtop.add_site(site, update_types=False) for particle in compound.particles(): already_added_site = site_map.get(particle, None) if already_added_site: continue pos =[0] * u.nanometer if particle.element: ele = search_method(particle.element.symbol) else: ele = search_method( site = Atom(, position=pos, element=ele) site_map[particle] = site # If the top has subtopologies, then place this particle into # a single-site subtopology -- ensures that all sites are in the # same level of hierarchy. if len(top.subtops) > 0: subtop = SubTopology( top.add_subtopology(subtop) subtop.add_site(site, update_types=False) else: top.add_site(site, update_types=False) for b1, b2 in compound.bonds(): new_bond = Bond( connection_members=[site_map[b1], site_map[b2]], bond_type=None ) top.add_connection(new_bond, update_types=False) top.update_topology() if box: = from_mbuild_box(box) # Assumes 2-D systems are not supported in mBuild # if compound.periodicity is None and not box: else: if = from_mbuild_box( else: = from_mbuild_box(compound.get_boundingbox()) top.periodicity = compound.periodicity return top
[docs]def to_mbuild(topology): """Convert a gmso.Topology to mbuild.Compound. Parameters ---------- topology : gmso.Topology topology instance that need to be converted Returns ------- compound : mbuild.Compound """ msg = "Argument topology is not a Topology" assert isinstance(topology, Topology), msg compound = mb.Compound() if is Topology().name: = "Compound" else: = particle_map = dict() for site in topology.sites: if site.element: element = site.element.symbol else: element = None particle = mb.Compound(, pos=site.position, element=element ) particle_map[site] = particle compound.add(particle) for connect in topology.connections: if isinstance(connect, Bond): compound.add_bond( ( particle_map[connect.connection_members[0]], particle_map[connect.connection_members[1]], ) ) return compound
def from_mbuild_box(mb_box): """Convert an mBuild box to a GMSO box. Assumes that the mBuild box dimensions are in nanometers Parameters ---------- mb_box : mbuild.Box mBuild box object to be converted to a gmso.core.Box object Returns ------- box : gmso.core.Box """ # TODO: Unit tests if not isinstance(mb_box, mb.Box): raise ValueError("Argument mb_box is not an mBuild Box") if np.allclose(mb_box.lengths, [0, 0, 0]): warn("No box or boundingbox information detected, setting box to None") return None box = Box( lengths=np.asarray(mb_box.lengths) * u.nm, angles=np.asarray(mb_box.angles) *, ) return box