Пример #1
0
 def test_change_species(self):
     from copy import deepcopy
     from atooms.system import System, Particle
     system_A = System([Particle(species='A'), Particle(species='B')])
     system_C = System([Particle(species='0'), Particle(species='1')])
     system_F = System([Particle(species='1'), Particle(species='2')])
     from atooms.trajectory.decorators import change_species
     # DO nothing here
     self.assertTrue(
         _equal(system_A, change_species(deepcopy(system_A), 'A')))
     self.assertTrue(
         _equal(system_C, change_species(deepcopy(system_C), 'C')))
     self.assertTrue(
         _equal(system_F, change_species(deepcopy(system_F), 'F')))
     # Change
     self.assertTrue(
         _equal(system_C, change_species(deepcopy(system_A), 'C')))
     self.assertTrue(
         _equal(system_F, change_species(deepcopy(system_A), 'F')))
     self.assertTrue(
         _equal(system_A, change_species(deepcopy(system_C), 'A')))
     self.assertTrue(
         _equal(system_F, change_species(deepcopy(system_C), 'F')))
     self.assertTrue(
         _equal(system_A, change_species(deepcopy(system_F), 'A')))
     self.assertTrue(
         _equal(system_C, change_species(deepcopy(system_F), 'C')))
Пример #2
0
    def test_view(self):
        import numpy
        from atooms.system import Particle, System

        p = [Particle(), Particle()]
        s = System(p)
        pos = s.dump("pos", order='F', view=True)

        # Modify the dumped array in place preserves the view
        pos[:, 0] += 1.0
        self.assertTrue((p[0].position == pos[:, 0]).all())
        self.assertTrue(numpy.may_share_memory(p[0].position, pos[:, 0]))
        # Modify the position array in place preserves the view
        p[0].position *= 2
        self.assertTrue((p[0].position == pos[:, 0]).all())
        self.assertTrue(numpy.may_share_memory(p[0].position, pos[:, 0]))
        # Modify the position array in place preserves the view
        p[0].position[:] = p[0].position[:] + 4
        self.assertTrue((p[0].position == pos[:, 0]).all())
        self.assertTrue(numpy.may_share_memory(p[0].position, pos[:, 0]))
        pos[:, 0] = pos[:, 0] + 1.0
        self.assertTrue((p[0].position == pos[:, 0]).all())
        self.assertTrue(numpy.may_share_memory(p[0].position, pos[:, 0]))
        # Reassining the position will of course destroy the view
        p[0].position = p[0].position * 2
        self.assertFalse((p[0].position == pos[:, 0]).all())
        self.assertFalse(numpy.may_share_memory(p[0].position, pos[:, 0]))
Пример #3
0
 def test_interacting_system(self):
     p = PairPotential('lennard_jones', {
         'epsilon': 1.0,
         'sigma': 1.0
     }, [1, 1], CutOff('CS', 2.5))
     i = Interaction(p, 'atomic')
     s = System()
     s.interaction = i
Пример #4
0
 def setUp(self):
     N = 100
     L = 10.0
     self.ref = System()
     self.ref.cell = Cell([L, L, L])
     self.ref.particle = []
     self.ref.thermostat = Thermostat(1.0)
     self.ref.barostat = Barostat(1.0)
     self.ref.reservoir = Reservoir(1.0)
     while len(self.ref.particle) <= N:
         pos = [(random.random() - 0.5) * L, (random.random() - 0.5) * L,
                (random.random() - 0.5) * L]
         self.ref.particle.append(Particle(position=pos))
Пример #5
0
 def setUp(self):
     import copy
     particle = [
         Particle(position=[0.0, 0.0, 0.0], species='A', mass=1.0),
         Particle(position=[1.0, 1.0, 1.0], species='B', mass=2.0),
     ]
     cell = Cell([2.0, 2.0, 2.0])
     self.system = []
     self.system.append(System(copy.deepcopy(particle), cell))
     self.system.append(System(copy.deepcopy(particle), cell))
     self.inpfile = '/tmp/test_trajectory'
     self.inpdir = '/tmp/test_trajectory.d'
     from atooms.core.utils import mkdir
     mkdir(self.inpdir)
Пример #6
0
 def test_ovito(self):
     try:
         import ovito
     except ImportError:
         self.skipTest('missing ovito')
     N = 3
     L = 5.0
     system = System()
     system.cell = Cell([L, L, L])
     system.particle = []
     for _ in range(N):
         pos = (numpy.random.random(len(system.cell.side)) -
                0.5) * system.cell.side
         p = Particle(position=pos)
         system.particle.append(p)
     image = system.show('ovito')
Пример #7
0
def dump_config(filename,
                pos=None,
                diam=None,
                ptypes=None,
                box=None,
                compress=None):
    file_ext = os.path.splitext(filename)[1]
    cell = Cell(side=box)
    npart = pos.shape[0]

    particles = []
    for i in range(npart):
        p = Particle(species=ptypes[i],
                     position=pos[i, :] - box / 2.,
                     radius=diam[i] / 2.)
        particles.append(p)

    system = System(particle=particles, cell=cell)

    with Trajectory(filename, "w") as traj:
        # Step is always 0 for now.
        traj.write(system, 0)

    if file_ext == ".xyz":
        compress = True
    else:
        compress = False

    if compress:
        subprocess.run(["gzip", "-f", filename])
Пример #8
0
    def read_sample(self, frame):
        """ returns System instance. """
        snap = self.trajectory[frame]
        ndim = snap.configuration.dimensions

        # Convert typeid from [0, 0, 1, ...] to ['A', 'A', 'B', ...] when snap.particles.types = ['A', 'B']
        distinct_species = snap.particles.types
        distinct_typeids = list(range(len(distinct_species)))
        typeid_to_species = {}
        for i in distinct_typeids:
            typeid_to_species[i] = distinct_species[i]

        box = snap.configuration.box[:
                                     ndim]  # atooms does not handle sheared boxes.
        cell = Cell(side=box)

        N = snap.particles.position.shape[0]
        particles = []
        for i in range(N):
            p = Particle(mass=snap.particles.mass[i],
                         species=typeid_to_species[snap.particles.typeid[i]],
                         position=snap.particles.position[i, :ndim],
                         velocity=snap.particles.velocity[i, :ndim],
                         radius=snap.particles.diameter[i] / 2)
            particles.append(p)

        return System(particle=particles, cell=cell)
Пример #9
0
 def test_ram_inplace(self):
     particle = [Particle(position=[0.0, 0.0, 0.0])]
     system = System(particle)
     t = TrajectoryRam()
     t[0] = system
     particle[0].position += 1.0
     self.assertFalse(
         (t[0].particle[0].position == particle[0].position).all())
Пример #10
0
 def test_ram(self):
     particle = [Particle(position=[0.0, 0.0, 0.0])]
     system = System(particle)
     t = TrajectoryRam()
     t[0] = system
     particle[0].position = numpy.array([1.0, 1.0, 1.0])
     self.assertFalse(
         (t[0].particle[0].position == particle[0].position).all())
Пример #11
0
    def test_write_initial_state(self):
        p = [
            PairPotential('lennard_jones', {
                'epsilon': 1.0,
                'sigma': 1.0
            }, [1, 1], CutOff('CS', 2.5))
        ]
        i = [Interaction(p, 'atomic')]
        s = System()
        s.cell = Cell([1.0, 1.0, 1.0])
        t = TrajectoryHDF5('/tmp/test_potential.h5', 'w')
        t.write_interaction(i)
        t.close()

        t = TrajectoryHDF5('/tmp/test_potential.h5', 'r')
        i = t.read_interaction()
        t.close()
Пример #12
0
    def test_ram_copy(self):
        particle = [Particle(position=[0.0, 0.0, 0.0])]
        system = System(particle)
        t = TrajectoryRam()
        t[0] = system
        t[0].particle[0].position = numpy.array([1.0, 1.0, 1.0])
        # print system.particle[0].position, t[0].particle[0].position
        # print id(t[0].particle[0])
        # print id(t[0].particle[0])

        particle = [Particle(position=[0.0, 0.0, 0.0])]
        system = System(particle)
        s = System(particle)
        t = TrajectoryRamFull()
        t[0] = system
        s.update(t[0])
        s.particle[0].position = numpy.array([1.0, 1.0, 1.0])
        # print system.particle[0].position, t[0].particle[0].position, s.particle[0].position
        # print id(t[0].particle[0])
        # print id(t[0].particle[0])

        particle = [Particle(position=[0.0, 0.0, 0.0])]
        system = System(particle)
        t = TrajectoryRamFull()
        t[0] = system
        system.particle[0].position = numpy.array([1.0, 1.0, 1.0])
Пример #13
0
    def test_dump_cbk(self):
        """
        Make sure that applying callbacks or changing the particle array
        size creates a new dump.
        """
        import numpy
        from atooms.system import Particle, System

        for view in [False, True]:
            p = [Particle(), Particle()]
            s = System(p)
            pos1 = s.dump("pos", view=view)

            def cbk(system):
                s = copy.copy(system)
                s.particle = [system.particle[0]]
                return s

            s = cbk(s)
            pos2 = s.dump('pos', view=view)
            self.assertEqual(pos1.shape, (2, 3))
            self.assertEqual(pos2.shape, (1, 3))
            # Grandcanonical
            s.particle.append(Particle())
            self.assertEqual(s.dump('pos', view=view).shape, (2, 3))
            # Reassign particle
            # Expected failure with view = True
            if not view:
                s.particle[0] = Particle(position=[1.0, 1.0, 1.0])
                self.assertEqual(s.dump('pos', view=view)[0][0], 1.0)
Пример #14
0
 def read_sample(self, frame):
     cfg, box, pos, typ, vel = self.__read_one(self.__f_frames[frame])
     if vel is None:
         particle = [Particle(species=t, position=numpy.array(p)) for p, t in zip(pos, typ)]
     else:
         particle = [Particle(species=t, position=numpy.array(p), velocity=numpy.array(v))
                     for p, t, v in zip(pos, typ, vel)]
     cell = Cell(numpy.array(box))
     return System(particle, cell)
Пример #15
0
    def test_dump_species(self):
        """
        Make sure that changing species in the dump is reflected in the
        particle species and viceversa.
        """
        import numpy
        from atooms.system import Particle, System

        view = True
        p = [Particle(), Particle()]
        s = System(p)
        spe = s.dump("particle.species", view=True)
        spe[0] = 'B'
        self.assertEqual(spe[0], s.particle[0].species)
        # With this syntax, the numpy scalar preserves the view!
        # We should upgrade species to property and hide this inside
        s.particle[0].species[()] = 'C'
        self.assertEqual(spe[0], s.particle[0].species)
Пример #16
0
 def test_ram_full(self):
     particle = [Particle(position=[0.0, 0.0, 0.0])]
     system = System(particle)
     t = TrajectoryRamFull()
     t[0] = system
     system.particle[0].position = numpy.array([2.0, 2.0, 2.0])
     t[0] = system
     particle[0].position += 1.0
     self.assertFalse(
         (t[0].particle[0].position == particle[0].position).all())
Пример #17
0
    def test_write_initial_state(self):
        p = [
            PairPotential("lennard_jones", {
                "epsilon": 1.0,
                "sigma": 1.0
            }, [1, 1], CutOff("CS", 2.5))
        ]
        i = [Interaction(p, "atomic")]
        s = System()
        s.particle = [
            Particle(position=[1.0, 1.0, 1.0], velocity=[0.0, 0.0, 0.0])
        ]
        s.cell = Cell([1.0, 1.0, 1.0])
        with TrajectoryHDF5('/tmp/test_hdf5.h5', 'w') as t:
            t.write_interaction(i)
            t.write(s, 0)

        with TrajectoryHDF5('/tmp/test_hdf5.h5', 'r') as t:
            i = t.read_interaction()
            s = t[0]
Пример #18
0
    def test_view_clear(self):
        import numpy
        from atooms.system import Particle, System

        p = [Particle(), Particle()]
        s = System(p)

        # We check that particle positions are views on dump array
        pos = s.dump("pos", order='F', view=True)
        self.assertTrue((p[0].position == pos[:, 0]).all())
        self.assertTrue(numpy.may_share_memory(p[0].position, pos[:, 0]))

        # We should get the same dump array
        pos = s.dump("pos", order='F', view=True)
        self.assertTrue((p[0].position == pos[:, 0]).all())
        self.assertTrue(numpy.may_share_memory(p[0].position, pos[:, 0]))

        # We clear the dump array
        pos1 = s.dump("pos", order='F', view=True, clear=True)
        pos1 += 1
        self.assertFalse((p[0].position == pos[:, 0]).all())
        self.assertFalse(numpy.may_share_memory(p[0].position, pos[:, 0]))
Пример #19
0
 def test_callback_copy(self):
     import copy
     from atooms.trajectory.decorators import filter_species
     particle = [Particle(species='A'), Particle(species='B')]
     system = System(particle)
     t = TrajectoryRamFull()
     t[0] = system
     t.add_callback(copy.deepcopy)
     t.add_callback(filter_species, 'A')
     self.assertEqual(t[0].distinct_species(), ['A'])
     t.callbacks.pop()
     t.callbacks.pop()
     self.assertEqual(t[0].distinct_species(), ['A', 'B'])
Пример #20
0
 def test_overlap_random(self):
     # This test may fail from time to time
     from atooms.system.particle import collective_overlap
     N = 1000
     L = 5.0
     sys = [System(), System()]
     sys[0].cell = Cell([L, L, L])
     sys[1].cell = Cell([L, L, L])
     sys[0].particle = []
     sys[1].particle = []
     for _ in range(N):
         pos = [(random.random() - 0.5) * L, (random.random() - 0.5) * L,
                (random.random() - 0.5) * L]
         sys[0].particle.append(Particle(position=pos))
     for _ in range(N):
         pos = [(random.random() - 0.5) * L, (random.random() - 0.5) * L,
                (random.random() - 0.5) * L]
         sys[1].particle.append(Particle(position=pos))
     a = 0.3
     q_rand = ((a**3 * 4. / 3 * 3.1415) * N / sys[0].cell.volume)
     self.assertTrue(
         abs(q_rand - collective_overlap(sys[0].particle, sys[1].particle,
                                         a, sys[0].cell.side)) < 0.5)
Пример #21
0
    def read_sample(self, frame):
        # Read metadata of this frame
        meta = self._read_comment(frame)

        # Get number of particles
        self.trajectory.seek(self._index_header[frame])
        npart = int(self.trajectory.readline())

        # Read frame now
        self.trajectory.seek(self._index_frame[frame])
        particle = []
        for ipart in range(npart):
            p = Particle()
            data = self.trajectory.readline().split()
            i = 0
            for key, fmt, ndims in meta['Properties']:
                ndims = int(ndims)
                if key in self.alias:
                    key = self.alias[key]
                if ndims == 1:
                    if fmt == 'R':
                        setattr(p, key, float(data[i]))
                    elif fmt == 'I':
                        setattr(p, key, int(data[i]))
                    elif fmt == 'S':
                        setattr(p, key, data[i])
                    else:
                        raise ValueError('unknown format key')
                else:
                    if fmt == 'R':
                        setattr(
                            p, key,
                            numpy.array(data[i:i + ndims],
                                        dtype=numpy.float64))
                    elif fmt == 'I':
                        setattr(
                            p, key,
                            numpy.array(data[i:i + ndims], dtype=numpy.int64))
                    elif fmt == 'S':
                        setattr(p, key, numpy.array(data[i:i + ndims]))
                    else:
                        raise ValueError('unknown format key')
                i += ndims
            particle.append(p)

        side = meta["Lattice"]
        # TODO: remove hard coded
        cell = Cell([side[0], side[4], side[8]])
        return System(particle, cell)
Пример #22
0
    def read_sample(self, frame):
        """ returns System instance. """

        L = self.header[0]
        if self.ndim == 3:
            cell = Cell(side=[L, L, L])
        elif self.ndim == 2:
            cell = Cell(side=[L, L])

        N = self.data.shape[0]
        pos = self.data[:, :self.ndim]
        # Lerner group format has positions from [0, 1).
        pos = pos*L - L/2

        if self.velocity_present:
            # Next is the velocity, if it exists.
            vel = self.data[:, self.ndim:2*self.ndim]

        # # In 2D, we add a zero z-coordinate to be consistent with other formats.
        # if self.ndim == 3:
        #     # First ndim columns are always the position.
        # elif self.ndim == 2:
        #     new_pos = np.zeros((N, 3)).astype(float)
        #     new_pos[:, :self.ndim] = pos
        #     pos = new_pos
        #     if self.velocity_present:
        #         vel = np.zeros((N, 3)).astype(float)
        #         vel[:, :self.ndim] = self.data[:, self.ndim:2*self.ndim]

        particles = []
        for i in range(N):
            p = Particle()
            p.position = pos[i, :]
            if self.velocity_present:
                p.velocity = vel[i, :]
            if self.species_present and self.radius_present:
                p.species = str( int(self.data[i, -1]) )
                p.radius  = self.data[i, -2]
            elif self.radius_present:
                p.radius = self.data[i, -1]
            elif self.species_present:
                p.species = str( int(self.data[i, -1]) )

            particles.append(p)

        return System(particle=particles, cell=cell)
Пример #23
0
    def read_sample(self, frame):
        meta = self._read_comment(frame)
        self.trajectory.seek(self._index_frame[frame])

        # Read particles
        particle = []
        for _ in range(meta['npart']):
            data = self.trajectory.readline().strip().split()
            species = data[0]
            r = numpy.array(data[1:4], dtype=float)
            particle.append(Particle(species=species, position=r))

        # Read cell
        try:
            side = meta['cell']
            self._cell = Cell(side)
        except KeyError:
            pass

        return System(particle, self._cell)
Пример #24
0
def unfold(system):
    # s = system
    # particle = system.particle
    # for i, p in enumerate(particle):
    #     p.position += p.periodic_image * s.cell.side
    # system.particle = particle
    # return s
    from atooms.system import System
    npart = system.sample.GetNumberOfParticles()
    pos = system.sample.GetPositions()
    nsp = system.sample.GetNumberOfTypes()
    ima = system.sample.GetImages()
    spe = numpy.ndarray(npart, dtype=int)
    ii = 0
    for i in range(nsp):
        ni = system.sample.GetNumberThisType(i)
        spe[ii: ii + ni] = i
        ii += ni
    particle = [Particle(species=spe_i, position=pos_i) for spe_i, pos_i in
                zip(spe, pos)]
    for p, i in zip(particle, ima):
        p.position += i * system.cell.side

    return System(particle=particle, cell=system.cell)
Пример #25
0
    def read_sample(self, frame):
        system = System()
        s = self.trajectory["trajectory/realtime/sampleindex"].keys()[frame]
        system.eigenvalues = self.trajectory["trajectory/normalmodes/eigenvalues/%s" % s][:]
        system.eigenfreq = numpy.array([copysign(abs(x)**0.5, x) for x in system.eigenvalues])
        mode_idx = self.trajectory["trajectory/normalmodes/eigenvectors/index/%s" % s][:]
        eigv = {}
        for idx in mode_idx:
            # Modes are F-indexed
            omega = system.eigenfreq[idx-1]
            vect = self.trajectory["trajectory/normalmodes/eigenvectors/vector/%s_mode_%05d" % (s, idx)][:]
            eigv[omega] = vect
        system.eigenvectors = eigv

        # Add positions
        parent = os.path.splitext(self.trajectory.filename)[0]
        step = self.steps[frame]
        with TrajectoryHDF5(parent) as th:
            # The step should be there
            parent_frame = th.steps.index(step)
            system.particle = th[parent_frame].particle
            system.cell = th[parent_frame].cell
        return system
Пример #26
0
    def read_init(self):
        # read particles
        group = self.trajectory['/initialstate/particle']
        n = self.trajectory['/initialstate/particle/number_of_particles'][0]
        rad = None
        for entry in group:
            # TODO: refactor this
            if entry == 'element':
                spe = group[entry][:]
            if entry == 'mass':
                mas = group[entry][:]
            if entry == 'position':
                pos = group[entry][:]
            if entry == 'velocity':
                vel = group[entry][:]
            if entry == 'radius':
                rad = group[entry][:]
        if rad is not None:
            particle = [
                Particle(species=spe[i].decode().strip(),
                         mass=mas[i],
                         position=pos[i, :],
                         velocity=vel[i, :],
                         radius=rad[i]) for i in range(n)
            ]
        else:
            particle = [
                Particle(species=spe[i].decode().strip(),
                         mass=mas[i],
                         position=pos[i, :],
                         velocity=vel[i, :]) for i in range(n)
            ]

        # read cell
        group = self.trajectory['/initialstate/cell']
        for entry in group:
            if entry == 'sidebox':
                sidebox = group[entry][:]
        cell = Cell(sidebox)

        # read interaction
        interaction = self.read_interaction()

        # build system
        self._system = System(particle, cell, interaction)

        # read matrix
        if 'matrix' in self.trajectory['/initialstate']:
            group = self.trajectory['/initialstate/matrix']
            for entry in group:
                if entry == 'element':
                    spe = group[entry][:]
                if entry == 'mass':
                    mas = group[entry][:]
                if entry == 'position':
                    pos = group[entry][:]
            matrix = [
                Particle(species=spe[i].decode().strip(),
                         mass=mas[i],
                         position=pos[i, :]) for i in range(len(spe))
            ]
            self._system.matrix = copy.deepcopy(matrix)

        return self._system
Пример #27
0
    def read_sample(self, frame, unfolded=False):
        # TODO: due to unfolded argument this differs from the base class method Can we drop this?
        # We must increase frame by 1 if we iterate over frames with len().
        # This is some convention to be fixed once and for all
        # TODO: read cell on the fly NPT
        keys = list(self.trajectory['/trajectory/realtime/stepindex'].keys())
        csample = '/' + keys[frame]
        # read particles
        group = self.trajectory['/trajectory/particle']
        if unfolded:
            if 'position_unfolded' not in group:
                raise NotImplementedError(
                    'cannot unfold like this, use decorator instead')
            else:
                # fix for unfolded positions that were not written at the first step
                # should be fixed once and for all in md.x
                if frame == 0:
                    pos = self.trajectory['/initialstate/particle/position'][:]
                else:
                    pos = group['position_unfolded' + csample][:]
        else:
            pos = group['position' + csample][:]

        try:
            vel = group['velocity' + csample][:]
        except:
            vel = numpy.zeros([len(pos), ndim])

        # Dynamic properties
        p = []
        for r, v in zip(pos, vel):
            p.append(Particle(position=r, velocity=v))

        # Static properties
        # TODO: optimize, this takes quite some additional time, almost x2
        for pi, r in zip(p, self._system.particle):
            pi.mass = r.mass
            pi.species = r.species
            pi.radius = r.radius

        # Try update radii. This must be done after setting defaults.
        try:
            r = group['radius' + csample][:]
            for i, pi in enumerate(p):
                pi.radius = r[i]
            if 'radius' not in self.fields:
                self.fields.append('radius')
        except KeyError:
            if 'radius' in self.fields:
                self.fields.remove('radius')

        # Try update species. This must be done after setting defaults.
        # TODO: refactor
        try:
            spe = group['species' + csample][:]
            for i, pi in enumerate(p):
                pi.species = spe[i].decode().strip()
            if 'species' not in self.fields:
                self.fields.append('species')
        except KeyError:
            if 'species' in self.fields:
                self.fields.remove('species')

        # Read cell
        group = self.trajectory['/trajectory/cell']
        side = group['sidebox' + csample][:]
        # This fixes an issue with some hdf5 trajectories that stored
        # cell as (1,3) array
        if len(side.shape) == 2:
            side = side[0]
        self._system.cell.side = side

        # Read also interaction.
        has_int = True
        try:
            group = self.trajectory['/trajectory/interaction']
        except:
            has_int = False

        if has_int:
            self._system.interaction.total_energy = group['energy' +
                                                          csample][0]
            self._system.interaction.total_virial = group['virial' +
                                                          csample][0]
            self._system.interaction.total_stress = group['stress' +
                                                          csample][:]

        return System(p, self._system.cell, self._system.interaction)
Пример #28
0
 def __init__(self):
     self.system = System()
Пример #29
0
    def read_sample(self, frame):
        # Setup fields again, in case they have changed
        if self.__cache_fields != self.fields:
            self._setup_fields()
        # Read metadata of this frame
        meta = self._read_comment(frame)
        # Define read callbacks list before reading lines
        callbacks_read = []

        def _skip(p, data, meta):
            return data[1:]

        for key in self.fields:
            # If the key is associated to a explicit callback, go
            # for it. Otherwise we throw the field in an particle
            # attribute named key. If the key is None it means we skip
            # this column.
            if key is None:
                callbacks_read.append(_skip)
            elif key in self.callback_read:
                callbacks_read.append(self.callback_read[key])
            else:
                # Trick. We instantiate dynamically a fallback function
                # to avoid adding `key` to the other callbacks' interface
                namespace = {}
                exec(
                    """
from atooms.core.utils import tipify
def fallback(p, data, meta):
    p.__dict__['%s'] = tipify(data[0])
    return data[1:]
""" % key, namespace)
                callbacks_read.append(namespace['fallback'])

        # Read frame now
        self.trajectory.seek(self._index_frame[frame])
        particle = []
        for i in range(meta['npart']):
            p = Particle()
            # Note: we cannot optimize by shifting an index instead of
            # cropping lists all the time
            data = self.trajectory.readline().split()
            for cbk in callbacks_read:
                data = cbk(p, data, meta)
            particle.append(p)

        # Fix the masses.
        # We assume masses read from the header are sorted by species name.
        # The mass metadata must be adjusted to the given frame.
        if 'mass' in meta:
            if isinstance(meta['mass'], list) or isinstance(
                    meta['mass'], tuple):
                species = distinct_species(particle)
                # We must have as many mass entries as species
                if len(species) != len(meta['mass']):
                    raise ValueError('mass metadata issue %s, %s' %
                                     (species, meta['mass']))
                db = {}
                for key, value in zip(species, meta['mass']):
                    db[key] = value
                for p in particle:
                    p.mass = float(db[p.species])
            else:
                for p in particle:
                    p.mass = float(meta['mass'])

        # Add cell info
        if 'cell' in meta:
            cell = Cell(meta['cell'])
        else:
            cell = None

        return System(particle, cell)
Пример #30
0
class Test(unittest.TestCase):
    def setUp(self):
        N = 100
        L = 10.0
        self.ref = System()
        self.ref.cell = Cell([L, L, L])
        self.ref.particle = []
        self.ref.thermostat = Thermostat(1.0)
        self.ref.barostat = Barostat(1.0)
        self.ref.reservoir = Reservoir(1.0)
        while len(self.ref.particle) <= N:
            pos = [(random.random() - 0.5) * L, (random.random() - 0.5) * L,
                   (random.random() - 0.5) * L]
            self.ref.particle.append(Particle(position=pos))

    def test_density(self):
        system = copy.copy(self.ref)
        density_old = system.density
        system.density = density_old * 1.1
        self.assertAlmostEqual(system.density, density_old * 1.1)

    def test_temperature(self):
        system = copy.copy(self.ref)
        system.set_temperature(1.0)
        self.assertAlmostEqual(system.temperature, 1.0)

    def test_cm(self):
        system = copy.copy(self.ref)
        system.set_temperature(1.0)
        system.fix_momentum()
        self.assertAlmostEqual(system.cm_velocity[0], 0.0)
        self.assertAlmostEqual(system.cm_velocity[1], 0.0)
        self.assertAlmostEqual(system.cm_velocity[2], 0.0)
        pos_cm = system.cm_position
        for p in system.particle:
            p.position -= pos_cm
        self.assertAlmostEqual(system.cm_position[0], 0.0)
        self.assertAlmostEqual(system.cm_position[1], 0.0)
        self.assertAlmostEqual(system.cm_position[2], 0.0)

    def test_pbc_center(self):
        system = copy.copy(self.ref)
        # Move the center of the cell so that positions are within 0 and L
        system.cell.center = system.cell.side / 2
        for p in system.particle:
            p.position += system.cell.side / 2
        # Check that distances are the same
        for i in range(len(system.particle)):
            self.assertAlmostEqual(
                sum(self.ref.particle[0].distance(self.ref.particle[i],
                                                  self.ref.cell)**2),
                sum(system.particle[0].distance(system.particle[i],
                                                system.cell)**2))
        # Move one particle out of the box and fold it back
        pos = copy.copy(system.particle[0].position)
        system.particle[0].position += system.cell.side
        system.particle[0].fold(system.cell)
        self.assertAlmostEqual(pos[0], system.particle[0].position[0])
        self.assertAlmostEqual(pos[1], system.particle[0].position[1])
        self.assertAlmostEqual(pos[2], system.particle[0].position[2])

    def test_fold(self):
        system = copy.copy(self.ref)
        pos = copy.copy(system.particle[0].position)
        system.particle[0].position += system.cell.side
        system.particle[0].fold(system.cell)
        self.assertAlmostEqual(pos[0], system.particle[0].position[0])
        self.assertAlmostEqual(pos[1], system.particle[0].position[1])
        self.assertAlmostEqual(pos[2], system.particle[0].position[2])

    def test_overlaps(self):
        from atooms.system.particle import overlaps
        system = copy.copy(self.ref)
        for p in system.particle:
            p.radius = 1e-10
        pos = copy.copy(system.particle[1].position)
        system.particle[0].position = pos
        ov, ipart = overlaps(system.particle, system.cell)
        self.assertTrue(ov)
        self.assertEqual(ipart, [(0, 1)])

    def test_dump(self):
        self.assertEqual(
            self.ref.dump('spe')[-1],
            self.ref.dump('particle.species')[-1])
        self.assertAlmostEqual(
            self.ref.dump('pos')[-1][-1],
            self.ref.dump('particle.position')[-1][-1])
        self.assertAlmostEqual(
            self.ref.dump('vel')[-1][-1],
            self.ref.dump('particle.velocity')[-1][-1])

    def test_species(self):
        system = copy.copy(self.ref)
        npart = len(system.particle)
        for p in system.particle[0:10]:
            p.species = 'B'
        for p in system.particle[10:30]:
            p.species = 'C'
        from atooms.system.particle import composition, distinct_species
        self.assertEqual(distinct_species(system.particle), ['A', 'B', 'C'])
        self.assertEqual(system.distinct_species(), ['A', 'B', 'C'])
        self.assertEqual(composition(system.particle)['A'], npart - 30)
        self.assertEqual(composition(system.particle)['B'], 10)
        self.assertEqual(composition(system.particle)['C'], 20)

    def test_packing(self):
        import math
        system = copy.copy(self.ref)
        self.assertAlmostEqual(system.packing_fraction * 6 / math.pi,
                               system.density)

    def test_gyration(self):
        from atooms.system.particle import gyration_radius
        system = copy.copy(self.ref)

        # Ignore cell
        rg1 = gyration_radius(system.particle, method='N1')
        rg2 = gyration_radius(system.particle, method='N2')
        self.assertAlmostEqual(rg1, rg2)

        # With PBC all estimates are different but bounds must be ok
        rg1 = gyration_radius(system.particle, system.cell, method='min')
        rg2 = gyration_radius(system.particle, system.cell, method='N1')
        rg3 = gyration_radius(system.particle, system.cell, method='N2')
        self.assertLessEqual(rg1, rg2)
        self.assertLessEqual(rg3, rg2)

        # Equilateral triangle
        system.particle = [Particle(), Particle(), Particle()]
        system.particle[0].position = numpy.array([0.0, 0.0, 0.0])
        system.particle[1].position = numpy.array([1.0, 0.0, 0.0])
        system.particle[2].position = numpy.array([0.5, 0.5 * 3**0.5, 0])
        # Put the triangle across the cell
        system.particle[0].position -= 1.01 * system.cell.side / 2
        system.particle[1].position -= 1.01 * system.cell.side / 2
        system.particle[2].position -= 1.01 * system.cell.side / 2
        system.particle[0].fold(system.cell)
        system.particle[1].fold(system.cell)
        system.particle[2].fold(system.cell)
        rg1 = gyration_radius(system.particle, system.cell, method='min')
        rg2 = gyration_radius(system.particle, system.cell, method='N1')
        rg3 = gyration_radius(system.particle, system.cell, method='N2')
        self.assertAlmostEqual(rg1, 0.57735026919)
        self.assertAlmostEqual(rg2, 0.57735026919)
        self.assertAlmostEqual(rg3, 0.57735026919)

    def test_interaction(self):
        from atooms.interaction import Interaction
        system = copy.copy(self.ref)
        self.assertAlmostEqual(system.potential_energy(), 0.0)
        system.interaction = Interaction([])
        system.interaction.compute('energy', system.particle, system.cell)
        system.interaction.compute('forces', system.particle, system.cell)
        system.interaction.compute('stress', system.particle, system.cell)
        self.assertAlmostEqual(system.potential_energy(), 0.0)
        self.assertAlmostEqual(system.potential_energy(normed=True), 0.0)
        self.assertAlmostEqual(system.total_energy(), system.kinetic_energy())

    def test_overlap(self):
        from atooms.system.particle import self_overlap, collective_overlap
        sys1 = copy.deepcopy(self.ref)
        sys2 = copy.deepcopy(self.ref)
        sys1.particle = sys1.particle[:int(len(sys1.particle) / 2)]
        sys2.particle = sys2.particle[int(len(sys2.particle) / 2):]
        self.assertEqual(0, self_overlap(sys1.particle, sys2.particle, 0.001))
        self.assertEqual(
            0,
            collective_overlap(sys1.particle, sys2.particle, 0.001,
                               sys1.cell.side))
        sys1.particle = sys1.particle
        sys2.particle = sys1.particle
        self.assertEqual(1, self_overlap(sys1.particle, sys2.particle, 0.001))
        self.assertEqual(
            1,
            collective_overlap(sys1.particle, sys2.particle, 0.001,
                               sys1.cell.side))

    def test_overlap_random(self):
        # This test may fail from time to time
        from atooms.system.particle import collective_overlap
        N = 1000
        L = 5.0
        sys = [System(), System()]
        sys[0].cell = Cell([L, L, L])
        sys[1].cell = Cell([L, L, L])
        sys[0].particle = []
        sys[1].particle = []
        for _ in range(N):
            pos = [(random.random() - 0.5) * L, (random.random() - 0.5) * L,
                   (random.random() - 0.5) * L]
            sys[0].particle.append(Particle(position=pos))
        for _ in range(N):
            pos = [(random.random() - 0.5) * L, (random.random() - 0.5) * L,
                   (random.random() - 0.5) * L]
            sys[1].particle.append(Particle(position=pos))
        a = 0.3
        q_rand = ((a**3 * 4. / 3 * 3.1415) * N / sys[0].cell.volume)
        self.assertTrue(
            abs(q_rand - collective_overlap(sys[0].particle, sys[1].particle,
                                            a, sys[0].cell.side)) < 0.5)

    def test_view(self):
        import numpy
        from atooms.system import Particle, System

        p = [Particle(), Particle()]
        s = System(p)
        pos = s.dump("pos", order='F', view=True)

        # Modify the dumped array in place preserves the view
        pos[:, 0] += 1.0
        self.assertTrue((p[0].position == pos[:, 0]).all())
        self.assertTrue(numpy.may_share_memory(p[0].position, pos[:, 0]))
        # Modify the position array in place preserves the view
        p[0].position *= 2
        self.assertTrue((p[0].position == pos[:, 0]).all())
        self.assertTrue(numpy.may_share_memory(p[0].position, pos[:, 0]))
        # Modify the position array in place preserves the view
        p[0].position[:] = p[0].position[:] + 4
        self.assertTrue((p[0].position == pos[:, 0]).all())
        self.assertTrue(numpy.may_share_memory(p[0].position, pos[:, 0]))
        pos[:, 0] = pos[:, 0] + 1.0
        self.assertTrue((p[0].position == pos[:, 0]).all())
        self.assertTrue(numpy.may_share_memory(p[0].position, pos[:, 0]))
        # Reassining the position will of course destroy the view
        p[0].position = p[0].position * 2
        self.assertFalse((p[0].position == pos[:, 0]).all())
        self.assertFalse(numpy.may_share_memory(p[0].position, pos[:, 0]))

    def test_view_clear(self):
        import numpy
        from atooms.system import Particle, System

        p = [Particle(), Particle()]
        s = System(p)

        # We check that particle positions are views on dump array
        pos = s.dump("pos", order='F', view=True)
        self.assertTrue((p[0].position == pos[:, 0]).all())
        self.assertTrue(numpy.may_share_memory(p[0].position, pos[:, 0]))

        # We should get the same dump array
        pos = s.dump("pos", order='F', view=True)
        self.assertTrue((p[0].position == pos[:, 0]).all())
        self.assertTrue(numpy.may_share_memory(p[0].position, pos[:, 0]))

        # We clear the dump array
        pos1 = s.dump("pos", order='F', view=True, clear=True)
        pos1 += 1
        self.assertFalse((p[0].position == pos[:, 0]).all())
        self.assertFalse(numpy.may_share_memory(p[0].position, pos[:, 0]))

    def test_dump_cbk(self):
        """
        Make sure that applying callbacks or changing the particle array
        size creates a new dump.
        """
        import numpy
        from atooms.system import Particle, System

        for view in [False, True]:
            p = [Particle(), Particle()]
            s = System(p)
            pos1 = s.dump("pos", view=view)

            def cbk(system):
                s = copy.copy(system)
                s.particle = [system.particle[0]]
                return s

            s = cbk(s)
            pos2 = s.dump('pos', view=view)
            self.assertEqual(pos1.shape, (2, 3))
            self.assertEqual(pos2.shape, (1, 3))
            # Grandcanonical
            s.particle.append(Particle())
            self.assertEqual(s.dump('pos', view=view).shape, (2, 3))
            # Reassign particle
            # Expected failure with view = True
            if not view:
                s.particle[0] = Particle(position=[1.0, 1.0, 1.0])
                self.assertEqual(s.dump('pos', view=view)[0][0], 1.0)

    def test_dump_species(self):
        """
        Make sure that changing species in the dump is reflected in the
        particle species and viceversa.
        """
        import numpy
        from atooms.system import Particle, System

        view = True
        p = [Particle(), Particle()]
        s = System(p)
        spe = s.dump("particle.species", view=True)
        spe[0] = 'B'
        self.assertEqual(spe[0], s.particle[0].species)
        # With this syntax, the numpy scalar preserves the view!
        # We should upgrade species to property and hide this inside
        s.particle[0].species[()] = 'C'
        self.assertEqual(spe[0], s.particle[0].species)

    def test_decimate(self):
        from atooms.system import Particle, System
        from atooms.system.particle import composition, decimate
        p = [Particle(species='A')] * 20 + [Particle(species='B')] * 10
        pnew = decimate(p, 12)
        x = composition(pnew)
        self.assertEqual(x['A'], 8)
        self.assertEqual(x['B'], 4)

    def test_ovito(self):
        try:
            import ovito
        except ImportError:
            self.skipTest('missing ovito')
        N = 3
        L = 5.0
        system = System()
        system.cell = Cell([L, L, L])
        system.particle = []
        for _ in range(N):
            pos = (numpy.random.random(len(system.cell.side)) -
                   0.5) * system.cell.side
            p = Particle(position=pos)
            system.particle.append(p)
        image = system.show('ovito')