def connect(source, destination): """Connects two components or ports. Defines a power bond between the source and destination ports such that the bond tail is at the source, and the bond head is at the destination. We assume that either the source and/or destination is or has a free port. Args: source (Port or BondGraphBase): The tail of the power bond destination (Port or BondGraphBase): The head of the power bond Raises: InvalidPortException, InvalidComponentException See Also: :func:`disconnect` """ tail = _find_or_make_port(source, is_tail=True) head = _find_or_make_port(destination) model = tail.component.parent model_prime = head.component.parent if not model: raise InvalidComponentException(f"{tail.component} is not in a model") elif not model_prime: raise InvalidComponentException(f"{head.component} is not in a model") elif model is not model_prime: raise InvalidComponentException("Components are in different models") bond = Bond(tail, head) model.bonds.add(bond)
def swap(old_component, new_component): """ Replaces the old component with a new component. Components must be of compatible classes; 1 one port cannot replace an n-port, for example. The old component will be completely removed from the system model. Args: old_component: The component to be replaced. Must already be in the model. new_component: The substitute component which must not be in the model Raises: InvalidPortException, InvalidComponentException """ # TODO: More validation required def is_swap_valid(old_comp, new_comp): # noqa if not isinstance(new_comp, BondGraphBase): return False return True model = old_component.parent if not model: raise InvalidComponentException("No parent model.") elif new_component in model.components: raise InvalidComponentException("Component is already in the model") elif not is_swap_valid(old_component, new_component): raise InvalidComponentException("Cannot swap components") model.add(new_component) swaps = [] for bond in model.bonds: try: if bond.tail.component is old_component: tail = new_component.get_port() head = bond.head elif bond.head.component is old_component: tail = bond.tail head = new_component.get_port() else: continue except InvalidPortException: raise InvalidComponentException( "Cannot swap components: Incompatible ports") swaps.append((bond, Bond(tail, head))) for old_bond, new_bond in swaps: disconnect(old_bond.tail, old_bond.head) connect(new_bond.tail, new_bond.head) model.remove(old_component)
def test_compare(self): from BondGraphTools.base import Bond from BondGraphTools.actions import new c = new('C') one = new('1') b_1 = Bond(head=(c, 0), tail=(one, 0)) assert b_1 == ((one, 0), (c, 0))
def remove(self, bond): tail = bond.tail head = bond.head if bond in self: super().remove(bond) else: super().remove(Bond(head, tail)) head.is_connected = False tail.is_connected = False
def test_create(self): from BondGraphTools.base import Bond from BondGraphTools.actions import new c = new('C') one = new('1') b_1 = Bond(head=(c, 0), tail=(one, 0)) assert c in b_1 assert one in b_1 assert (c, 0) in b_1 assert (one, 0) in b_1 assert (one, 1) not in b_1