|
|
@@ -8,6 +8,7 @@ from .loopsolvers.linearsolver import LinearSolver
|
|
|
from .realtime.threadingBackend import ThreadingBackend, Platform
|
|
|
from .scheduling import TopologicalScheduler
|
|
|
from .tracers import Tracers
|
|
|
+from .state_events.locators import RegulaFalsiStateEventLocator
|
|
|
|
|
|
_TQDM_FOUND = True
|
|
|
try:
|
|
|
@@ -22,7 +23,7 @@ class Simulator:
|
|
|
This class implements the semantics of CBDs.
|
|
|
|
|
|
Args:
|
|
|
- model (CBD): A :class:`CBD` model to simulate.
|
|
|
+ model (CBD.Core.CBD): A :class:`CBD` model to simulate.
|
|
|
|
|
|
:Defaults:
|
|
|
The following properties further define the internal mechanisms of
|
|
|
@@ -61,7 +62,10 @@ class Simulator:
|
|
|
- :func:`setProgressBar`
|
|
|
* - strong component system solver
|
|
|
- :class:`CBD.linearsolver.LinearSolver`
|
|
|
- - N/A
|
|
|
+ - :func:`setAlgebraicLoopSolver`
|
|
|
+ * - state event locator
|
|
|
+ - :class:`CBD.state_events.locators.RegulaFalsiStateEventLocator`
|
|
|
+ - :func:`setStateEventLocator`
|
|
|
"""
|
|
|
def __init__(self, model):
|
|
|
self.model = model
|
|
|
@@ -110,6 +114,10 @@ class Simulator:
|
|
|
"poststep": [],
|
|
|
"clock_update": []
|
|
|
}
|
|
|
+
|
|
|
+ self.__state_events = []
|
|
|
+ self.__stel = None
|
|
|
+ self.setStateEventLocator(RegulaFalsiStateEventLocator())
|
|
|
|
|
|
# TODO: make this variable, given more solver implementations
|
|
|
# self.__solver = SympySolver(self.__logger)
|
|
|
@@ -251,8 +259,7 @@ class Simulator:
|
|
|
- :func:`setDeltaT`
|
|
|
- :class:`CBD.lib.std.Clock`
|
|
|
"""
|
|
|
- clock = self.getClock()
|
|
|
- return clock.getInputSignal(input_port='h').value
|
|
|
+ return self.getClock().getDeltaT()
|
|
|
|
|
|
def setDeltaT(self, delta_t):
|
|
|
"""
|
|
|
@@ -299,6 +306,25 @@ class Simulator:
|
|
|
"""
|
|
|
self.__solver = solver
|
|
|
|
|
|
+ def setStateEventLocator(self, stel):
|
|
|
+ """
|
|
|
+ Sets the state event locator to use when level crossings occur.
|
|
|
+
|
|
|
+ Args:
|
|
|
+ stel (CBD.state_events.locators.StateEventLocator): The new state event to use.
|
|
|
+ """
|
|
|
+ self.__stel = stel
|
|
|
+ self.__stel.setSimulator(self)
|
|
|
+
|
|
|
+ def registerStateEvent(self, event):
|
|
|
+ """
|
|
|
+ Registers a state event to the current simulator.
|
|
|
+
|
|
|
+ Args:
|
|
|
+ event (CBD.state_events.StateEvent): The event to register.
|
|
|
+ """
|
|
|
+ self.__state_events.append(event)
|
|
|
+
|
|
|
def setBlockRate(self, block_path, rate):
|
|
|
"""
|
|
|
Sets the rate for a specific block. Independent of the stepsize, the
|
|
|
@@ -496,7 +522,21 @@ class Simulator:
|
|
|
self.__sim_data[1] = self.__scheduler.obtain(self.__sim_data[0], curIt, self.getTime())
|
|
|
self.__computeBlocks(self.__sim_data[1], self.__sim_data[0], self.__sim_data[2])
|
|
|
self.__sim_data[2] += 1
|
|
|
- # TODO: LCC
|
|
|
+ # TODO: multiple LCC
|
|
|
+ for event in self.__state_events:
|
|
|
+ if not event.fired and self.__stel.detect_signal(event.output_name, event.level, event.direction):
|
|
|
+ event.fired = True
|
|
|
+ t = self.__stel.run(event.output_name, event.level, event.direction)
|
|
|
+ event.event(t, self.model)
|
|
|
+
|
|
|
+ # Reset the model
|
|
|
+ self.model._rewind()
|
|
|
+ self.model.clearSignals()
|
|
|
+ self.model.getClock().setStartTime(t)
|
|
|
+ self.__sim_data[0] = None
|
|
|
+ self.__sim_data[2] = 0
|
|
|
+ elif event.fired:
|
|
|
+ event.fired = False
|
|
|
self.signal("poststep")
|
|
|
|
|
|
def _lcc_compute(self):
|