Esempio n. 1
0
# type 1 = A-
# type 2 = H+

N0 = 50  # number of titratable units
K_diss = 0.0088

for i in range(N0):
    system.part.add(id=i, pos=np.random.random(3) * system.box_l, type=1)
for i in range(N0, 2 * N0):
    system.part.add(id=i, pos=np.random.random(3) * system.box_l, type=2)

RE = None
if (mode == "reaction_ensemble"):
    RE = reaction_ensemble.ReactionEnsemble(temperature=1, exclusion_radius=1)
elif (mode == "constant_pH_ensemble"):
    RE = reaction_ensemble.ConstantpHEnsemble(temperature=1,
                                              exclusion_radius=1)
    RE.constant_pH = 2
RE.add_reaction(gamma=K_diss,
                reactant_types=[0],
                reactant_coefficients=[1],
                product_types=[1, 2],
                product_coefficients=[1, 1],
                default_charges={
                    0: 0,
                    1: -1,
                    2: +1
                })
print(RE.get_status())
system.setup_type_map([0, 1, 2])

for i in range(10000):
Esempio n. 2
0
class ReactionEnsembleTest(ut.TestCase):

    """Test the core implementation of the reaction ensemble."""

    N0 = 40
    c0 = 0.00028
    type_HA = 0
    type_A = 1
    type_H = 5
    temperature = 1.0
    # avoid extreme regions in the titration curve e.g. via the choice
    # choose target alpha not too far from 0.5 to get good statistics in a
    # small number of steps
    pKa_minus_pH = -0.2
    pH = 2
    pKa = pKa_minus_pH + pH
    Ka = 10**(-pKa)
    box_l = (N0 / c0)**(1.0 / 3.0)
    system = espressomd.System(box_l=[box_l, box_l, box_l])
    np.random.seed(69)  # make reaction code fully deterministic
    system.cell_system.skin = 0.4
    system.time_step = 0.01
    RE = reaction_ensemble.ConstantpHEnsemble(
        temperature=1.0,
        exclusion_radius=1, seed=44)

    @classmethod
    def setUpClass(cls):
        for i in range(0, 2 * cls.N0, 2):
            cls.system.part.add(id=i, pos=np.random.random(3) *
                                cls.system.box_l, type=cls.type_A)
            cls.system.part.add(id=i + 1, pos=np.random.random(3) *
                                cls.system.box_l, type=cls.type_H)

        cls.RE.add_reaction(
            gamma=cls.Ka, reactant_types=[cls.type_HA],
            reactant_coefficients=[1], product_types=[cls.type_A, cls.type_H],
            product_coefficients=[1, 1],
            default_charges={cls.type_HA: 0, cls.type_A: -1, cls.type_H: +1})
        cls.RE.constant_pH = cls.pH

    @classmethod
    def ideal_alpha(cls, pH):
        return 1.0 / (1 + 10**(cls.pKa - pH))

    def test_ideal_titration_curve(self):
        N0 = ReactionEnsembleTest.N0
        type_A = ReactionEnsembleTest.type_A
        type_H = ReactionEnsembleTest.type_H
        type_HA = ReactionEnsembleTest.type_HA
        system = ReactionEnsembleTest.system
        RE = ReactionEnsembleTest.RE
        # chemical warmup - get close to chemical equilibrium before we start
        # sampling
        RE.reaction(40 * N0)

        average_NH = 0.0
        average_NHA = 0.0
        average_NA = 0.0
        num_samples = 1000
        for _ in range(num_samples):
            RE.reaction(10)
            average_NH += system.number_of_particles(type=type_H)
            average_NHA += system.number_of_particles(type=type_HA)
            average_NA += system.number_of_particles(type=type_A)
        average_NH /= float(num_samples)
        average_NA /= float(num_samples)
        average_NHA /= float(num_samples)
        average_alpha = average_NA / float(N0)
        # note you cannot calculate the pH via -log10(<NH>/volume) in the
        # constant pH ensemble, since the volume is totally arbitrary and does
        # not influence the average number of protons
        pH = ReactionEnsembleTest.pH
        pKa = ReactionEnsembleTest.pKa
        target_alpha = ReactionEnsembleTest.ideal_alpha(pH)
        rel_error_alpha = abs(
            average_alpha - target_alpha) / target_alpha
        # relative error
        self.assertLess(
            rel_error_alpha,
            0.015,
            msg="\nDeviation from ideal titration curve is too big for the given input parameters.\n"
            + "  pH: " + str(pH)
            + "  pKa: " + str(pKa)
            + "  average_NH: " + str(average_NH)
            + "  average_NA: " + str(average_NA)
            + "  average_NHA:" + str(average_NHA)
            + "  average alpha: " + str(average_alpha)
            + "  target_alpha: " + str(target_alpha)
            + "  rel_error: " + str(rel_error_alpha)
        )