def __init__(self, config): super(SimEnvironment, self).__init__() #: The configuration dictionary. self.config = config #: The pseudo-random number generator; an instance of #: :class:`random.Random`. self.rand = random.Random() seed = config.setdefault('sim.seed', None) if six.PY3: self.rand.seed(seed, version=1) else: self.rand.seed(seed) timescale_str = self.config.setdefault('sim.timescale', '1 s') #: Simulation timescale ``(magnitude, units)`` tuple. The current #: simulation time is ``now * timescale``. self.timescale = parse_time(timescale_str) duration = config.setdefault('sim.duration', '0 s') #: The intended simulation duration, in units of :attr:`timescale`. self.duration = scale_time(parse_time(duration), self.timescale) #: The simulation runs "until" this event. By default, this is the #: configured "sim.duration", but may be overridden by subclasses. self.until = self.duration #: From 'meta.sim.index', the simulation's index when running multiple #: related simulations or `None` for a standalone simulation. self.sim_index = config.get('meta.sim.index') #: :class:`TraceManager` instance. self.tracemgr = TraceManager(self)
def time(self, t=None, unit='s'): """The current simulation time scaled to specified unit. :param float t: Time in simulation units. Default is :attr:`now`. :param str unit: Unit of time to scale to. Default is 's' (seconds). :returns: Simulation time scaled to to `unit`. """ target_scale = parse_time(unit) ts_mag, ts_unit = self.timescale sim_time = ((self.now if t is None else t) * ts_mag, ts_unit) return scale_time(sim_time, target_scale)
def __init__(self, config): super(SimEnvironment, self).__init__() #: The configuration dictionary. self.config = config #: The pseudo-random number generator; an instance of #: :class:`random.Random`. self.rand = random.Random() if six.PY3: self.rand.seed(config['sim.seed'], version=1) else: self.rand.seed(config['sim.seed']) #: Simulation timescale `(magnitude, units)` tuple. The current #: simulation time is `env.now * env.timescale`. self.timescale = parse_time(self.config['sim.timescale']) #: The intended simulation duration, in units of `timescale`. self.duration = scale_time(parse_time(config['sim.duration']), self.timescale)
def simulate(config, top_type, env_type=SimEnvironment): """Initialize, elaborate, and run a simulation. :param dict config: Configuration dictionary for the simulation. :param top_type: The model's top-level Component subclass. :param env_type: :class:`SimEnvironment` subclass. :returns: Dictionary containing the model-specific results of the simulation. """ env = env_type(config) result_filename = config.get('sim.result.file') result = {'config': config} t0 = timeit.default_timer() with _Workspace(config): top_type.pre_init(env) with TraceManager(env) as tracemgr: try: with _progress_notification(env): top = top_type(parent=None, env=env, tracemgr=tracemgr) top.elaborate() env.run(until=env.duration) top.post_simulate() except Exception as e: result['sim.exception'] = repr(e) raise else: result['sim.exception'] = None now_ts = env.now, env.timescale[1] result['sim.time'] = scale_time(now_ts, (1, 's')) top.get_result(result) finally: result['sim.runtime'] = timeit.default_timer() - t0 if result_filename is not None: with open(result_filename, 'w') as result_file: yaml.dump(result, stream=result_file) return result
def _get_interval_period_s(config): period_str = config.setdefault('sim.progress.update_period', '1 s') return scale_time(parse_time(period_str), (1, 's'))
def test_scale_time(input_t, input_tscale, expected): scaled = scale_time(input_t, input_tscale) assert expected == scaled assert isinstance(scaled, type(expected))
def _get_interval_period_s(config: ConfigDict) -> Union[int, float]: period_str: str = config.setdefault('sim.progress.update_period', '1 s') return scale_time(parse_time(period_str), (1, 's'))