diff --git a/interfaces/cython/cantera/drawnetwork.py b/interfaces/cython/cantera/drawnetwork.py index 3731031bb..f5ad82e7a 100644 --- a/interfaces/cython/cantera/drawnetwork.py +++ b/interfaces/cython/cantera/drawnetwork.py @@ -199,6 +199,7 @@ def draw_surface(surface, dot=None, **kwargs): return dot def draw_connections(connections, dot=None, **kwargs): +def draw_connections(connections, dot=None, show_wall_velocity=True, **kwargs): """ Draw connections between reactors and reservoirs. This includes flow controllers and walls. @@ -272,6 +273,27 @@ def draw_connections(connections, dot=None, **kwargs): # remove duplicates from the set of the connections still to be drawn connections.difference_update(duplicates | inv_duplicates) + # id to ensure that wall velocity and heat flow arrows align + samehead = sametail = r_in.name + "-" + r_out.name + # display wall velocity as arrow indicating the wall's movement + try: + if c.velocity != 0 and show_wall_velocity: + if c.velocity > 0: + v = c.velocity + inflow_name, outflow_name = r_in.name, r_out.name + else: + v = -c.velocity + inflow_name, outflow_name = r_out_name, r_in_name + + dot.edge(inflow_name, outflow_name, + **{"arrowtail": "teecrow", "dir": "back", + "arrowsize": "1.5", "penwidth": "0", "weight": "2", + "samehead": samehead, "sametail": sametail, + "taillabel": f"wall velocity = {v:.2g} m/s", + **kwargs.get("wall_edge_attr", {})}) + except AttributeError: + pass + # sum up heat rate/mass flow rate while considering the direction rate = (getattr(c, rate_attr) + sum(getattr(c, rate_attr) for c in duplicates) @@ -289,6 +311,8 @@ def draw_connections(connections, dot=None, **kwargs): elif rate_attr == "heat_rate": label = f"q = {rate:.2g} W" - dot.edge(inflow_name, outflow_name, **{"label": label, **edge_attr}) + dot.edge(inflow_name, outflow_name, + **{"label": label, "samehead": samehead, "sametail": sametail, + **edge_attr}) return dot diff --git a/test/python/test_reactor.py b/test/python/test_reactor.py index 537cac169..d26103ae8 100644 --- a/test/python/test_reactor.py +++ b/test/python/test_reactor.py @@ -917,7 +917,26 @@ class TestReactor(utilities.CanteraTest): dot = w.draw(node_attr={'style': 'filled'}, edge_attr={'style': 'dashed'}) expected = [('\t"Name 2" -> "Name 1" [label="q = 30 W" ' - 'color=blue style=dashed]\n')] + 'color=blue samehead="Name 1-Name 2" ' + 'sametail="Name 1-Name 2" style=dashed]\n')] + self.assertEqual(dot.body, expected) + + @utilities.unittest.skipIf(_graphviz is None, "graphviz is not installed") + def test_draw_moving_wall(self): + T1, P1, X1 = 300, 101325, 'O2:1.0' + T2, P2, X2 = 600, 101325, 'O2:1.0' + self.make_reactors(T1=T1, P1=P1, X1=X1, T2=T2, P2=P2, X2=X2) + self.r1.name = "Name 1" + self.r2.name = "Name 2" + w = ct.Wall(self.r1, self.r2, U=0.1, velocity=1) + dot = w.draw() + expected = [('\t"Name 1" -> "Name 2" [arrowsize=1.5 arrowtail=teecrow ' + 'dir=back penwidth=0 samehead="Name 1-Name 2" ' + 'sametail="Name 1-Name 2" ' + 'taillabel="wall velocity = 1 m/s" weight=2]\n'), + ('\t"Name 2" -> "Name 1" [label="q = 30 W" ' + 'color=red samehead="Name 1-Name 2" ' + 'sametail="Name 1-Name 2" style=dashed]\n')] self.assertEqual(dot.body, expected) @utilities.unittest.skipIf(_graphviz is None, "graphviz is not installed") @@ -937,6 +956,7 @@ class TestReactor(utilities.CanteraTest): dot = mfc.draw(node_attr={'style': 'filled'}, edge_attr={'style': 'dotted'}) expected = [('\tInlet -> Reactor [label="m = 2 kg/s" ' + 'samehead="Inlet-Reactor" sametail="Inlet-Reactor" ' 'style=dotted xlabel=MFC]\n')] self.assertEqual(dot.body, expected) @@ -973,15 +993,20 @@ class TestReactor(utilities.CanteraTest): ('\tOutlet [label="{T (K)\\n200.00|P (bar)' '\\n1.013}|" shape=Mrecord xlabel=Outlet]\n'), ('\t"Cold inlet" -> "Cold reactor" [label="m = 2 kg/s" ' - 'color=green]\n'), + 'color=green samehead="Cold inlet-Cold reactor" ' + 'sametail="Cold inlet-Cold reactor"]\n'), ('\t"Hot reactor" -> Outlet [label="m = 3 kg/s" ' - 'color=green]\n'), + 'color=green samehead="Hot reactor-Outlet" ' + 'sametail="Hot reactor-Outlet"]\n'), ('\t"Cold reactor" -> Outlet [label="m = 2 kg/s" ' - 'color=green]\n'), + 'color=green samehead="Cold reactor-Outlet" ' + 'sametail="Cold reactor-Outlet"]\n'), ('\t"Hot reactor" -> "Cold reactor" [label="q = 4e+03 W" ' - 'color=orange style=dashed]\n'), + 'color=orange samehead="Hot reactor-Cold reactor" ' + 'sametail="Hot reactor-Cold reactor" style=dashed]\n'), ('\t"Hot inlet" -> "Hot reactor" [label="m = 3 kg/s" ' - 'color=green]\n')] + 'color=green samehead="Hot inlet-Hot reactor" ' + 'sametail="Hot inlet-Hot reactor"]\n')] # use sets because order can be random self.assertSetEqual(set(dot.body), set(expected))