Constant concentration
This will demonstrate how to achieve a constant concentration $[S]_\mathrm{eq}$ of S particles, where the value of $[S]_\mathrm{eq}$ can be roughly adjusted under some approximations.
Define reactions of substrate with factory particles F
$$F \rightleftharpoons F + S$$with forward propensity (intrinsic rate constant) $f_+$ and backward propensity $f_-$. The according macroscopic rates of these processes would be $k_+$ and $k_-$. In equilibrium under assumption of the law of mass action [1]:
$$ K = \frac{[F]_\mathrm{eq}[S]_\mathrm{eq}}{[F]_\mathrm{eq}} = [S]_\mathrm{eq} $$The equilibrium constant also relates $k_+$ and $k_-$, which are functions of the propensities $f_+$ and $f_-$ respectively:
$$ K = \frac{k_+(f_+)}{k_-(f_-)} $$Since the "$+$" reaction is unimolecular we have $k_+=f_+$. The "$-$" reaction depends on the choice of reaction model. Here we choose the Doi model. Furthermore in equilibrium the effective "$-$" rate does not depend on diffusion and we can formulate it for a dilute system(well described by an isolated pair, see [2]) and in the absence of potentials yielding $k_-= f_- V_R$. The reaction volume is spherical $V_R=\frac{4}{3}\pi R^3$ with reaction radius $R$. Combining the equations above gives the constant concentration
$$ [S]_\mathrm{eq} = \frac{f_+}{f_- V_R} $$- [1] Atkins, Peter; de Paula, Julio: Atkins’ physical chemistry, Oxford University Press, 2006
- [2] Fröhner, Christoph; Noé, Frank: Reversible interacting-particle reaction dynamics. The Journal of Physical Chemistry B, 122.49 (2018): 11240-11250.
import os
import numpy as np
import matplotlib.pyplot as plt
import readdy
print(readdy.__version__)
factory_minus_rate = 0.08
factory_plus_rate = 0.1
factory_reaction_radius = 0.5
factory_reaction_volume = 4./3. * np.pi * factory_reaction_radius**3
concentration = factory_plus_rate / factory_minus_rate / factory_reaction_volume
print(concentration)
system = readdy.ReactionDiffusionSystem(
box_size=[10.,10.,10.],
periodic_boundary_conditions=[True, True, True],
unit_system=None
)
system.add_species("S", 1.)
system.add_species("F", 1.)
system.reactions.add_fusion(
"factory-fusion", "F", "S", "F", factory_minus_rate,
factory_reaction_radius, weight1=0., weight2=1.)
system.reactions.add_fission(
"factory-fission", "F", "F", "S", factory_plus_rate,
factory_reaction_radius, weight1=0., weight2=1.)
simulation = system.simulation("SingleCPU", reaction_handler="UncontrolledApproximation")
simulation.observe.number_of_particles(1, types=["S", "F"])
simulation.output_file = "const_concentration.h5"
if os.path.exists(simulation.output_file):
os.remove(simulation.output_file)
simulation.add_particles("F", np.random.uniform(size=(1000,3)) * 10. - 5.)
timestep = 5e-3
simulation.run(50000, timestep)
traj = readdy.Trajectory(simulation.output_file)
time, counts = traj.read_observable_number_of_particles()
volume = 10**3
plt.plot(time * timestep, counts[:,0]/volume, label=r"$[S]$")
plt.hlines(concentration, *plt.xlim(), label=r"theoretical value $[S]_\mathrm{eq}$")
plt.legend(loc="lower right")
plt.xlabel(r"Time in $[\mathrm{time}]$")
plt.ylabel(r"Concentration in $[\mathrm{length}]^{-3}$")
plt.show()