|
|
@@ -6,6 +6,7 @@ from pypdevs.DEVS import AtomicDEVS, CoupledDEVS
|
|
|
from pypdevs.infinity import INFINITY
|
|
|
from pypdevs.simulator import Simulator
|
|
|
|
|
|
+from graphviz import Source
|
|
|
|
|
|
class DelayedAtomic(AtomicDEVS):
|
|
|
def __init__(self, name: str, int_delay: float, ext_delay: float, add_out_port: bool = False, prep_time=0.0, mode:str = ""):
|
|
|
@@ -172,6 +173,35 @@ class DEVStoneWrapper(CoupledDEVS, ABC):
|
|
|
result.append(coupled)
|
|
|
return "".join(result)
|
|
|
|
|
|
+ def dot(self, output: bool=False) -> None:
|
|
|
+ result = ("\n\ndigraph {\n\tlayout=dot;"
|
|
|
+ "\n\tnodesep=0.25;"
|
|
|
+ "\n\tranksep=0.2;"
|
|
|
+ "\n\trankdir=LR;"
|
|
|
+ "\n\tsplines=ortho;\n")
|
|
|
+ result += f"\tCoupled_{self.depth}[shape=box, label=\"C_{self.depth}\"];\n"
|
|
|
+ coupled = self.component_set[0]
|
|
|
+ result += f"\t{coupled.name}[shape=box, label=\"{'C_' + '_'.join(coupled.name.split('_')[1:3])}\"];\n"
|
|
|
+
|
|
|
+ for model in self.models:
|
|
|
+ result += f"\t{model.name}[shape=ellipse, label=\"{'A_' + '_'.join(model.name.split('_')[1:3])}\"];\n"
|
|
|
+
|
|
|
+ for connections in self.i_in.outline:
|
|
|
+ result += f"\tCoupled_{self.depth}:i_in -> {str(connections).split('.')[2]}:{connections.name};\n"
|
|
|
+
|
|
|
+ for model in self.models:
|
|
|
+ if not hasattr(model, "o_out"):
|
|
|
+ continue
|
|
|
+ for connections in model.o_out.outline:
|
|
|
+ result += f"\t{model.name}:o_out -> {str(connections).split('.')[2]}:{connections.name};\n"
|
|
|
+ result += "}\n"
|
|
|
+
|
|
|
+ src = Source(result)
|
|
|
+ src.view(filename=f'graph_coupled_{self.depth}') # Opens in default PDF viewer
|
|
|
+
|
|
|
+ if output:
|
|
|
+ print(result)
|
|
|
+
|
|
|
@abstractmethod
|
|
|
def gen_coupled(self):
|
|
|
""" :return a coupled method with i_in and o_out ports"""
|
|
|
@@ -368,7 +398,7 @@ class HI2LI(DEVStoneWrapper):
|
|
|
prep_time=self.prep_time, stats=self.stats)
|
|
|
|
|
|
|
|
|
-class Fertilizer(AtomicDEVS):
|
|
|
+class DynamicGenerator(AtomicDEVS):
|
|
|
def __init__(self, name: str, period: float = 1.0, repeat: int = 1):
|
|
|
super().__init__(name)
|
|
|
self.period = period
|
|
|
@@ -413,7 +443,7 @@ class dLI(DEVStoneWrapper):
|
|
|
assert isinstance(self.component_set[idx], AtomicDEVS)
|
|
|
self.connectPorts(self.i_in, self.component_set[idx].i_in)
|
|
|
|
|
|
- self.generator = self.addSubModel(Fertilizer(self.name + "_gen", repeat=self.max_gen))
|
|
|
+ self.generator = self.addSubModel(DynamicGenerator(self.name + "_gen", repeat=self.max_gen))
|
|
|
|
|
|
def gen_coupled(self):
|
|
|
return dLI("Coupled_%d" % (self.depth - 1), self.depth - 1, self.width, self.int_delay, self.ext_delay,
|
|
|
@@ -422,7 +452,6 @@ class dLI(DEVStoneWrapper):
|
|
|
def modelTransition(self, state):
|
|
|
if state.get("generate", True) and self.depth > 1:
|
|
|
# print("model", self.name)
|
|
|
- self.connectPorts(self.i_in, self.component_set[0].i_in)
|
|
|
name = "Atomic_%d_%d" % (self.depth - 1, self.width) if self.depth > 1 else "Atomic_0_%d" % self.width
|
|
|
if self.stats:
|
|
|
new_atom = DelayedAtomicStats(name, self.int_delay, self.ext_delay,
|
|
|
@@ -458,7 +487,7 @@ class dHI(DEVStoneWrapper):
|
|
|
self.connectPorts(self.component_set[idx].o_out, self.component_set[idx + 1].i_in)
|
|
|
self.connectPorts(self.i_in, self.component_set[idx].i_in)
|
|
|
|
|
|
- self.generator = self.addSubModel(Fertilizer(self.name + "_gen", repeat=self.max_gen))
|
|
|
+ self.generator = self.addSubModel(DynamicGenerator(self.name + "_gen", repeat=self.max_gen))
|
|
|
|
|
|
def gen_coupled(self):
|
|
|
return dHI("Coupled_%d" % (self.depth - 1), self.depth - 1, self.width, self.int_delay, self.ext_delay,
|
|
|
@@ -474,8 +503,8 @@ class dHI(DEVStoneWrapper):
|
|
|
new_atom = DelayedAtomic(name, self.int_delay, self.ext_delay,
|
|
|
add_out_port=self.add_atomic_out_ports, prep_time=self.prep_time, mode="LI-Dynamic")
|
|
|
|
|
|
- last = self.component_set[-2]
|
|
|
-
|
|
|
+ last = self.models[-1]
|
|
|
+ print("last: ", last.name)
|
|
|
self.models.append(self.addSubModel(new_atom))
|
|
|
self.connectPorts(self.i_in, new_atom.i_in)
|
|
|
if isinstance(last, AtomicDEVS) and hasattr(last, "o_out"):
|