Each World has its corresponding Simulator.
In [1]:
from ecell4.core import *
from ecell4.gillespie import GillespieWorld as world_type, GillespieSimulator as simulator_type
# from ecell4.ode import ODEWorld as world_type, ODESimulator as simulator_type
# from ecell4.lattice import LatticeWorld as world_type, LatticeSimulator as simulator_type
# from ecell4.meso import MesoscopicWorld as world_type, MesoscopicSimulator as simulator_type
# from ecell4.bd import BDWorld as world_type, BDSimulator as simulator_type
# from ecell4.egfrd import EGFRDWorld as world_type, EGFRDSimulator as simulator_type
Simulator needs a Model and World at the instantiation.
In [2]:
m = NetworkModel()
m.add_species_attribute(Species("A", "0.0025", "1"))
m.add_reaction_rule(create_degradation_reaction_rule(Species("A"), 0.693 / 1))
w = world_type(Real3(1, 1, 1))
w.bind_to(m)
w.add_molecules(Species("A"), 60)
sim = simulator_type(m, w)
sim.set_dt(0.01) #XXX: Optional
A Simulator has getters for a simulation time, a step interval, and the next-event time. In principle, a Simulator returns the World's time as its simulation time, and does a sum of the current time and a step interval as the next-event time.
In [3]:
print(sim.num_steps())
print(sim.t(), w.t())
print(sim.next_time(), sim.t() + sim.dt())
A Simulator can return the connected model and world. They are not copies, but the shared objects.
In [4]:
print(sim.model(), sim.world())
If you change a World after connecting it to a Simulator, you have to call initialize()
manually before step()
. The call will update the internal state of the Simulator.
In [5]:
sim.world().add_molecules(Species("A"), 60) # w.add_molecules(Species("A"), 60)
sim.initialize()
In [6]:
# w.save('test.h5')
Simulator has two types of step
functions. First, with no argument, step()
increments the time until next_time()
.
In [7]:
print("%.3e %.3e" % (sim.t(), sim.next_time()))
sim.step()
print("%.3e %.3e" % (sim.t(), sim.next_time()))
With an argument upto
, if upto
is later than next_time()
, step(upto)
increments the time upto the next_time()
and returns True
. Otherwise, it increments the time for upto
and returns False
. (If the current time t()
is less than upto
, it does nothing and returns False
.)
In [8]:
print("%.3e %.3e" % (sim.t(), sim.next_time()))
print(sim.step(0.1))
print("%.3e %.3e" % (sim.t(), sim.next_time()))
For a discrete-step simulation, the main loop should be written like:
In [9]:
# w.load('test.h5')
sim.initialize()
In [10]:
next_time, dt = 0.0, 1e-2
for _ in range(5):
while sim.step(next_time): pass
next_time += dt
print("%.3e %.3e %d %g" % (sim.t(), sim.dt(), sim.num_steps(), w.num_molecules(Species("A"))))
In [ ]: