|
|
@@ -101,7 +101,7 @@ class DelayedAtomicStats(DelayedAtomic):
|
|
|
class DEVStoneWrapper(CoupledDEVS, ABC):
|
|
|
|
|
|
def __init__(self, name: str, depth: int, width: int, int_delay: float, ext_delay: float,
|
|
|
- add_atomic_out_ports: bool = False, prep_time=0, stats=False, mode: str = ""):
|
|
|
+ add_atomic_out_ports: bool = False, prep_time=0, stats=False, mode: str = "", dynamic: bool = False):
|
|
|
super().__init__(name)
|
|
|
|
|
|
self.depth = depth
|
|
|
@@ -143,6 +143,9 @@ class DEVStoneWrapper(CoupledDEVS, ABC):
|
|
|
self.connectPorts(self.i_in, coupled.i_in)
|
|
|
self.connectPorts(coupled.o_out, self.o_out)
|
|
|
|
|
|
+ if dynamic:
|
|
|
+ return # width will be dynamically generated
|
|
|
+
|
|
|
# + (idx * 1e-6) to address too many transitions at the same time
|
|
|
# => problem for Classic DEVS only it seems
|
|
|
for idx in range(width - 1):
|
|
|
@@ -173,7 +176,7 @@ class DEVStoneWrapper(CoupledDEVS, ABC):
|
|
|
result.append(coupled)
|
|
|
return "".join(result)
|
|
|
|
|
|
- def dot(self, output: bool=False) -> None:
|
|
|
+ def dot(self, name) -> None:
|
|
|
result = ("\n\ndigraph {\n\tlayout=dot;"
|
|
|
"\n\tnodesep=0.25;"
|
|
|
"\n\tranksep=0.2;"
|
|
|
@@ -197,10 +200,7 @@ class DEVStoneWrapper(CoupledDEVS, ABC):
|
|
|
result += "}\n"
|
|
|
|
|
|
src = Source(result)
|
|
|
- src.view(filename=f'graph_coupled_{self.depth}') # Opens in default PDF viewer
|
|
|
-
|
|
|
- if output:
|
|
|
- print(result)
|
|
|
+ src.view(filename=f'{name}_{self.depth}')
|
|
|
|
|
|
@abstractmethod
|
|
|
def gen_coupled(self):
|
|
|
@@ -436,13 +436,14 @@ class dLI(DEVStoneWrapper):
|
|
|
"""
|
|
|
def __init__(self, name: str, depth: int, width: int, int_delay: float, ext_delay: float, prep_time=0, stats=False):
|
|
|
super().__init__(name, depth, width, int_delay, ext_delay, add_atomic_out_ports=False, prep_time=prep_time,
|
|
|
- stats=stats, mode="LI-Dynamic")
|
|
|
+ stats=stats, mode="LI-Dynamic", dynamic=True)
|
|
|
|
|
|
- self.max_gen = 5
|
|
|
for idx in range(1, len(self.component_set)):
|
|
|
assert isinstance(self.component_set[idx], AtomicDEVS)
|
|
|
self.connectPorts(self.i_in, self.component_set[idx].i_in)
|
|
|
|
|
|
+ self.current_width = 1
|
|
|
+ self.max_gen = width - 1 # dynamically generate atomic components until width is reached excludes the coupled model
|
|
|
self.generator = self.addSubModel(DynamicGenerator(self.name + "_gen", repeat=self.max_gen))
|
|
|
|
|
|
def gen_coupled(self):
|
|
|
@@ -451,8 +452,7 @@ class dLI(DEVStoneWrapper):
|
|
|
|
|
|
def modelTransition(self, state):
|
|
|
if state.get("generate", True) and self.depth > 1:
|
|
|
- # print("model", self.name)
|
|
|
- name = "Atomic_%d_%d" % (self.depth - 1, self.width) if self.depth > 1 else "Atomic_0_%d" % self.width
|
|
|
+ name = "Atomic_%d_%d" % (self.depth - 1, self.current_width) if self.depth > 1 else "Atomic_0_%d" % self.current_width
|
|
|
if self.stats:
|
|
|
new_atom = DelayedAtomicStats(name, self.int_delay, self.ext_delay,
|
|
|
add_out_port=self.add_atomic_out_ports, prep_time=self.prep_time, mode="LI-Dynamic")
|
|
|
@@ -463,7 +463,7 @@ class dLI(DEVStoneWrapper):
|
|
|
self.models.append(self.addSubModel(new_atom))
|
|
|
self.connectPorts(self.i_in, new_atom.i_in)
|
|
|
|
|
|
- self.width += 1
|
|
|
+ self.current_width += 1
|
|
|
# print(f"{self.name}: added {new_atom.name} (width is now {self.width})")
|
|
|
return False
|
|
|
return False
|
|
|
@@ -475,9 +475,8 @@ class dHI(DEVStoneWrapper):
|
|
|
"""
|
|
|
def __init__(self, name: str, depth: int, width: int, int_delay: float, ext_delay: float, prep_time=0, stats=False):
|
|
|
super().__init__(name, depth, width, int_delay, ext_delay, add_atomic_out_ports=True, prep_time=prep_time,
|
|
|
- stats=stats, mode="HI-Dynamic")
|
|
|
+ stats=stats, mode="HI-Dynamic", dynamic=True)
|
|
|
|
|
|
- self.max_gen = 5
|
|
|
if len(self.component_set) > 1:
|
|
|
assert isinstance(self.component_set[-1], AtomicDEVS)
|
|
|
self.connectPorts(self.i_in, self.component_set[-1].i_in)
|
|
|
@@ -487,6 +486,8 @@ 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.current_width = 1
|
|
|
+ self.max_gen = width - 1 # dynamically generate atomic components until width is reached excludes the coupled model
|
|
|
self.generator = self.addSubModel(DynamicGenerator(self.name + "_gen", repeat=self.max_gen))
|
|
|
|
|
|
def gen_coupled(self):
|
|
|
@@ -495,7 +496,7 @@ class dHI(DEVStoneWrapper):
|
|
|
|
|
|
def modelTransition(self, state):
|
|
|
if state.get("generate", True) and self.depth > 1:
|
|
|
- name = "Atomic_%d_%d" % (self.depth - 1, self.width) if self.depth > 1 else "Atomic_0_%d" % self.width
|
|
|
+ name = "Atomic_%d_%d" % (self.depth - 1, self.current_width) if self.depth > 1 else "Atomic_0_%d" % self.current_width
|
|
|
if self.stats:
|
|
|
new_atom = DelayedAtomicStats(name, self.int_delay, self.ext_delay,
|
|
|
add_out_port=self.add_atomic_out_ports, prep_time=self.prep_time, mode="LI-Dynamic")
|
|
|
@@ -503,15 +504,15 @@ 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.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"):
|
|
|
- self.connectPorts(last.o_out, new_atom.i_in)
|
|
|
+ if len(self.models) > 1:
|
|
|
+ prev = self.models[-2]
|
|
|
+ print("last: ", prev.name)
|
|
|
+ if isinstance(prev, AtomicDEVS) and hasattr(prev, "o_out"):
|
|
|
+ self.connectPorts(prev.o_out, new_atom.i_in)
|
|
|
|
|
|
- self.width += 1
|
|
|
- # print(f"{self.name}: added {new_atom.name} (width is now {self.width})")
|
|
|
+ self.current_width += 1
|
|
|
return False
|
|
|
return False
|
|
|
|