class MagnetostaticsInteractionsTests(ut.TestCase):
    # Handle to espresso system
    system = espressomd.System()

    def setUp(self):
        self.system.box_l = 10, 10, 10
        if not self.system.part.exists(0):
            self.system.part.add(id=0, pos=(0.1, 0.1, 0.1), dip=(1.3, 2.1, -6))
        if not self.system.part.exists(1):
            self.system.part.add(id=1, pos=(0, 0, 0), dip=(7.3, 6.1, -4))

    if "DP3M" in espressomd.features():
        test_DP3M = generate_test_for_class(
            DipolarP3M,
            dict(prefactor=1.0,
                 epsilon=0.0,
                 inter=1000,
                 mesh_off=[0.5, 0.5, 0.5],
                 r_cut=2.4,
                 mesh=[8, 8, 8],
                 cao=1,
                 alpha=12,
                 accuracy=0.01))

    if "DIPOLAR_DIRECT_SUM" in espressomd.features():
        test_DdsCpu = generate_test_for_class(DipolarDirectSumCpu,
                                              dict(prefactor=3.4))
        test_DdsRCpu = generate_test_for_class(
            DipolarDirectSumWithReplicaCpu, dict(prefactor=3.4, n_replica=2))
Beispiel #2
0
class ewald_GPU_test(ut.TestCase):
    if "ELECTROSTATICS" in espressomd.features(
    ) and "CUDA" in espressomd.features(
    ) and "EWALD_GPU" in espressomd.features():
        from espressomd.electrostatics import EwaldGpu

        def runTest(self):
            es = espressomd.System()
            test_params = {}
            test_params["bjerrum_length"] = 2
            test_params["num_kx"] = 2
            test_params["num_ky"] = 2
            test_params["num_kz"] = 2
            test_params["K_max"] = 10
            test_params["time_calc_steps"] = 100
            test_params["rcut"] = 0.9
            test_params["accuracy"] = 1e-1
            test_params["precision"] = 1e-2
            test_params["alpha"] = 3.5

            ewald = EwaldGpu(**test_params)
            es.actors.add(ewald)
            self.assertTrue(
                params_match(test_params, ewald._get_params_from_es_core()))

    if __name__ == "__main__":
        print("Features: ", espressomd.features())
        ut.main()
Beispiel #3
0
class ElectrostaticInteractionsTests(ut.TestCase):
    if "ELECTROSTATICS" in espressomd.features():
        # Handle to espresso system
        system = espressomd.System()
        
        def setUp(self):
            self.system.box_l = 10, 10, 10
            if not self.system.part.exists(0):
                self.system.part.add(id=0, pos=(2.0, 2.0, 2.0), q=1)
            if not self.system.part.exists(1):
                self.system.part.add(id=1, pos=(8.0, 8.0, 8.0), q=-1)
            print("ut.TestCase setUp")
    
         
        test_P3M = generate_test_for_class(system, P3M, dict(bjerrum_length=1.0,
                                                                     epsilon=0.0,
                                                                     inter=1000,
                                                                     mesh_off=[0.5, 0.5, 0.5],
                                                                     r_cut=2.4,
                                                                     mesh=[2, 2, 2],
                                                                     cao=1,
                                                                     alpha=12,
                                                                     accuracy=0.01,
                                                                     tune=False))
    
        if "COULOMB_DEBYE_HUECKEL" in espressomd.features():
            test_CDH = generate_test_for_class(system, CDH, dict(bjerrum_length=1.0,
                                                                         kappa=2.3,
                                                                         r_cut=2,
                                                                         r0=1,
                                                                         r1=1.9,
                                                                         eps_int=0.8,
                                                                         eps_ext=1,
                                                                         alpha=2))
Beispiel #4
0
class ElectrostaticInteractionsTests(ut.TestCase):
    def setup(self):
        self.system.box_l = 10, 10, 10
        if not self.system.part.exists(0):
            self.system.part.add(id=0, pos=(0.0, 0.0, 0.0), q=1)
        if not self.system.part.exists(1):
            self.system.part.add(id=1, pos=(0.1, 0.1, 0.1), q=-1)

    test_P3M = generate_test_for_class(
        P3M,
        dict(bjerrum_length=1.0,
             epsilon=0.0,
             inter=1000,
             mesh_off=[0.5, 0.5, 0.5],
             r_cut=2.4,
             mesh=[2, 2, 2],
             cao=1,
             alpha=12,
             accuracy=0.01))

    test_DH = generate_test_for_class(
        DH, dict(bjerrum_length=1.0, kappa=2.3, r_cut=2))
    if "CDG" in espressomd.features():
        test_CDH = generate_test_for_class(
            CDH,
            dict(bjerrum_length=1.0,
                 kappa=2.3,
                 r_cut=2,
                 r0=1,
                 r1=2,
                 eps_int=0.8,
                 eps_ext=1,
                 alpha=2))
Beispiel #5
0
    def check_dissipation(self, n):
        """
        Check the dissipation relations: the simple viscous decelleration test.

        Parameters
        ----------
        n : :obj:`int`
            Number of particles of the each type. There are 2 types.

        """

        tol = 1.2E-3
        for step in range(100):
            self.system.integrator.run(2)
            for i in range(n):
                for k in range(2):
                    ind = i + k * n
                    for j in range(3):
                        # Note: velocity is defined in the lab frame of reference
                        # while gamma_tr is defined in the body one.
                        # Hence, only isotropic gamma_tran_p_validate could be
                        # tested here.
                        self.assertLess(
                            abs(self.system.part[ind].v[j] -
                                math.exp(-self.gamma_tran_p_validate[k, j] *
                                         self.system.time / self.mass)), tol)
                        if "ROTATION" in espressomd.features():
                            self.assertLess(
                                abs(self.system.part[ind].omega_body[j] -
                                    math.exp(-self.gamma_rot_p_validate[k, j] *
                                             self.system.time / self.J[j])),
                                tol)
 def test(self):
     if "ROTATION" in espressomd.features():
         n_test_cases = 5
     else:
         n_test_cases = 4
     for i in range(n_test_cases):
         self.run_test_case(i)
 def setUp(self):
     self.system.time = 0.0
     self.system.part.clear()
     if "BROWNIAN_DYNAMICS" in espressomd.features():
         self.system.thermostat.turn_off()
         # the default integrator is supposed implicitly
         self.system.integrator.set_nvt()
Beispiel #8
0
 def test(self):
     if "CUDA" in espressomd.features():
         system = espressomd.System(box_l=[1, 1, 1])
         self.assertEqual(system.cuda_init_handle.device_list != {},
                          espressomd.gpu_available())
     else:
         self.assertFalse(espressomd.gpu_available())
Beispiel #9
0
    def fluctuation_dissipation_param_setup(self,n):
        """
        Setup the parameters for the following fluctuation-dissipation
        test.
    
        Parameters
        ----------
        n : :obj:`int`
            Number of particles of the each type. There are 2 types.

        """

        ## Time
        self.es.time_step = 0.03
        
        ## Space
        box = 10.0
        self.es.box_l = box,box,box
        if espressomd.has_features(("PARTIAL_PERIODIC",)):
            self.es.periodicity = 0,0,0
        
        ## NVT thermostat
        # Just some temperature range to cover by the test:
        self.kT = self.generate_scalar_ranged_rnd(0.3,5)
        # See the above comment regarding the gamma assignments.
        # Note: here & hereinafter specific variations in these ranges are related to
        # the test execution duration to achieve the required statistical averages faster.
        self.gamma_global = self.generate_vec_ranged_rnd(0.5,2.0/3.0)
        self.gamma_global_rot = self.generate_vec_ranged_rnd(0.2,20)
        # Per-particle parameters
        self.kT_p = 2.5,2.0
        for k in range(2):
            self.gamma_tran_p[k, :] = self.generate_vec_ranged_rnd(0.4,10.0)
            self.gamma_rot_p[k, :] = self.generate_vec_ranged_rnd(0.2,20.0)
        
        ## Particles
        # As far as the problem characteristic time is t0 ~ mass / gamma
        # and the Langevin equation finite-difference approximation is stable
        # only for time_step << t0, it is needed to set the mass higher than
        # some minimal value according to the value min_mass_param.
        # Also, it is expected to test the large enough mass (max_mass_param).
        # It should be not very large, otherwise the thermalization will require
        # too much of the CPU time.
        min_mass_param = 0.2
        max_mass_param = 7.0
        self.mass = self.generate_scalar_ranged_rnd(min_mass_param,max_mass_param)
        self.J = self.generate_vec_ranged_rnd(min_mass_param,max_mass_param)
        for i in range(n):
            for k in range(2):
                ind = i + k * n
                part_pos = np.random.random(3) * box
                part_v = 0.0,0.0,0.0
                part_omega_body = 0.0,0.0,0.0
                self.es.part.add(rotation=(1,1,1), id=ind, mass=self.mass, rinertia=self.J,
                                 pos=part_pos, v=part_v)
                if "ROTATION" in espressomd.features():
                    self.es.part[ind].omega_body = part_omega_body
Beispiel #10
0
    def rot_diffusion_param_setup(self, n):
        """
        Setup the parameters for the rotational diffusion
        test check_rot_diffusion().

        Parameters
        ----------
        n : :obj:`int`
            Number of particles.

        """

        # Time
        # The time step should be less than t0 ~ mass / gamma
        self.system.time_step = 3E-3

        # Space
        box = 10.0
        self.system.box_l = box, box, box
        if espressomd.has_features(("PARTIAL_PERIODIC", )):
            self.system.periodicity = 0, 0, 0

        # NVT thermostat
        # Just some temperature range to cover by the test:
        self.kT = uniform(1.5, 6.5)
        # Note: here & hereinafter specific variations in the random parameter ranges are related to
        # the test execution duration to achieve the required statistical averages faster.
        # The friction gamma_global should be large enough in order to have the small enough D ~ kT / gamma and
        # to observe the details of the original rotational diffusion: the Perrin1936 (see the reference below) tests are visible
        # only when the diffusive rotation is ~pi due to the exponential temporal dependencies (see the equations referred in the check_rot_diffusion()).
        # Also, t0 ~ J / gamma should be small enough
        # in order to remove the small-time-scale diffusion effects which do not fit the Perrin1936's
        # tests which are based on the partial differential equation (eq. (68), Perrin1934) leading only to the simple
        # classical Einstein-Smoluchowski equations of the diffusion
        # in a contrast of the eq. (10.2.26) [N. Pottier,
        # https://doi.org/10.1007/s10955-010-0114-6 (2010)].
        self.gamma_global = 1E2 * uniform(0.35, 1.05, (3))

        # Particles
        # As far as the problem characteristic time is t0 ~ J / gamma
        # and the Langevin equation finite-difference approximation is stable
        # only for time_step << t0, it is needed to set the moment of inertia higher than
        # some minimal value.
        # Also, it is expected to test the large enough J.
        # It should be not very large, otherwise the thermalization will require
        # too much of the CPU time: the in silico time should clock over the
        # t0.
        self.J = uniform(1.5, 16.5, (3))
        for ind in range(n):
            part_pos = np.random.random(3) * box
            self.system.part.add(rotation=(1, 1, 1),
                                 id=ind,
                                 rinertia=self.J,
                                 pos=part_pos)
            if "ROTATION" in espressomd.features():
                self.system.part[ind].omega_body = 0.0, 0.0, 0.0
Beispiel #11
0
    def check_dissipation(self):
        """
        Check the dissipation relations: the simple viscous decelleration test.

        """

        tol = 1.25E-4
        for i in range(100):
            for k in range(2):
                for j in range(3):
                    # Note: velocity is defined in the lab frame of reference
                    # while gamma_tr is defined in the body one.
                    # Hence, only isotropic gamma_tran_p_validate could be tested here.
                    self.assertLess(
                        abs(self.es.part[k].v[j] - math.exp(- self.gamma_tran_p_validate[k, j] * self.es.time / self.mass)), tol)
                    if "ROTATION" in espressomd.features():
                        self.assertLess(abs(
                            self.es.part[k].omega_body[j] - math.exp(- self.gamma_rot_p_validate[k, j] * self.es.time / self.J[j])), tol)
Beispiel #12
0
    def set_particle_specific_gamma(self,n):
        """
        Set the particle-specific gamma.
    
        Parameters
        ----------
        n : :obj:`int`
            Number of particles of the each type. There are 2 types.

        """

        for k in range(2):
            self.gamma_tran_p_validate[k, :] = self.gamma_tran_p[k, :]
            self.gamma_rot_p_validate[k, :] = self.gamma_rot_p[k, :]
            for i in range(n):
                ind = i + k * n
                self.es.part[ind].gamma = self.gamma_tran_p[k, :]
                if "ROTATION" in espressomd.features():
                    self.es.part[ind].gamma_rot = self.gamma_rot_p[k, :]
    def test_configure_and_import(self):
        with tempfile.TemporaryDirectory() as temp_dir:
            path_in = pathlib.Path(temp_dir) / "sample.py"
            path_out = pathlib.Path(temp_dir) / "sample_test_processed.py"
            path_features = pathlib.Path(temp_dir) / "sample_impossible.py"

            # test importing a simple sample
            sys.argv.append("42")
            sys_argv_ref = list(sys.argv)
            path_in.write_text("""
import sys
from argparse import ArgumentParser
value = 42
argv = list(sys.argv)
import espressomd.visualization
""")
            sample, _ = iw.configure_and_import(
                path_in, move_to_script_dir=False, cmd_arguments=["TestCase"],
                gpu=False, script_suffix="test", value=43)
            self.assertEqual(sys.argv, sys_argv_ref)
            self.assertEqual(sample.argv, [path_in.name, "TestCase"])
            self.assertTrue(path_out.exists(), f"File {path_out} not found")
            self.assertEqual(sample.value, 43)
            self.assertIn(
                "espressomd.visualization = unittest.mock.MagicMock()",
                path_out.read_text())

            # test importing a sample that relies on features not compiled in
            inactive_features = espressomd.all_features() - set(espressomd.features())
            if inactive_features:
                path_features.write_text(f"""
import espressomd
espressomd.assert_features({list(inactive_features)})
""")
                module, _ = iw.configure_and_import(path_features)
                self.assertIsInstance(module, ut.mock.MagicMock)

                # importing a valid sample is impossible after a failed import
                sample, _ = iw.configure_and_import(
                    path_in, move_to_script_dir=True, script_suffix="test",
                    cmd_arguments=["TestCase"], gpu=False, value=43)
                self.assertIsInstance(sample, ut.mock.MagicMock)
    def run_test_case(self, test_case):
        seed(1)
        # Decelleration
        self.es.time_step = 0.007
        self.es.part.clear()
        # gamma_tran/gamma_rot matrix: [2 types of particless] x [3 dimensions
        # X Y Z]
        gamma_tran = np.zeros((2, 3))
        gamma_tr = np.zeros((2, 3))
        gamma_rot = np.zeros((2, 3))
        gamma_rot_validate = np.zeros((2, 3))
        # The translational gamma isotropy is required here. See comments below.
        # Global gamma for tests without particle-specific gammas:
        # gamma_global = np.ones((3))
        gamma_global = np.zeros((3))
        gamma_global[0] = np.array((0.5 + np.random.random()) * 2.0 / 3.0)
        gamma_global[1] = gamma_global[0]
        gamma_global[2] = gamma_global[0]
        # Additional test case (5th) for the specific global rotational gamma set.
        gamma_global_rot = np.array((0.5 + np.random.random(3)) * 2.0 / 3.0)
        # Per-paricle values for the remaining decelleration tests:
        # Either translational friction isotropy is required
        # or both translational and rotational ones.
        # Otherwise these types of motion will interfere.
        # ..Let's test both cases depending on the particle index.
        gamma_tran[0, 0] = np.array(0.5 + np.random.random())
        gamma_tran[0, 1] = gamma_tran[0, 0]
        gamma_tran[0, 2] = gamma_tran[0, 0]
        gamma_rot[0, :] = np.array((0.5 + random(3)) * 2.0 / 3.0)
        
        gamma_tran[1, 0] = np.array(0.5 + np.random.random())
        gamma_tran[1, 1] = gamma_tran[1, 0]
        gamma_tran[1, 2] = gamma_tran[1, 0]
        gamma_rot[1, 0] = np.array((0.5 + np.random.random()) * 2.0 / 3.0)
        gamma_rot[1, 1] = gamma_rot[1, 0]
        gamma_rot[1, 2] = gamma_rot[1, 0]

        if test_case != 4:
            self.es.thermostat.set_langevin(
                kT=0.0,
                gamma=[
                    gamma_global[0],
                    gamma_global[1],
                    gamma_global[2]])
        else:
            self.es.thermostat.set_langevin(
                kT=0.0,
                gamma=[
                    gamma_global[0],
                    gamma_global[1],
                    gamma_global[2]],
                gamma_rotation=[
                    gamma_global_rot[0],
                    gamma_global_rot[1],
                    gamma_global_rot[2]])

        self.es.cell_system.skin = 5.0
        mass = 12.74
        J = [10.0, 10.0, 10.0]

        for i in range(len(self.es.part)):
            self.es.part[i].remove()

        for i in range(2):
            self.es.part.add(rotation=(1,1,1), pos=np.array([0.0, 0.0, 0.0]), id=i)
            self.es.part[i].v = np.array([1.0, 1.0, 1.0])
            if "ROTATION" in espressomd.features():
                self.es.part[i].omega_body = np.array([1.0, 1.0, 1.0])
            self.es.part[i].mass = mass
            self.es.part[i].rinertia = np.array(J)

        print("\n")

        for k in range(2):
            if test_case == 0:
                if (k == 0):
                    print("------------------------------------------------")
                    print("Test " + str(test_case) + ": no particle specific values")
                    print("------------------------------------------------")
                # No assignments are needed.
    
            if test_case == 1:
                if (k == 0):
                    print("------------------------------------------------")
                    print("Test " + str(test_case) +
                        ": particle specific gamma but not temperature")
                    print("------------------------------------------------")
                self.es.part[k].gamma = gamma_tran[k, :]
                if "ROTATION" in espressomd.features():
                    self.es.part[k].gamma_rot = gamma_rot[k, :]
    
            if test_case == 2:
                if (k == 0):
                    print("------------------------------------------------")
                    print("Test " + str(test_case) +
                        ": particle specific temperature but not gamma")
                    print("------------------------------------------------")
                self.es.part[k].temp = 0.0
    
            if test_case == 3:
                if (k == 0):
                    print("------------------------------------------------")
                    print("Test " + str(test_case) +
                        ": both particle specific gamma and temperature")
                    print("------------------------------------------------")
                self.es.part[k].temp = 0.0
                self.es.part[k].gamma = gamma_tran[k, :]
                if "ROTATION" in espressomd.features():
                    self.es.part[k].gamma_rot = gamma_rot[k, :]
            
            if test_case == 4:
                if (k == 0):
                    print("------------------------------------------------")
                    print("Test " + str(test_case) + ": no particle specific values.")
                    print("Rotational specific global thermostat")
                    print("------------------------------------------------")
                    # No assignments are needed.

        if test_case == 1 or test_case == 3:
            gamma_tr = gamma_tran
            gamma_rot_validate = gamma_rot
        else:
            for k in range(2):
                gamma_tr[k, :] = gamma_global[:]
                if test_case != 4:
                    gamma_rot_validate[k, :] = gamma_global[:]
                else:
                    gamma_rot_validate[k, :] = gamma_global_rot[:]

        self.es.time = 0.0

        tol = 1.25E-4
        for i in range(100):
            for k in range(2):
                for j in range(3):
                    # Note: velocity is defined in the lab frame of reference
                    # while gamma_tr is defined in the body one.
                    # Hence, only isotropic gamma_tr could be tested here.
                    self.assertLess(
                        abs(self.es.part[k].v[j] - math.exp(- gamma_tr[k, j] * self.es.time / mass)), tol)
                    if "ROTATION" in espressomd.features():
                        self.assertLess(abs(
                            self.es.part[k].omega_body[j] - math.exp(- gamma_rot_validate[k, j] * self.es.time / J[j])), tol)

        for i in range(len(self.es.part)):
            self.es.part[i].remove()

        # thermalization
        # Checks if every degree of freedom has 1/2 kT of energy, even when
        # mass and inertia tensor are active

        # 2 different langevin parameters for particles
        temp = np.array([2.5, 2.0])
        D_tr = np.zeros((2, 3))
        for k in range(2):
            gamma_tran[k, :] = np.array((0.4 + np.random.random(3)) * 10)
            gamma_rot[k, :] = np.array((0.2 + np.random.random(3)) * 20)

        box = 10.0
        self.es.box_l = [box, box, box]
        if espressomd.has_features(("PARTIAL_PERIODIC",)):
            self.es.periodicity = 0, 0, 0
        # Random temperature
        kT = (0.3 + np.random.random()) * 5
        gamma_global = np.array((0.5 + np.random.random(3)) * 2.0 / 3.0)
        gamma_global_rot = np.array((0.2 + np.random.random(3)) * 20)

        if test_case == 2 or test_case == 3:
            halfkT = temp / 2.0
        else:
            halfkT = np.array([kT, kT]) / 2.0

        if test_case == 1 or test_case == 3:
            gamma_tr = gamma_tran
        else:
            for k in range(2):
                gamma_tr[k, :] = gamma_global[:]

        # translational diffusion
        for k in range(2):
            D_tr[k, :] = 2.0 * halfkT[k] / gamma_tr[k, :]

        if test_case != 4:
            self.es.thermostat.set_langevin(
                kT=kT,
                gamma=[
                    gamma_global[0],
                    gamma_global[1],
                    gamma_global[2]])
        else:
            self.es.thermostat.set_langevin(
                kT=kT,
                gamma=[
                    gamma_global[0],
                    gamma_global[1],
                    gamma_global[2]],
                gamma_rotation=[
                    gamma_global_rot[0],
                    gamma_global_rot[1],
                    gamma_global_rot[2]])

        # no need to rebuild Verlet lists, avoid it
        self.es.cell_system.skin = 5.0
        self.es.time_step = 0.03
        n = 200
        mass = (0.2 + np.random.random()) * 7.0
        J = np.array((0.2 + np.random.random(3)) * 7.0)

        for i in range(n):
            for k in range(2):
                ind = i + k * n
                part_pos = np.array(np.random.random(3) * box)
                part_v = np.array([0.0, 0.0, 0.0])
                part_omega_body = np.array([0.0, 0.0, 0.0])
                self.es.part.add(rotation=(1,1,1), id=ind, mass=mass, rinertia=J,
                                 pos=part_pos, v=part_v)
                if "ROTATION" in espressomd.features():
                    self.es.part[ind].omega_body = part_omega_body
                if test_case == 1:
                    self.es.part[ind].gamma = gamma_tran[k, :]
                    if "ROTATION" in espressomd.features():
                        self.es.part[ind].gamma_rot = gamma_rot[k, :]

                if test_case == 2:
                    self.es.part[ind].temp = temp[k]
                if test_case == 3:
                    self.es.part[ind].gamma = gamma_tran[k, :]
                    if "ROTATION" in espressomd.features():
                        self.es.part[ind].gamma_rot = gamma_rot[k, :]
                    self.es.part[ind].temp = temp[k]

        # Get rid of short range calculations if exclusions are on
        # if espressomd.has_features("EXCLUSIONS"):

        # matrices: [2 types of particless] x [3 dimensions X Y Z]
        # velocity^2, omega^2, position^2
        v2 = np.zeros((2, 3))
        o2 = np.zeros((2, 3))
        dr2 = np.zeros((2, 3))
        sigma2_tr = np.zeros((2))
        dr_norm = np.zeros((2))

        pos0 = np.zeros((2 * n, 3))
        for p in range(n):
            for k in range(2):
                ind = p + k * n
                pos0[ind, :] = self.es.part[ind].pos
        dt0 = mass / gamma_tr

        loops = 200
        print("Thermalizing...")
        therm_steps = 20
        self.es.integrator.run(therm_steps)
        print("Measuring...")

        int_steps = 5
        for i in range(loops):
            self.es.integrator.run(int_steps)
            # Get kinetic energy in each degree of freedom for all particles
            for p in range(n):
                for k in range(2):
                    ind = p + k * n
                    v = self.es.part[ind].v
                    if "ROTATION" in espressomd.features():
                        o = self.es.part[ind].omega_body
                        o2[k, :] = o2[k, :] + np.power(o[:], 2)
                    pos = self.es.part[ind].pos
                    v2[k, :] = v2[k, :] + np.power(v[:], 2)
                    dr2[k, :] = np.power((pos[:] - pos0[ind, :]), 2)
                    dt = (int_steps * (i + 1) + therm_steps) * \
                        self.es.time_step
                    # translational diffusion variance: after a closed-form
                    # integration of the Langevin EOM
                    sigma2_tr[k] = 0.0
                    for j in range(3):
                        sigma2_tr[k] = sigma2_tr[k] + D_tr[k,
                                                           j] * (2.0 * dt + dt0[k,
                                                                              j] * (- 3.0 + 4.0 * math.exp(- dt / dt0[k,
                                                                                                                  j]) - math.exp(- 2.0 * dt / dt0[k,
                                                                                                                                                j])))
                    dr_norm[k] = dr_norm[k] + \
                        (sum(dr2[k, :]) - sigma2_tr[k]) / sigma2_tr[k]

        tolerance = 0.15
        Ev = 0.5 * mass * v2 / (n * loops)
        Eo = 0.5 * J * o2 / (n * loops)
        dv = np.zeros((2))
        do = np.zeros((2))
        do_vec = np.zeros((2, 3))
        for k in range(2):
            dv[k] = sum(Ev[k, :]) / (3.0 * halfkT[k]) - 1.0
            do[k] = sum(Eo[k, :]) / (3.0 * halfkT[k]) - 1.0
            do_vec[k, :] = Eo[k, :] / halfkT[k] - 1.0
        dr_norm = dr_norm / (n * loops)
        for k in range(2):
            print("\n")
            print("k = " + str(k))
            print("mass = " + str(mass))
            print("gamma_tr = {0} {1} {2}".format(
                gamma_tr[k, 0], gamma_tr[k, 1], gamma_tr[k, 2]))
            if test_case == 1 or test_case == 3:
                print("gamma_rot = {0} {1} {2}".format(
                    gamma_rot[k, 0], gamma_rot[k, 1], gamma_rot[k, 2]))
            else:
                print("gamma_global = {0} {1} {2}".format(
                    gamma_global[0], gamma_global[1], gamma_global[2]))
            print("Moment of inertia principal components: = " + str(J))
            print("1/2 kT = " + str(halfkT[k]))
            print("Translational energy: {0} {1} {2}".format(
                Ev[k, 0], Ev[k, 1], Ev[k, 2]))
            print("Rotational energy: {0} {1} {2}".format(
                Eo[k, 0], Eo[k, 1], Eo[k, 2]))

            print("Deviation in translational energy: " + str(dv[k]))
            if "ROTATION" in espressomd.features():
                print("Deviation in rotational energy: " + str(do[k]))
                print("Deviation in rotational energy per degrees of freedom: {0} {1} {2}".format(
                    do_vec[k, 0], do_vec[k, 1], do_vec[k, 2]))
            print(
                "Deviation in translational diffusion: {0} ".format(
                    dr_norm[k]))

            self.assertLessEqual(
                abs(
                    dv[k]),
                tolerance,
                msg='Relative deviation in translational energy too large: {0}'.format(
                    dv[k]))
            if "ROTATION" in espressomd.features():
                self.assertLessEqual(
                    abs(
                        do[k]),
                    tolerance,
                    msg='Relative deviation in rotational energy too large: {0}'.format(
                        do[k]))
                self.assertLessEqual(abs(
                    do_vec[k, 0]), tolerance, msg='Relative deviation in rotational energy per the body axis X is too large: {0}'.format(do_vec[k, 0]))
                self.assertLessEqual(abs(
                    do_vec[k, 1]), tolerance, msg='Relative deviation in rotational energy per the body axis Y is too large: {0}'.format(do_vec[k, 1]))
                self.assertLessEqual(abs(
                    do_vec[k, 2]), tolerance, msg='Relative deviation in rotational energy per the body axis Z is too large: {0}'.format(do_vec[k, 2]))
            self.assertLessEqual(
                abs(
                    dr_norm[k]),
                tolerance,
                msg='Relative deviation in translational diffusion is too large: {0}'.format(
                    dr_norm[k]))
class RotDiffAniso(ut.TestCase):
    longMessage = True
    round_error_prec = 1E-14
    # Handle for espresso system
    system = espressomd.System(box_l=[1.0, 1.0, 1.0])
    system.cell_system.skin = 5.0

    # The NVT thermostat parameters
    kT = 0.0
    gamma_global = np.zeros((3))

    # Particle properties
    J = [0.0, 0.0, 0.0]

    np.random.seed(4)

    def setUp(self):
        self.system.time = 0.0
        self.system.part.clear()
        if "BROWNIAN_DYNAMICS" in espressomd.features():
            self.system.thermostat.turn_off()
            # the default integrator is supposed implicitly
            self.system.integrator.set_nvt()

    def add_particles_setup(self, n):
        """
        Adding particles according to the
        previously set parameters.

        Parameters
        ----------
        n : :obj:`int`
            Number of particles.

        """

        for ind in range(n):
            part_pos = np.random.random(3) * self.box
            self.system.part.add(rotation=(1, 1, 1), id=ind, pos=part_pos)
            self.system.part[ind].rinertia = self.J
            if espressomd.has_features("ROTATION"):
                self.system.part[ind].omega_body = [0.0, 0.0, 0.0]

    def set_anisotropic_param(self):
        """
        Select parameters for anisotropic particles.

        """

        # NVT thermostat
        # Note: here & hereinafter specific variations in the random parameter
        # ranges are related to the test execution duration to achieve the
        # required statistical averages faster. The friction gamma_global should
        # be large enough in order to have the small enough D ~ kT / gamma and
        # to observe the details of the original rotational diffusion: the
        # Perrin1936 (see the reference below) tests are visible only when the
        # diffusive rotation is ~pi due to the exponential temporal dependencies
        # (see the equations referred in the check_rot_diffusion()).
        # Also, t0 ~ J / gamma should be small enough in order to remove the
        # small-time-scale diffusion effects which do not fit the Perrin1936's
        # tests which are based on the partial differential equation
        # (eq. (68), Perrin1934) leading only to the simple classical
        # Einstein-Smoluchowski equations of the diffusion in a contrast of the
        # eq. (10.2.26) [N. Pottier, doi:10.1007/s10955-010-0114-6 (2010)].
        self.gamma_global = 1E2 * np.random.uniform(0.35, 1.05, (3))

        # Particles' properties
        # As far as the problem characteristic time is t0 ~ J / gamma
        # and the Langevin equation finite-difference approximation is stable
        # only for time_step << t0, it is needed to set the moment of inertia
        # higher than some minimal value.
        # Also, it is expected to test the large enough J.
        # It should be not very large, otherwise the thermalization will require
        # too much of the CPU time: the in silico time should clock over the
        # t0.
        self.J = np.random.uniform(1.5, 16.5, (3))

    def set_isotropic_param(self):
        """
        Select parameters for isotropic particles.

        Parameters
        ----------

        """

        # NVT thermostat
        # see the comments in set_anisotropic_param()
        self.gamma_global[0] = 1E2 * np.random.uniform(0.35, 1.05)
        self.gamma_global[1] = self.gamma_global[0]
        self.gamma_global[2] = self.gamma_global[0]
        # Particles' properties
        # see the comments in set_anisotropic_param()
        self.J[0] = np.random.uniform(1.5, 16.5)
        self.J[1] = self.J[0]
        self.J[2] = self.J[0]

    def rot_diffusion_param_setup(self):
        """
        Setup the parameters for the rotational diffusion
        test check_rot_diffusion().

        """

        # Time
        # The time step should be less than t0 ~ mass / gamma
        self.system.time_step = 3E-3

        # Space
        self.box = 10.0
        self.system.box_l = 3 * [self.box]
        self.system.periodicity = [0, 0, 0]

        # NVT thermostat
        # Just some temperature range to cover by the test:
        self.kT = np.random.uniform(0.5, 1.5)

    def check_rot_diffusion(self, n):
        """
        The rotational diffusion tests based on the reference work
        [Perrin, F. (1936) Journal de Physique et Le Radium, 7(1), 1-11.
        https://doi.org/10.1051/jphysrad:01936007010100]
        with a theoretical background of
        [Perrin, F. (1934) Journal de Physique et Le Radium, 5(10), 497-511.
        https://doi.org/10.1051/jphysrad:01934005010049700]

        Parameters
        ----------
        n : :obj:`int`
            Number of particles.

        """
        # Global diffusivity tensor in the body frame:
        D = self.kT / self.gamma_global

        # Thermalizing...
        therm_steps = 100
        self.system.integrator.run(therm_steps)

        # Measuring...
        # Set the initial conditions according to the [Perrin1936], p.3.
        # The body angular velocity is rotated now, but there is only the
        # thermal velocity, hence, this does not impact the test and its
        # physical context.
        for ind in range(n):
            self.system.part[ind].quat = [1.0, 0.0, 0.0, 0.0]
        # Average direction cosines
        # Diagonal ones:
        dcosjj_validate = np.zeros((3))
        dcosjj_dev = np.zeros((3))
        # same to the power of 2
        dcosjj2_validate = np.zeros((3))
        dcosjj2_dev = np.zeros((3))
        # The non-diagonal elements for 2 different tests: negative ("nn") and
        # positive ("pp") ones.
        dcosijpp_validate = np.ones((3, 3))
        dcosijpp_dev = np.zeros((3, 3))
        dcosijnn_validate = np.ones((3, 3))
        dcosijnn_dev = np.zeros((3, 3))
        # The non-diagonal elements to the power of 2
        dcosij2_validate = np.ones((3, 3))
        dcosij2_dev = np.zeros((3, 3))

        self.system.time = 0.0
        int_steps = 20
        loops = 100
        for _ in range(loops):
            self.system.integrator.run(steps=int_steps)
            dcosjj = np.zeros((3))
            dcosjj2 = np.zeros((3))
            dcosijpp = np.zeros((3, 3))
            dcosijnn = np.zeros((3, 3))
            dcosij2 = np.zeros((3, 3))
            for ind in range(n):
                # Just a direction cosines functions averaging..
                dir_cos = tests_common.rotation_matrix_quat(self.system, ind)
                for j in range(3):
                    # the LHS of eq. (23) [Perrin1936].
                    dcosjj[j] += dir_cos[j, j]
                    # the LHS of eq. (32) [Perrin1936].
                    dcosjj2[j] += dir_cos[j, j]**2.0
                    for i in range(3):
                        if i != j:
                            # the LHS of eq. (24) [Perrin1936].
                            dcosijpp[i, j] += dir_cos[i, i] * dir_cos[j, j] + \
                                dir_cos[i, j] * dir_cos[j, i]
                            # the LHS of eq. (25) [Perrin1936].
                            dcosijnn[i, j] += dir_cos[i, i] * dir_cos[j, j] - \
                                dir_cos[i, j] * dir_cos[j, i]
                            # the LHS of eq. (33) [Perrin1936].
                            dcosij2[i, j] += dir_cos[i, j]**2.0
            dcosjj /= n
            dcosjj2 /= n
            dcosijpp /= n
            dcosijnn /= n
            dcosij2 /= n

            # Actual comparison.

            tolerance = 0.2
            # Too small values of the direction cosines are out of interest
            # compare to 0..1 range.
            min_value = 0.14

            # Eq. (23) [Perrin1936].
            dcosjj_validate[0] = np.exp(-(D[1] + D[2]) * self.system.time)
            dcosjj_validate[1] = np.exp(-(D[0] + D[2]) * self.system.time)
            dcosjj_validate[2] = np.exp(-(D[0] + D[1]) * self.system.time)
            dcosjj_dev = np.absolute(dcosjj -
                                     dcosjj_validate) / dcosjj_validate
            for j in range(3):
                if np.absolute(dcosjj_validate[j]) < min_value:
                    dcosjj_dev[j] = 0.0

            # Eq. (24) [Perrin1936].
            dcosijpp_validate[0, 1] = np.exp(-(4 * D[2] + D[1] + D[0]) *
                                             self.system.time)
            dcosijpp_validate[1, 0] = np.exp(-(4 * D[2] + D[1] + D[0]) *
                                             self.system.time)
            dcosijpp_validate[0, 2] = np.exp(-(4 * D[1] + D[2] + D[0]) *
                                             self.system.time)
            dcosijpp_validate[2, 0] = np.exp(-(4 * D[1] + D[2] + D[0]) *
                                             self.system.time)
            dcosijpp_validate[1, 2] = np.exp(-(4 * D[0] + D[2] + D[1]) *
                                             self.system.time)
            dcosijpp_validate[2, 1] = np.exp(-(4 * D[0] + D[2] + D[1]) *
                                             self.system.time)
            dcosijpp_dev = np.absolute(dcosijpp -
                                       dcosijpp_validate) / dcosijpp_validate
            for i in range(3):
                for j in range(3):
                    if np.absolute(dcosijpp_validate[i, j]) < min_value:
                        dcosijpp_dev[i, j] = 0.0

            # Eq. (25) [Perrin1936].
            dcosijnn_validate[0, 1] = np.exp(-(D[1] + D[0]) * self.system.time)
            dcosijnn_validate[1, 0] = np.exp(-(D[1] + D[0]) * self.system.time)
            dcosijnn_validate[0, 2] = np.exp(-(D[2] + D[0]) * self.system.time)
            dcosijnn_validate[2, 0] = np.exp(-(D[2] + D[0]) * self.system.time)
            dcosijnn_validate[1, 2] = np.exp(-(D[2] + D[1]) * self.system.time)
            dcosijnn_validate[2, 1] = np.exp(-(D[2] + D[1]) * self.system.time)
            dcosijnn_dev = np.absolute(dcosijnn -
                                       dcosijnn_validate) / dcosijnn_validate
            for i in range(3):
                for j in range(3):
                    if np.absolute(dcosijnn_validate[i, j]) < min_value:
                        dcosijnn_dev[i, j] = 0.0

            # Eq. (30) [Perrin1936].
            D0 = sum(D[:]) / 3.0
            D1D1 = 0.0
            for j in range(3):
                for i in range(3):
                    if i != j:
                        D1D1 += D[i] * D[j]
            D1D1 /= 6.0
            # Technical workaround of a digital arithmetic issue for isotropic
            # particle
            if np.absolute(
                (D0**2 - D1D1) / (D0**2 + D1D1)) < self.round_error_prec:
                D1D1 *= (1.0 - 2.0 * self.round_error_prec)
            # Eq. (32) [Perrin1936].
            dcosjj2_validate = 1. / 3. + (1. / 3.) * (1. + (D - D0) / (2. * np.sqrt(D0**2 - D1D1))) \
                * np.exp(-6. * (D0 - np.sqrt(D0**2 - D1D1)) * self.system.time) \
                + (1. / 3.) * (1. - (D - D0) / (2. * np.sqrt(D0**2 - D1D1))) \
                * np.exp(-6. * (D0 + np.sqrt(D0**2 - D1D1)) * self.system.time)
            dcosjj2_dev = np.absolute(dcosjj2 -
                                      dcosjj2_validate) / dcosjj2_validate
            for j in range(3):
                if np.absolute(dcosjj2_validate[j]) < min_value:
                    dcosjj2_dev[j] = 0.0

            # Eq. (33) [Perrin1936].
            dcosij2_validate[0, 1] = 1. / 3. - (1. / 6.) * (1. - (D[2] - D0) / (2. * np.sqrt(D0**2 - D1D1))) \
                * np.exp(-6. * (D0 - np.sqrt(D0**2 - D1D1)) * self.system.time) \
                - (1. / 6.) * (1. + (D[2] - D0) / (2. * np.sqrt(D0**2 - D1D1))) \
                * np.exp(-6. * (D0 + np.sqrt(D0**2 - D1D1)) * self.system.time)
            dcosij2_validate[1, 0] = dcosij2_validate[0, 1]

            dcosij2_validate[0, 2] = 1. / 3. - (1. / 6.) * (1. - (D[1] - D0) / (2. * np.sqrt(D0**2 - D1D1))) \
                * np.exp(-6. * (D0 - np.sqrt(D0**2 - D1D1)) * self.system.time) \
                - (1. / 6.) * (1. + (D[1] - D0) / (2. * np.sqrt(D0**2 - D1D1))) \
                * np.exp(-6. * (D0 + np.sqrt(D0**2 - D1D1)) * self.system.time)
            dcosij2_validate[2, 0] = dcosij2_validate[0, 2]

            dcosij2_validate[1, 2] = 1. / 3. - (1. / 6.) * (1. - (D[0] - D0) / (2. * np.sqrt(D0**2 - D1D1))) \
                * np.exp(-6. * (D0 - np.sqrt(D0**2 - D1D1)) * self.system.time) \
                - (1. / 6.) * (1. + (D[0] - D0) / (2. * np.sqrt(D0**2 - D1D1))) \
                * np.exp(-6. * (D0 + np.sqrt(D0**2 - D1D1)) * self.system.time)
            dcosij2_validate[2, 1] = dcosij2_validate[1, 2]
            dcosij2_dev = np.absolute(dcosij2 -
                                      dcosij2_validate) / dcosij2_validate
            for i in range(3):
                for j in range(3):
                    if np.absolute(dcosij2_validate[i, j]) < min_value:
                        dcosij2_dev[i, j] = 0.0

            for j in range(3):
                self.assertLessEqual(
                    abs(dcosjj_dev[j]),
                    tolerance,
                    msg='Relative deviation dcosjj_dev[{0}] in a rotational '
                    'diffusion is too large: {1}'.format(j, dcosjj_dev[j]))
                self.assertLessEqual(
                    abs(dcosjj2_dev[j]),
                    tolerance,
                    msg='Relative deviation dcosjj2_dev[{0}] in a rotational '
                    'diffusion is too large: {1}'.format(j, dcosjj2_dev[j]))
                for i in range(3):
                    if i != j:
                        self.assertLessEqual(
                            abs(dcosijpp_dev[i, j]),
                            tolerance,
                            msg='Relative deviation dcosijpp_dev[{0},{1}] in a '
                            'rotational diffusion is too large: {2}'.format(
                                i, j, dcosijpp_dev[i, j]))
                        self.assertLessEqual(
                            abs(dcosijnn_dev[i, j]),
                            tolerance,
                            msg='Relative deviation dcosijnn_dev[{0},{1}] in a '
                            'rotational diffusion is too large: {2}'.format(
                                i, j, dcosijnn_dev[i, j]))
                        self.assertLessEqual(
                            abs(dcosij2_dev[i, j]),
                            tolerance,
                            msg='Relative deviation dcosij2_dev[{0},{1}] in a '
                            'rotational diffusion is too large: {2}'.format(
                                i, j, dcosij2_dev[i, j]))

    # Langevin Dynamics / Anisotropic
    def test_case_00(self):
        n = 800
        self.rot_diffusion_param_setup()
        self.set_anisotropic_param()
        self.add_particles_setup(n)
        self.system.thermostat.set_langevin(kT=self.kT,
                                            gamma=self.gamma_global,
                                            seed=42)
        # Actual integration and validation run
        self.check_rot_diffusion(n)

    # Langevin Dynamics / Isotropic
    def test_case_01(self):
        n = 800
        self.rot_diffusion_param_setup()
        self.set_isotropic_param()
        self.add_particles_setup(n)
        self.system.thermostat.set_langevin(kT=self.kT,
                                            gamma=self.gamma_global,
                                            seed=42)
        # Actual integration and validation run
        self.check_rot_diffusion(n)

    if "BROWNIAN_DYNAMICS" in espressomd.features():
        # Brownian Dynamics / Isotropic
        def test_case_10(self):
            n = 800
            self.system.thermostat.turn_off()
            self.rot_diffusion_param_setup()
            self.set_isotropic_param()
            self.add_particles_setup(n)
            self.system.thermostat.set_brownian(kT=self.kT,
                                                gamma=self.gamma_global,
                                                seed=42)
            self.system.integrator.set_brownian_dynamics()
            # Actual integration and validation run
            self.check_rot_diffusion(n)
Beispiel #16
0
# ESPResSo is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Tests particle property setters/getters
from __future__ import print_function
import espressomd
import unittest as ut
import numpy as np
from tests_common import *

if "ELECTROSTATICS" in espressomd.features() and "CUDA" in espressomd.features():
    from espressomd.electrostatics import P3M_GPU

    class P3M_GPU_test(ut.TestCase):
        def runTest(self):
            es = espressomd.System()
            test_params = {}
            test_params["bjerrum_length"] = 2
            test_params["cao"] = 2
            test_params["inter"] = 3
            test_params["r_cut"] = 0.9
            test_params["accuracy"] = 1e-1
            test_params["mesh"] = [10, 10, 10]
            test_params["epsilon"] = 20.0
            test_params["mesh_off"] = [0.8, 0.8, 0.8]
            test_params["alpha"] = 1.1
Beispiel #17
0
# (at your option) any later version.
#
# ESPResSo is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Tests particle property setters/getters
import espressomd
import unittest as ut
import numpy as np

if "P3M_GPU" in espressomd.features():
    from espressomd.electrostatics import P3M_GPU

    class P3M_GPU_test(ut.TestCase):
        es = espressomd.System()
        test_params = {}
        test_params["bjerrum_length"] = 2
        test_params["cao"] = 2
        test_params["inter"] = 3
        test_params["r_cut"] = 0.9
        test_params["accuracy"] = 1e-1
        test_params["mesh"] = [10, 10, 10]
        test_params["epsilon"] = 20.0
        test_params["mesh_off"] = [0.8, 0.8, 0.8]
        test_params["alpha"] = 1.1
        test_params["tune"] = False
class ParticleProperties(ut.TestCase):
    #  def __init__(self,particleId):
    #    self.pid=particleId
    # the system which will be tested
    system = espressomd.System()

    # Particle id to work on
    pid = 17

    # Error tolerance when comparing arrays/tuples...
    tol = 1E-9

    def bondsMatch(self, inType, outType, inParams, outParams):
        """Check, if the bond type set and gotten back as well as the bond 
        parameters set and gotten back match. Only check keys present in
        inParams.
        """
        if inType != outType:
            return False

        for k in list(inParams.keys()):
            if k not in outParams:
                return False
            if outParams[k] != inParams[k]:
                return False

        return True

    def setUp(self):
        if not self.system.part.exists(self.pid):
            self.system.part.add(id=self.pid, pos=(0, 0, 0, 0))

    def generateTestForBondParams(_bondId, _bondClass, _params):
        """Generates test cases for checking bond parameters set and gotten back
        from Es actually match. Only keys which are present  in _params are checked
        1st arg: Id of the bonded ia in Espresso to test on, i.e., 0,2,1...
        2nd: Class of the bond potential to test, ie.e, FeneBond, HarmonicBond
        3rd: Bond parameters as dictionary, i.e., {"k"=1.,"r_0"=0.
        """
        bondId = _bondId
        bondClass = _bondClass
        params = _params

        def func(self):
            # This code is run at the execution of the generated function.
            # It will use the state of the variables in the outer function,
            # which was there, when the outer function was called
            self.system.bonded_inter[bondId] = bondClass(**params)
            outBond = self.system.bonded_inter[bondId]
            tnIn = bondClass(**params).type_number()
            tnOut = outBond.type_number()
            outParams = outBond.params
            self.assertTrue(
                self.bondsMatch(tnIn, tnOut, params, outParams),
                bondClass(**params).type_name() +
                ": value set and value gotten back differ for bond id " +
                str(bondId) + ": " + params.__str__() + " vs. " +
                outParams.__str__())

        return func

    test_fene = generateTestForBondParams(0, FeneBond, {
        "r_0": 1.1,
        "k": 5.2,
        "d_r_max": 3.
    })
    test_fene2 = generateTestForBondParams(1, FeneBond, {
        "r_0": 1.1,
        "k": 5.2,
        "d_r_max": 3.
    })
    test_harmonic = generateTestForBondParams(0, HarmonicBond, {
        "r_0": 1.1,
        "k": 5.2
    })
    test_harmonic2 = generateTestForBondParams(0, HarmonicBond, {
        "r_0": 1.1,
        "k": 5.2,
        "r_cut": 1.3
    })

    if "ROTATION" in code_info.features():
        test_harmonic_dumbbell = generateTestForBondParams(
            0, HarmonicDumbbellBond, {
                "k1": 1.1,
                "k2": 2.2,
                "r_0": 1.5
            })
        test_harmonic_dumbbell2 = generateTestForBondParams(
            0, HarmonicDumbbellBond, {
                "k1": 1.1,
                "k2": 2.2,
                "r_0": 1.5,
                "r_cut": 1.9
            })

    test_dihedral = generateTestForBondParams(0, Dihedral, {
        "mult": 3.0,
        "bend": 5.2,
        "phase": 3.
    })

    if "BOND_ANGLE" in espressomd.features():
        test_angle_harm = generateTestForBondParams(0, Angle_Harmonic, {
            "bend": 5.2,
            "phi0": 3.2
        })
        test_angle_cos = generateTestForBondParams(0, Angle_Cosine, {
            "bend": 5.2,
            "phi0": 3.2
        })
        test_angle_cossquare = generateTestForBondParams(
            0, Angle_Cossquare, {
                "bend": 5.2,
                "phi0": 0.
            })
    if "LENNARD_JONES" in espressomd.features():
        test_subt_lj = generateTestForBondParams(0, Subt_Lj, {
            "k": 5.2,
            "r": 3.2
        })

    if "TABULATED" in espressomd.features():
        test_tabulated = generateTestForBondParams(0, Tabulated, {
            "type": "distance",
            "filename": "lj1.tab"
        })
Beispiel #19
0
        e_kin = e - e_pot
        print(" {} {} {} {}".format(time, e, e_pot, e_kin), file=f)


def calc_temperature(system):
    E = system.analysis.energy()['total']
    n_part = len(system.part)

    return 2. / 3. * E / n_part


# check for necessary feature
required_features = ["MASS", "TABULATED"]
espressomd.assert_features(required_features)

print("Program Information:\n{}\n".format(espressomd.features()))
espresso_release = (espressomd.version.major(), espressomd.version.minor())

# set system properties:
skin = 0.5
time_step = 0.002
friction = 5.0
int_steps = 900
eq_steps = 100
steps_per_int = 100

atomnumber, box, atompos = readgrofile('spce.gro')
nm2Angstroem = 10
box_length = box * nm2Angstroem
positions = atompos * nm2Angstroem
mass = 18
class Non_bonded_interactionsTests(ut.TestCase):
    #  def __init__(self,particleId):
    #    self.pid=particleId

    # Handle to espresso system
    es = espressomd.System()

    def intersMatch(self, inType, outType, inParams, outParams):
        """Check, if the interaction type set and gotten back as well as the bond 
        parameters set and gotten back match. Only check keys present in
        inParams.
        """
        if inType != outType:
            print("Type mismatch:", inType, outType)
            return False

        for k in inParams.keys():
            if k not in outParams:
                print(k, "missing from returned parameters")
                return False
            if outParams[k] != inParams[k]:
                print("Mismatch in parameter ", k, inParams[k], outParams[k])
                return False

        return True

    def generateTestForNon_bonded_interaction(_partType1, _partType2,
                                              _interClass, _params,
                                              _interName):
        """Generates test cases for checking interaction parameters set and gotten back
        from Es actually match. Only keys which are present  in _params are checked
        1st and 2nd arg: Particle type ids to check on
        3rd: Class of the interaction to test, ie.e, FeneBond, HarmonicBond
        4th: Interaction parameters as dictionary, i.e., {"k"=1.,"r_0"=0.
        5th: Name of the interaction property to set (i.e. "lennardJones")
        """
        partType1 = _partType1
        partType2 = _partType2
        interClass = _interClass
        params = _params
        interName = _interName

        def func(self):
            # This code is run at the execution of the generated function.
            # It will use the state of the variables in the outer function,
            # which was there, when the outer function was called

            # Set parameters
            getattr(self.es.non_bonded_inter[partType1, partType2],
                    interName).set_params(**params)

            # Read them out again
            outInter = getattr(self.es.non_bonded_inter[partType1, partType2],
                               interName)
            outParams = outInter.get_params()

            self.assertTrue(
                self.intersMatch(interClass, type(outInter), params,
                                 outParams),
                interClass(**params).type_name() +
                ": value set and value gotten back differ for particle types "
                + str(partType1) + " and " + str(partType2) + ": " +
                params.__str__() + " vs. " + outParams.__str__())

        return func

    test_lj1 = generateTestForNon_bonded_interaction(
        0, 0, LennardJonesInteraction, {
            "epsilon": 1.,
            "sigma": 2.,
            "cutoff": 3.,
            "shift": 4.,
            "offset": 5.,
            "min": 7.
        }, "lennard_jones")
    test_lj2 = generateTestForNon_bonded_interaction(
        0, 0, LennardJonesInteraction, {
            "epsilon": 1.3,
            "sigma": 2.2,
            "cutoff": 3.4,
            "shift": 4.1,
            "offset": 5.1,
            "min": 7.1
        }, "lennard_jones")
    test_lj3 = generateTestForNon_bonded_interaction(
        0, 0, LennardJonesInteraction, {
            "epsilon": 1.3,
            "sigma": 2.2,
            "cutoff": 3.4,
            "shift": 4.1,
            "offset": 5.1,
            "min": 7.1
        }, "lennard_jones")

    if "LENNARD_JONES_GENERIC" in espressomd.features():
        test_ljgen1 = generateTestForNon_bonded_interaction(
            0, 0, GenericLennardJonesInteraction, {
                "epsilon": 1.,
                "sigma": 2.,
                "cutoff": 3.,
                "shift": 4.,
                "offset": 5.,
                "e1": 7,
                "e2": 8,
                "b1": 9.,
                "b2": 10.
            }, "generic_lennard_jones")
        test_ljgen2 = generateTestForNon_bonded_interaction(
            0, 0, GenericLennardJonesInteraction, {
                "epsilon": 1.1,
                "sigma": 2.1,
                "cutoff": 3.1,
                "shift": 4.1,
                "offset": 5.1,
                "e1": 71,
                "e2": 81,
                "b1": 9.1,
                "b2": 10.1
            }, "generic_lennard_jones")
        test_ljgen3 = generateTestForNon_bonded_interaction(
            0, 0, GenericLennardJonesInteraction, {
                "epsilon": 1.2,
                "sigma": 2.2,
                "cutoff": 3.2,
                "shift": 4.2,
                "offset": 5.2,
                "e1": 72,
                "e2": 82,
                "b1": 9.2,
                "b2": 10.2
            }, "generic_lennard_jones")

    def test_forcecap(self):
        self.es.non_bonded_inter.set_force_cap(17.5)
        self.assertEqual(self.es.non_bonded_inter.get_force_cap(), 17.5)
Beispiel #21
0
    def dissipation_param_setup(self, n):
        """
        Setup the parameters for the following dissipation
        test.

        Parameters
        ----------
        n : :obj:`int`
            Number of particles of the each type. There are 2 types.

        """

        # Time
        self.system.time_step = 0.007

        # Space
        box = 1.0
        self.system.box_l = box, box, box
        if espressomd.has_features(("PARTIAL_PERIODIC", )):
            self.system.periodicity = 0, 0, 0

        # NVT thermostat
        self.kT = 0.0
        # The translational gamma isotropy is required here.
        # Global gamma for tests without particle-specific gammas.
        #
        # As far as the problem characteristic time is t0 ~ mass / gamma
        # and the Langevin equation finite-difference approximation is stable
        # only for time_step << t0, it is needed to set the gamma less than
        # some maximal value according to the value gamma_max.
        # Also, it cannot be very small (gamma_min), otherwise the thermalization will require
        # too much of the CPU time. Same: for all such gamma assignments throughout the test.
        #
        gamma_min = self.gamma_min
        gamma_max = self.gamma_max
        gamma_rnd = uniform(gamma_min, gamma_max)
        self.gamma_global = gamma_rnd, gamma_rnd, gamma_rnd
        # Additional test case for the specific global rotational gamma set.
        self.gamma_global_rot = uniform(gamma_min, gamma_max, 3)
        # Per-paricle values:
        self.kT_p = 0.0, 0.0
        # Either translational friction isotropy is required
        # or both translational and rotational ones.
        # Otherwise these types of motion will interfere.
        # ..Let's test both cases depending on the particle index.
        self.gamma_tran_p[0, 0] = uniform(gamma_min, gamma_max)
        self.gamma_tran_p[0, 1] = self.gamma_tran_p[0, 0]
        self.gamma_tran_p[0, 2] = self.gamma_tran_p[0, 0]
        self.gamma_rot_p[0, :] = uniform(gamma_min, gamma_max, 3)
        self.gamma_tran_p[1, 0] = uniform(gamma_min, gamma_max)
        self.gamma_tran_p[1, 1] = self.gamma_tran_p[1, 0]
        self.gamma_tran_p[1, 2] = self.gamma_tran_p[1, 0]
        self.gamma_rot_p[1, 0] = uniform(gamma_min, gamma_max)
        self.gamma_rot_p[1, 1] = self.gamma_rot_p[1, 0]
        self.gamma_rot_p[1, 2] = self.gamma_rot_p[1, 0]

        # Particles
        self.mass = 12.74
        self.J = 10.0, 10.0, 10.0
        for i in range(n):
            for k in range(2):
                ind = i + k * n
                self.system.part.add(rotation=(1, 1, 1),
                                     pos=(0.0, 0.0, 0.0),
                                     id=ind)
                self.system.part[ind].v = 1.0, 1.0, 1.0
                if "ROTATION" in espressomd.features():
                    self.system.part[ind].omega_body = 1.0, 1.0, 1.0
                self.system.part[ind].mass = self.mass
                self.system.part[ind].rinertia = self.J
Beispiel #22
0
from __future__ import print_function
import unittest as ut
import numpy as np
import espressomd


if "ENGINE" in espressomd.features():
    class SwimmerTest(ut.TestCase):
        def test(self):
            boxl = 12
            sampsteps = 2000
            tstep = 0.01

            v_swim = 0.3
            f_swim = 0.1
            temp = 0.0
            gamma = 1.0

            pos_0 = np.array([boxl/2., boxl/2., 1.*boxl/3.])
            pos_1 = np.array([boxl/2., boxl/2., 2.*boxl/3.])

            def z_f(t,z0):
                return f_swim/gamma*(-1./gamma + t + (1./gamma)*np.exp(-gamma*t))+z0

            def z_v(t,z0):
                return v_swim*(-1./gamma + t + (1./gamma)*np.exp(-gamma*t))+z0

            S = espressomd.System()

            S.box_l = [boxl, boxl, boxl]
            S.cell_system.skin = 0.1
#
# ESPResSo is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Tests particle property setters/getters
import unittest as ut
import espressomd
import numpy as np
from espressomd.interactions import LennardJonesInteraction

if "LENNARD_JONES_GENERIC" in espressomd.features():
    from espressomd.interactions import GenericLennardJonesInteraction


class Non_bonded_interactionsTests(ut.TestCase):
    #  def __init__(self,particleId):
    #    self.pid=particleId

    # Handle to espresso system
    es = espressomd.System()

    def intersMatch(self, inType, outType, inParams, outParams):
        """Check, if the interaction type set and gotten back as well as the bond 
        parameters set and gotten back match. Only check keys present in
        inParams.
        """
        "genericLennardJones",
    )
    test_ljgen3 = generateTestForNonBondedInteraction(
        0,
        0,
        GenericLennardJonesInteraction,
        {
            "epsilon": 1.2,
            "sigma": 2.2,
            "cutoff": 3.2,
            "shift": 4.2,
            "offset": 5.2,
            "e1": 72,
            "e2": 82,
            "b1": 9.2,
            "b2": 10.2,
            "lambda": 11.2,
            "delta": 12.2,
        },
        "genericLennardJones",
    )

    def test_forcecap(self):
        self.es.nonBondedInter.setForceCap(17.5)
        self.assertEqual(self.es.nonBondedInter.getForceCap(), 17.5)


if __name__ == "__main__":
    print("Features: ", espressomd.features())
    ut.main()
#
# ESPResSo is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Tests particle property setters/getters
import unittest as ut
import espressomd
import numpy as np
from espressomd.interactions import LennardJonesInteraction

if "LENNARD_JONES_GENERIC" in espressomd.features():
    from espressomd.interactions import GenericLennardJonesInteraction

class Non_bonded_interactionsTests(ut.TestCase):
    #  def __init__(self,particleId):
    #    self.pid=particleId

    # Handle to espresso system
    es = espressomd.System()

    def intersMatch(self, inType, outType, inParams, outParams):
        """Check, if the interaction type set and gotten back as well as the bond 
        parameters set and gotten back match. Only check keys present in
        inParams.
        """
        if inType != outType:
Beispiel #26
0
    def dissipation_param_setup(self):
        """
        Setup the parameters for the following dissipation
        test.

        """

        ## Time
        self.es.time_step = 0.007
        
        ## Space
        box = 1.0
        self.es.box_l = box,box,box
        if espressomd.has_features(("PARTIAL_PERIODIC",)):
            self.es.periodicity = 0,0,0
        
        ## NVT thermostat
        self.kT = 0.0
        # The translational gamma isotropy is required here.
        # Global gamma for tests without particle-specific gammas.
        #
        # As far as the problem characteristic time is t0 ~ mass / gamma
        # and the Langevin equation finite-difference approximation is stable
        # only for time_step << t0, it is needed to set the gamma less than
        # some maximal value according to the value max_gamma_param.
        # Also, it cannot be very small (min_gamma_param), otherwise the thermalization will require
        # too much of the CPU time. Same: for all such gamma assignments throughout the test.
        #
        min_gamma_param = 0.5
        max_gamma_param = 2.0/3.0
        gamma_rnd = self.generate_scalar_ranged_rnd(min_gamma_param, max_gamma_param)
        self.gamma_global = gamma_rnd, gamma_rnd, gamma_rnd
        # Additional test case for the specific global rotational gamma set.
        self.gamma_global_rot = self.generate_vec_ranged_rnd(0.5,2.0/3.0)
        # Per-paricle values:
        self.kT_p = 0.0,0.0
        # Either translational friction isotropy is required
        # or both translational and rotational ones.
        # Otherwise these types of motion will interfere.
        # ..Let's test both cases depending on the particle index.
        self.gamma_tran_p[0, 0] = self.generate_scalar_ranged_rnd(0.5,1.0)
        self.gamma_tran_p[0, 1] = self.gamma_tran_p[0, 0]
        self.gamma_tran_p[0, 2] = self.gamma_tran_p[0, 0]
        self.gamma_rot_p[0, :] = self.generate_vec_ranged_rnd(0.5,2.0/3.0)
        self.gamma_tran_p[1, 0] = self.generate_scalar_ranged_rnd(0.5,1.0)
        self.gamma_tran_p[1, 1] = self.gamma_tran_p[1, 0]
        self.gamma_tran_p[1, 2] = self.gamma_tran_p[1, 0]
        self.gamma_rot_p[1, 0] = self.generate_scalar_ranged_rnd(0.5,2.0/3.0)
        self.gamma_rot_p[1, 1] = self.gamma_rot_p[1, 0]
        self.gamma_rot_p[1, 2] = self.gamma_rot_p[1, 0]
        
        ## Particles
        self.mass = 12.74
        self.J = 10.0,10.0,10.0
        for i in range(2):
            self.es.part.add(rotation=(1,1,1), pos=(0.0,0.0,0.0), id=i)
            self.es.part[i].v = 1.0,1.0,1.0
            if "ROTATION" in espressomd.features():
                self.es.part[i].omega_body = 1.0,1.0,1.0
            self.es.part[i].mass = self.mass
            self.es.part[i].rinertia = self.J
Beispiel #27
0
class ParticleProperties(ut.TestCase):
    #  def __init__(self,particleId):
    #    self.pid=particleId

    # Particle id to work on
    pid = 17

    # Error tolerance when comparing arrays/tuples...
    tol = 1E-9

    # Handle for espresso system
    es = espressomd.System()

    def arraysNearlyEqual(self, a, b):
        """Test, if the magnitude of the difference between two arrays is smaller than the tolerance"""

        # Check length
        if len(a) != len(b):
            return False

        # We have to use a loop, since we can't be sure, we're getting numpy arrays
        sum = 0.
        for i in range(len(a)):
            sum += abs(a[i] - b[i])

        if sum > self.tol:
            return False

        return True

    def setUp(self):
        self.es.part[self.pid].pos = 0, 0, 0
        self.es.bondedInter[0] = FeneBond(k=1, d_r_max=5)
        self.es.bondedInter[1] = FeneBond(k=1, d_r_max=5)

    def generateTestForVectorProperty(_propName, _value):
        """Generates test cases for vectorial particle properties such as
    position, velocity...
    1st arg: name of the property (e.g., "pos"), 
    2nd array: value to be used for testing. Has to be numpy.array of floats
    """
        # This is executed, when generateTestForVectorProperty() is called
        propName = _propName
        value = _value

        def func(self):
            # This code is run at the execution of the generated function.
            # It will use the state of the variables in the outer function,
            # which was there, when the outer function was called
            setattr(self.es.part[self.pid], propName, value)
            print(propName, value, getattr(self.es.part[self.pid], propName))
            self.assertTrue(
                self.arraysNearlyEqual(
                    getattr(self.es.part[self.pid], propName), value),
                propName + ": value set and value gotten back differ.")

        return func

    def generateTestForScalarProperty(_propName, _value):
        """Generates test cases for scalar particle properties such as
    type, mass, charge...
    1st arg: name of the property (e.g., "type"), 
    2nd array: value to be used for testing. int or float
    """
        # This is executed, when generateTestForVectorProperty() is called
        propName = _propName
        value = _value

        def func(self):
            # This code is run at the execution of the generated function.
            # It will use the state of the variables in the outer function,
            # which was there, when the outer function was called
            setattr(self.es.part[self.pid], propName, value)
            print(propName, value, getattr(self.es.part[self.pid], propName))
            self.assertTrue(
                getattr(self.es.part[self.pid], propName) == value,
                propName + ": value set and value gotten back differ.")

        return func

    test_pos = generateTestForVectorProperty("pos", np.array([0.1, 0.2, 0.3]))
    test_v = generateTestForVectorProperty("v", np.array([0.2, 0.3, 0.4]))
    test_f = generateTestForVectorProperty("f", np.array([0.2, 0.3, 0.7]))
    test_type = generateTestForScalarProperty("type", int(3))
    test_bonds_property = generateTestForScalarProperty(
        "bonds", ((0, 1), (1, 2)))

    if "MASS" in espressomd.features():
        test_mass = generateTestForScalarProperty("mass", 1.3)

    if "ROTATION" in espressomd.features():
        test_omega_lab = generateTestForVectorProperty("omega_lab",
                                                       np.array([4., 2., 1.]))
        test_omega_body = generateTestForVectorProperty(
            "omega_body", np.array([4., 72., 1.]))
        test_torque_lab = generateTestForVectorProperty(
            "torque_lab", np.array([4., 72., 3.7]))
        # The tested value has to be nromalized!
        test_quat = generateTestForVectorProperty(
            "quat", np.array([0.5, 0.5, 0.5, 0.5]))


#    test_director=generateTestForVectorProperty("director",np.array([0.5,0.4,0.3]))

    if "ELECTROSTATICS" in espressomd.features():
        test_charge = generateTestForScalarProperty("q", -19.7)

    if "DIPOLES" in espressomd.features():
        test_dip = generateTestForVectorProperty("dip",
                                                 np.array([0.5, -0.5, 3]))
        test_dipm = generateTestForScalarProperty("dipm", -9.7)

    if "VIRTUAL_SITES" in espressomd.features():
        test_virtual = generateTestForScalarProperty("virtual", 1)
    if "VIRTUAL_SITES_RELATIVE" in espressomd.features():
        test_zz_vs_relative = generateTestForScalarProperty(
            "vs_relative", ((0, 5.0)))
class CoulombCloudWall(ut.TestCase):
    """This compares p3m, p3m_gpu, scafacos_p3m and scafacos_p2nfft 
       electrostatic forces and energy against stored data."""
    S = espressomd.System()
    forces = {}
    tolerance = 1E-3

    # Reference energy from p3m in the tcl test case
    reference_energy = 148.94229549

    def setUp(self):
        self.S.box_l = (10, 10, 10)
        self.S.time_step = 0.01
        self.S.skin = 0.4

        #  Clear actors that might be left from prev tests
        if len(self.S.actors):
            del self.S.actors[0]
        self.S.part.clear()
        data = np.genfromtxt("data/coulomb_cloud_wall_system.data")

        # Add particles to system and store reference forces in hash
        # Input format: id pos q f
        for particle in data:
            id = particle[0]
            pos = particle[1:4]
            q = particle[4]
            f = particle[5:]
            self.S.part.add(id=int(id), pos=pos, q=q)
            self.forces[id] = f

    def compare(self, method_name, energy=True):
        # Compare forces and energy now in the system to stored ones

        # Force
        force_abs_diff = 0.
        for p in self.S.part:
            force_abs_diff += abs(np.sqrt(sum((p.f - self.forces[p.id])**2)))
        force_abs_diff /= len(self.S.part)

        print method_name, "force difference", force_abs_diff

        # Energy
        if energy:
            energy_abs_diff = abs(self.S.analysis.energy(
                self.S)["total"] - self.reference_energy)
            print method_name, "energy difference", energy_abs_diff
            self.assertTrue(energy_abs_diff <= self.tolerance, "Absolte energy difference " +
                            str(energy_abs_diff) + " too large for " + method_name)
        self.assertTrue(force_abs_diff <= self.tolerance, "Asbolute force difference " +
                        str(force_abs_diff) + " too large for method " + method_name)

    # Tests for individual methods

    if "P3M" in espressomd.features():
        def test_p3m(self):
            self.S.actors.add(P3M(bjerrum_length=1, r_cut=1.001,
                                  mesh=64, cao=7, alpha=2.70746, tune=False))
            integrate(0)
            self.compare("p3m", energy=True)

    if "ELECTROSTATICS" in espressomd.features() and "CUDA" in espressomd.features():
        def test_p3m_gpu(self):
            self.S.actors.add(P3M_GPU(
                bjerrum_length=1, r_cut=1.001, mesh=64, cao=7, alpha=2.70746, tune=False))
            integrate(0)
            self.compare("p3m_gpu", energy=False)

    if "SCAFACOS" in espressomd.features():
        if "p3m" in scafacos.available_methods():
            def test_scafacos_p3m(self):
                self.S.actors.add(Scafacos(bjerrum_length=1, method_name="p3m", method_params={
                                  "p3m_r_cut": 1.001, "p3m_grid": 64, "p3m_cao": 7, "p3m_alpha": 2.70746}))
                integrate(0)
                self.compare("scafacos_p3m", energy=True)

        if "p2nfft" in scafacos.available_methods():
            def test_scafacos_p2nfft(self):
                self.S.actors.add(Scafacos(bjerrum_length=1, method_name="p2nfft", method_params={
                                  "p2nfft_r_cut": 1.001, "tolerance_field": 1E-4}))
                integrate(0)
                self.compare("scafacos_p2nfft", energy=True)

    def test_zz_deactivation(self):
        # Is the energy 0, if no methods active
        self.assertTrue(self.S.analysis.energy(self.S)["total"] == 0.0)
Beispiel #29
0
import unittest as ut
import numpy as np
import espressomd
from espressomd import thermostat
from espressomd import integrate

if "ENGINE" in espressomd.features():

    class SwimmerTest(ut.TestCase):
        def test(self):
            boxl = 12
            sampsteps = 2000
            tstep = 0.01

            v_swim = 0.3
            f_swim = 0.1
            temp = 0.0
            gamma = 1.0

            pos_0 = np.array([boxl / 2., boxl / 2., 1. * boxl / 3.])
            pos_1 = np.array([boxl / 2., boxl / 2., 2. * boxl / 3.])

            def z_f(t, z0):
                return f_swim / gamma * (
                    -1. / gamma + t + (1. / gamma) * np.exp(-gamma * t)) + z0

            def z_v(t, z0):
                return v_swim * (-1. / gamma + t +
                                 (1. / gamma) * np.exp(-gamma * t)) + z0

            S = espressomd.System()
Beispiel #30
0
        self.s.part.add(id=0, pos=[0, 0, 0], type=0, q=+1.)
        self.s.part.add(id=1, pos=[1, 0, 0], type=0, q=-1.)

        # Small alpha means large short-range contribution
        self.s.actors.add(P3M(prefactor=1, r_cut=3.0, accuracy=1e-3,
                                  mesh=32, cao=7, alpha=0.1, tune=False))

        # Only short-range part of the coulomb energy
        pair_energy = self.s.analysis.energy()[('coulomb', 0)]
        self.assertGreater(abs(pair_energy), 0.)

        self.s.integrator.run(0)
        pair_force = self.s.part[0].f[0]
        self.assertGreater(abs(pair_force), 0.)
        self.assertAlmostEqual(self.s.part[1].f[0], -pair_force, places=7)

        pair_pressure = self.s.analysis.pressure()[('coulomb', 0)]
        self.assertGreater(abs(pair_pressure), 0.)

        self.s.part[0].exclusions = [1]
        # Force and energy should not be changed by the exclusion
        self.s.integrator.run(0)
        self.assertAlmostEqual(self.s.part[0].f[0], pair_force, places=7)
        self.assertAlmostEqual(self.s.part[1].f[0], -pair_force, places=7)
        self.assertAlmostEqual(self.s.analysis.energy()[('coulomb', 0)], pair_energy, places=7)
        self.assertAlmostEqual(self.s.analysis.pressure()[('coulomb', 0)], pair_pressure, places=7)

if __name__ == "__main__":
    print("Features: ", espressomd.features())
    ut.main()
class CoulombCloudWall(ut.TestCase):
    if "ELECTROSTATICS" in espressomd.features():
        """This compares p3m, p3m_gpu, scafacos_p3m and scafacos_p2nfft
           electrostatic forces and energy against stored data."""
        S = espressomd.System(box_l=[1.0, 1.0, 1.0])
        S.seed = S.cell_system.get_state()['n_nodes'] * [1234]
        np.random.seed(S.seed)

        forces = {}
        tolerance = 1E-3

        # Reference energy from p3m in the tcl test case
        reference_energy = 2. * 148.94229549

        def setUp(self):
            self.S.box_l = (10, 10, 20)
            self.S.time_step = 0.01
            self.S.cell_system.skin = 0.4

            #  Clear actors that might be left from prev tests
            if self.S.actors:
                del self.S.actors[0]
            self.S.part.clear()
            data = np.genfromtxt(
                abspath("data/coulomb_cloud_wall_duplicated_system.data"))

            # Add particles to system and store reference forces in hash
            # Input format: id pos q f
            for particle in data:
                id = particle[0]
                pos = particle[1:4]
                q = particle[4]
                f = particle[5:]
                self.S.part.add(id=int(id), pos=pos, q=q)
                self.forces[id] = f

        def compare(self, method_name, energy=True):
            # Compare forces and energy now in the system to stored ones
            # Force
            force_abs_diff = 0.
            for p in self.S.part:
                force_abs_diff += abs(
                    np.sqrt(sum((p.f - self.forces[p.id])**2)))
            force_abs_diff /= len(self.S.part)

            # Energy
            if energy:
                energy_abs_diff = abs(self.S.analysis.energy()["total"] -
                                      self.reference_energy)
                self.assertTrue(
                    energy_abs_diff <= self.tolerance,
                    "Absolute energy difference " + str(energy_abs_diff) +
                    " too large for " + method_name)
            self.assertTrue(
                force_abs_diff <= self.tolerance,
                "Absolute force difference " + str(force_abs_diff) +
                " too large for method " + method_name)

        # Tests for individual methods

        if "P3M" in espressomd.features():

            def test_p3m(self):
                self.S.actors.add(
                    espressomd.electrostatics.P3M(prefactor=1,
                                                  r_cut=1.001,
                                                  accuracy=1e-3,
                                                  mesh=[64, 64, 128],
                                                  cao=7,
                                                  alpha=2.70746,
                                                  tune=False))
                self.S.integrator.run(0)
                self.compare("p3m", energy=True)

        @ut.skipIf(not espressomd.gpu_available(), "No gpu")
        def test_p3m_gpu(self):
            if str(espressomd.cuda_init.CudaInitHandle().device_list[0]
                   ) == "Device 687f":
                print("Test skipped on AMD GPU")
                return
            self.S.actors.add(
                espressomd.electrostatics.P3MGPU(prefactor=1,
                                                 r_cut=1.001,
                                                 accuracy=1e-3,
                                                 mesh=[64, 64, 128],
                                                 cao=7,
                                                 alpha=2.70746,
                                                 tune=False))
            self.S.integrator.run(0)
            self.compare("p3m_gpu", energy=False)

        def test_zz_deactivation(self):
            # Is the energy 0, if no methods active
            self.assertTrue(self.S.analysis.energy()["total"] == 0.0)
Beispiel #32
0
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
"""
This sample illustrates how particles of interest can be accessed via slicing.
"""
import espressomd
from espressomd import thermostat
import numpy as np

print("""
=======================================================
=                   slice_input.py                    =
=======================================================

Program Information:""")
print(espressomd.features())

# System parameters
#############################################################

box_l = 10.0

# Integration parameters
#############################################################

system = espressomd.System(box_l=[box_l] * 3)
system.set_random_state_PRNG()
#system.seed = system.cell_system.get_state()['n_nodes'] * [1234]
np.random.seed(seed=system.seed)

system.time_step = 0.01
Beispiel #33
0
    def check_fluctuation_dissipation(self,n):
        """
        Check the fluctuation-dissipation relations: thermalization
        and diffusion properties.
    
        Parameters
        ----------
        n : :obj:`int`
            Number of particles of the each type. There are 2 types.

        """

        ## The thermalization and diffusion test
        # Checks if every degree of freedom has 1/2 kT of energy, even when
        # mass and inertia tensor are active
        # Check the factual translational diffusion.
        #
        # matrices: [2 types of particless] x [3 dimensions X Y Z]
        # velocity^2, omega^2, position^2
        v2 = np.zeros((2, 3))
        o2 = np.zeros((2, 3))
        dr2 = np.zeros((2, 3))
        # Variance to compare with:
        sigma2_tr = np.zeros((2))
        # Comparable variance:
        dr_norm = np.zeros((2))

        pos0 = np.zeros((2 * n, 3))
        for p in range(n):
            for k in range(2):
                ind = p + k * n
                pos0[ind, :] = self.es.part[ind].pos
        dt0 = self.mass / self.gamma_tran_p_validate

        loops = 250
        print("Thermalizing...")
        therm_steps = 20
        self.es.integrator.run(therm_steps)
        print("Measuring...")

        int_steps = 5
        for i in range(loops):
            self.es.integrator.run(int_steps)
            # Get kinetic energy in each degree of freedom for all particles
            for p in range(n):
                for k in range(2):
                    ind = p + k * n
                    v = self.es.part[ind].v
                    if "ROTATION" in espressomd.features():
                        o = self.es.part[ind].omega_body
                        o2[k, :] = o2[k, :] + np.power(o[:], 2)
                    pos = self.es.part[ind].pos
                    v2[k, :] = v2[k, :] + np.power(v[:], 2)
                    dr2[k, :] = np.power((pos[:] - pos0[ind, :]), 2)
                    dt = (int_steps * (i + 1) + therm_steps) * \
                        self.es.time_step
                    # translational diffusion variance: after a closed-form
                    # integration of the Langevin EOM;
                    # ref. the eq. (10.2.26) N. Pottier, https://doi.org/10.1007/s10955-010-0114-6 (2010)
                    # after simple transformations and the dimensional model matching (cf. eq. (10.1.1) there):
                    sigma2_tr[k] = 0.0
                    for j in range(3):
                        sigma2_tr[k] += self.D_tran_p_validate[k,
                                                           j] * (2.0 * dt + dt0[k,
                                                                              j] * (- 3.0 + 4.0 * math.exp(- dt / dt0[k,
                                                                                                                  j]) - math.exp(- 2.0 * dt / dt0[k,
                                                                                                                                                j])))
                    dr_norm[k] += (sum(dr2[k, :]) - sigma2_tr[k]) / sigma2_tr[k]

        tolerance = 0.15
        Ev = 0.5 * self.mass * v2 / (n * loops)
        Eo = 0.5 * self.J * o2 / (n * loops)
        dv = np.zeros((2))
        do = np.zeros((2))
        do_vec = np.zeros((2, 3))
        for k in range(2):
            dv[k] = sum(Ev[k, :]) / (3.0 * self.halfkT_p_validate[k]) - 1.0
            do[k] = sum(Eo[k, :]) / (3.0 * self.halfkT_p_validate[k]) - 1.0
            do_vec[k, :] = Eo[k, :] / self.halfkT_p_validate[k] - 1.0
        dr_norm /= (n * loops)
        
        for k in range(2):
            print("\n")
            print("k = " + str(k))

            self.assertLessEqual(
                abs(
                    dv[k]),
                tolerance,
                msg='Relative deviation in translational energy too large: {0}'.format(
                    dv[k]))
            if "ROTATION" in espressomd.features():
                self.assertLessEqual(
                    abs(
                        do[k]),
                    tolerance,
                    msg='Relative deviation in rotational energy too large: {0}'.format(
                        do[k]))
                self.assertLessEqual(abs(
                    do_vec[k, 0]), tolerance, msg='Relative deviation in rotational energy per the body axis X is too large: {0}'.format(do_vec[k, 0]))
                self.assertLessEqual(abs(
                    do_vec[k, 1]), tolerance, msg='Relative deviation in rotational energy per the body axis Y is too large: {0}'.format(do_vec[k, 1]))
                self.assertLessEqual(abs(
                    do_vec[k, 2]), tolerance, msg='Relative deviation in rotational energy per the body axis Z is too large: {0}'.format(do_vec[k, 2]))
            self.assertLessEqual(
                abs(
                    dr_norm[k]),
                tolerance,
                msg='Relative deviation in translational diffusion is too large: {0}'.format(
                    dr_norm[k]))