Skip to content

Commit

Permalink
handle potentially superposed events in the Deterministic Simulation …
Browse files Browse the repository at this point in the history
…Algorithm (DSA)
  • Loading branch information
artgoldberg committed Jul 28, 2020
1 parent 3f2ac1a commit bb163e9
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 6 deletions.
Binary file not shown.
6 changes: 3 additions & 3 deletions tests/submodels/test_dynamic_submodel.py
Expand Up @@ -245,7 +245,7 @@ def test_deterministic_simulation_algorithm_submodel_statics(self):
reaction_indices.add(event_record[reaction_idx])
self.assertEqual(reaction_indices, set([str(i) for i in range(len(self.dsa_submodel.reactions))]))

# test handle_ExecuteDsaReaction_msg(): execute next reaction
# test handle_ExecuteDsaReaction_msgs(): execute next reaction
# reaction_3_forward has the highest reaction rate
events = self.simulation_engine.event_queue.next_events()
self.assertEqual(len(events), 1)
Expand All @@ -261,7 +261,7 @@ def test_deterministic_simulation_algorithm_submodel_statics(self):
expected_pop_changes = dict(zip(species, [-1, -2, +1]))
# set time of dsa_submodel to time of the event
self.dsa_submodel.time = event.event_time
self.dsa_submodel.handle_ExecuteDsaReaction_msg(event)
self.dsa_submodel.handle_ExecuteDsaReaction_msgs(event)
for s_id, expected_pop_change in expected_pop_changes.items():
self.assertEqual(pops_before[s_id] + expected_pop_changes[s_id],
populations.read_one(event.event_time, s_id))
Expand All @@ -271,7 +271,7 @@ def test_deterministic_simulation_algorithm_submodel_statics(self):
pop = populations.read_one(event.event_time, species_id)
populations.adjust_discretely(event.event_time, {species_id: -pop})
with self.assertRaises(DynamicMultialgorithmError):
self.dsa_submodel.handle_ExecuteDsaReaction_msg(event)
self.dsa_submodel.handle_ExecuteDsaReaction_msgs(event)

# test DsaSubmodel options
expected = dict(a=1)
Expand Down
24 changes: 22 additions & 2 deletions wc_sim/submodels/testing/deterministic_simulation_algorithm.py
Expand Up @@ -45,7 +45,7 @@ class DsaSubmodel(DynamicSubmodel):
# at any time instant, process messages in this order
MESSAGE_TYPES_BY_PRIORITY = [ExecuteDsaReaction]

event_handlers = [(ExecuteDsaReaction, 'handle_ExecuteDsaReaction_msg')]
event_handlers = [(ExecuteDsaReaction, 'handle_ExecuteDsaReaction_msgs')]

def __init__(self, id, dynamic_model, reactions, species, dynamic_compartments,
local_species_population, options=None):
Expand Down Expand Up @@ -89,7 +89,7 @@ def send_initial_events(self):
reaction_index = self.reaction_table[reaction.id]
self.schedule_ExecuteDsaReaction(dt, reaction_index)

def handle_ExecuteDsaReaction_msg(self, event):
def execute_dsa_reaction(self, event):
""" Handle a simulation event that contains an :obj:`ExecuteDsaReaction` message
Args:
Expand All @@ -108,6 +108,26 @@ def handle_ExecuteDsaReaction_msg(self, event):
self.execute_reaction(reaction)
self.schedule_next_reaction_execution(reaction)

def handle_ExecuteDsaReaction_msgs(self, event_or_events):
""" Handle one or more simulation event(s) that contain an :obj:`ExecuteDsaReaction` message
Reactions with the same rates will occur simultaneously and be superposed.
Args:
event_or_events (:obj:`obj`): an :obj:`Event` to execute or a list of :obj:`Event` to execute
Raises:
:obj:`DynamicMultialgorithmError:` if the reaction does not have sufficient reactants to execute
"""
# handle either superposed events or a single event
if isinstance(event_or_events, list):
for event in event_or_events:
self.execute_dsa_reaction(event)
else:
event = event_or_events
self.execute_dsa_reaction(event)


def schedule_ExecuteDsaReaction(self, dt, reaction_index):
""" Schedule an :obj:`ExecuteDsaReaction` event.
Expand Down
3 changes: 2 additions & 1 deletion wc_sim/testing/utils.py
Expand Up @@ -302,7 +302,8 @@ def verify_independently_solved_model(test_case, model_filename, results_dir):
checkpoint_period = model.parameters.get_one(id='checkpoint_period').value
args = dict(results_dir=results_dir,
checkpoint_period=checkpoint_period,
ode_time_step=1.)
ode_time_step=1.,
progress_bar=True)
simulation = Simulation(model)
start_time = time.perf_counter()
results_dir = simulation.run(time_max=time_max, **args).results_dir
Expand Down

0 comments on commit bb163e9

Please sign in to comment.