def do_switch(self): """ Checks if is an event time and perform switch if true. Time is approximated with a tolerance of 1e-8. """ ret = False system = self.system # refresh switch times if enabled if self.config.refresh_event: system.store_switch_times(system.exist.pflow_tds) # if not all events have been processed if self._switch_idx < system.n_switches: # if the current time is close enough to the next event time if np.equal(system.dae.t, system.switch_times[self._switch_idx]): # `_last_switch_t` is used by the Jacobian updater self._last_switch_t = system.switch_times[self._switch_idx] # only call `switch_action` on the models that defined the time system.switch_action(system.switch_dict[self._last_switch_t]) # progress `_switch_idx` to avoid calling the same event if time gets stuck self._switch_idx += 1 system.vars_to_models() ret = True # if a `custom_event` flag is set (without a specific callback) if self.custom_event is True: system.switch_action(system.exist.pflow_tds) self._last_switch_t = system.dae.t.tolist() system.vars_to_models() self.custom_event = False ret = True # check system connectivity after a switching if ret is True and self.config.check_conn == 1: system.connectivity(info=False) return ret
def is_time(self, dae_t): """ Element-wise check if the DAE time is the same as the parameter value. The current implementation uses `np.equal`. Parameters ---------- dae_t : float Current simulation time Returns ------- np.ndarray The array containing the truth value of if the DAE time is close to the parameter value. Notes ----- The previous implementation with `np.isclose` with default `rtol=1e-5` mistakes the immediate pre- and post-event time as in-event when simulation time is greater than 10. """ return np.equal(dae_t, self.v)