Skip to content

Commit

Permalink
Merge branch 'main' into update_port_access_labels
Browse files Browse the repository at this point in the history
  • Loading branch information
daico007 committed May 26, 2022
2 parents b9045c8 + bcbf980 commit 482fef1
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 1 deletion.
48 changes: 47 additions & 1 deletion mbuild/compound.py
Original file line number Diff line number Diff line change
Expand Up @@ -1331,7 +1331,7 @@ def is_independent(self):
if not self.parent:
# This is the very top level, and hence have to be independent
return True
elif not list(self.root.bonds()):
elif not self.root.bond_graph:
# If there is no bond in the top level, then everything is independent
return True
else:
Expand Down Expand Up @@ -1679,6 +1679,52 @@ def _visualize_nglview(self, show_ports=False, color_scheme={}):
overwrite_nglview_default(widget)
return widget

def flatten(self, inplace=True):
"""Flatten the hierarchical structure of the Compound.
Modify the mBuild Compound to become a Compound where there is
a single container (self) that contains all the particles.
Parameter
---------
inplace : bool, optional, default=True
Option to perform the flatten operation inplace or return a copy
Return
------
self : mb.Compound or None
return a flatten Compound if inplace is False.
"""
ports_list = list(self.all_ports())
children_list = list(self.children)
particle_list = list(self.particles())
bond_graph = self.root.bond_graph

# Make a list of bond that involved the particles of this compound.
# This include bonds made exist between this compound and other
# component of the system
new_bonds = list()
for particle in particle_list:
for neighbor in bond_graph._adj.get(particle, []):
new_bonds.append((particle, neighbor))

# Remove all the children
if inplace:
for child in children_list:
# Need to handle the case when child is a port
self.remove(child)

# Re-add the particles and bonds
self.add(particle_list)
self.add(ports_list)

for bond in new_bonds:
self.add_bond(bond)
else:
comp = clone(self)
comp.flatten(inplace=True)
return comp

def update_coordinates(self, filename, update_port_locations=True):
"""Update the coordinates of this Compound from a file.
Expand Down
35 changes: 35 additions & 0 deletions mbuild/tests/test_compound.py
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,41 @@ def test_particle_in_particle(self):
assert len(list(parent.ancestors())) == 0
assert next(parent.particles_by_name("A")) == part

def test_flatten_eth(self, ethane):
# Before flattening
assert len(ethane.children) == 2
assert ethane.n_particles == 8
assert ethane.n_bonds == 7

# Flatten with inplace = False
copy = ethane.flatten(inplace=False)
assert ethane.n_particles == copy.n_particles == len(copy.children)
assert ethane.n_bonds == copy.n_bonds

# After flattening
ethane.flatten()
assert len(ethane.children) == ethane.n_particles == 8
assert ethane.n_bonds == 7

def test_flatten_box_of_eth(self, ethane):
box_of_eth = mb.fill_box(compound=ethane, n_compounds=2, box=[1, 1, 1])
# Before flattening
assert len(box_of_eth.children) == 2
assert box_of_eth.n_bonds == 7 * 2
assert box_of_eth.n_particles == 8 * 2

# After flattening
box_of_eth.flatten()
assert len(box_of_eth.children) == box_of_eth.n_particles == 8 * 2
assert box_of_eth.n_bonds == 7 * 2

def test_flatten_with_port(self, ethane):
ethane.remove(ethane[2])
original_ports = ethane.all_ports()
ethane.flatten()
assert len(ethane.all_ports()) == len(original_ports)
assert ethane.all_ports()[0] == original_ports[0]

@pytest.mark.skipif(
not has_openbabel, reason="Open Babel package not installed"
)
Expand Down

0 comments on commit 482fef1

Please sign in to comment.