def test_add_subtopology(self): top = Topology() subtop = SubTopology() assert top.n_subtops == 0 top.add_subtopology(subtop) assert top.n_subtops == 1
def test_3_layer_top(self): top_top = Top() mid_top = SubTop() site = Site() top_top.add_subtopology(mid_top) mid_top.add_site(site) compound = to_mbuild(top_top) assert len(compound.children) == 1 assert compound.children[0].n_particles == 1 assert compound.n_particles == 1
def test_add_site_parent(self): top = Topology() subtop = SubTopology() site1 = Atom(position=u.nm * np.zeros(3)) site2 = Atom(position=u.nm * np.ones(3)) top.add_subtopology(subtop) assert top.n_sites == 0 assert subtop.n_sites == 0 subtop.add_site(site1) assert top.n_sites == 1 assert subtop.n_sites == 1 top.add_site(site2) assert top.n_sites == 2 assert subtop.n_sites == 1
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 compound.name != mb.Compound().name: top.name = compound.name site_map = dict() for child in compound.children: if len(child.children) == 0: continue else: subtop = SubTopology(name=child.name) top.add_subtopology(subtop) for particle in child.particles(): pos = particle.xyz[0] * u.nanometer ele = search_method(particle.name) site = Site(name=particle.name, position=pos, element=ele) site_map[particle] = site subtop.add_site(site) top.update_topology() for particle in compound.particles(): already_added_site = site_map.get(particle, None) if already_added_site: continue pos = particle.xyz[0] * u.nanometer ele = search_method(particle.name) site = Site(name=particle.name, 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(name=particle.name) top.add_subtopology(subtop) subtop.add_site(site) else: top.add_site(site) for b1, b2 in compound.bonds(): new_bond = Bond(connection_members=[site_map[b1], site_map[b2]], connection_type=None) top.add_connection(new_bond) top.update_topology() if box: top.box = from_mbuild_box(box) # Assumes 2-D systems are not supported in mBuild # if compound.periodicity is None and not box: else: if np.allclose(compound.periodicity, np.zeros(3)): box = from_mbuild_box(compound.boundingbox) if box: box.lengths += [0.5, 0.5, 0.5] * u.nm top.box = box else: top.box = Box(lengths=compound.periodicity) return top