Beispiel #1
0
    def distance2(self, x1, x2, option='reduced', radius=20, limits=None):

        # Compute the vector from x1 to x2
        dv = np.array(x2) - np.array(x1)

        # If we are not in reduced coordinates,
        # Convert into them
        if option != 'reduced':
            dred = self.cartesian2reduced(dv)
        else:
            dred = dv

        dwrap = wrap2_pmhalf(dred)

        if limits is None:
            limits = np.zeros(3, dtype=int)
            corners = self.get_wigner_seitz_container()

            limits[0] = min(int(ceil(max(1e-14 + abs(np.array([corners[x][0] for x in corners]))))), 5)
            limits[1] = min(int(ceil(max(1e-14 + abs(np.array([corners[x][1] for x in corners]))))), 5)
            limits[2] = min(int(ceil(max(1e-14 + abs(np.array([corners[x][2] for x in corners]))))), 5)

        ret = {}
        for i0 in np.arange(-limits[0], limits[0] + 1):
            for i1 in np.arange(-limits[1], limits[1] + 1):
                for i2 in np.arange(-limits[2], limits[2] + 1):
                    dtot = dwrap + np.array([i0, i1, i2])
                    norm2 = np.dot(np.dot(dtot, self.metric), dtot)
                    if norm2 < radius * radius:
                        ret[(i0, i1, i2)] = {'distance': sqrt(norm2), 'image': dtot}

        return ret
Beispiel #2
0
    def distance2(self, x1, x2, option='reduced', radius=20, limits=None):

        # Compute the vector from x1 to x2
        dv = np.array(x2) - np.array(x1)

        # If we are not in reduced coordinates,
        # Convert into them
        if option != 'reduced':
            dred = self.cartesian2reduced(dv)
        else:
            dred = dv

        dwrap = wrap2_pmhalf(dred)

        if limits is None:
            limits = np.zeros(3, dtype=int)
            corners = self.get_wigner_seitz_container()

            limits[0] = min(int(ceil(max(1e-14 + abs(np.array([corners[x][0] for x in corners]))))), 5)
            limits[1] = min(int(ceil(max(1e-14 + abs(np.array([corners[x][1] for x in corners]))))), 5)
            limits[2] = min(int(ceil(max(1e-14 + abs(np.array([corners[x][2] for x in corners]))))), 5)

        ret = {}
        for i0 in np.arange(-limits[0], limits[0] + 1):
            for i1 in np.arange(-limits[1], limits[1] + 1):
                for i2 in np.arange(-limits[2], limits[2] + 1):
                    dtot = dwrap + np.array([i0, i1, i2])
                    norm2 = np.dot(np.dot(dtot, self.metric), dtot)
                    if norm2 < radius * radius:
                        ret[(i0, i1, i2)] = {'distance': sqrt(norm2), 'image': dtot}

        return ret
Beispiel #3
0
    def distance2(self, x1, x2, option='reduced'):

        # Compute the vector from x1 to x2
        dv = _np.array(x2)-_np.array(x1)

        # If we are not in reduced coordinates,
        # Convert into them
        if option != 'reduced':
            dred = self.cartesian2reduced(dv)
        else:
            dred = dv

        dwrap = wrap2_pmhalf(dred)

        limits = _np.zeros(3)
        corners = self.get_wigner_seitz_container()
        #for key, value in corners.iteritems():
        #    print key, value
        limits[0] = int(math.ceil(max(1e-14+abs(_np.array([corners[x][0] for x in corners])))))
        limits[1] = int(math.ceil(max(1e-14+abs(_np.array([corners[x][1] for x in corners])))))
        limits[2] = int(math.ceil(max(1e-14+abs(_np.array([corners[x][2] for x in corners])))))
        #print limits
        ret = {}
        for i0 in _np.arange(-limits[0], limits[0]+1):
            for i1 in _np.arange(-limits[1], limits[1]+1):
                for i2 in _np.arange(-limits[2], limits[2]+1):
                    dtot = dwrap+_np.array([i0, i1, i2])
                    norm2 = _np.dot(_np.dot(dtot, self.metric), dtot)
                    ret[(i0, i1, i2)] = {'distance': math.sqrt(norm2), 'image': dtot}
        return ret
Beispiel #4
0
    def distances_in_sphere(self, x1, x2, radius, option='reduced', exclude_out_sphere=True, sort_by_distance=True):
        """
        Returns all the distances between two positions x1 and x2
        taking into account the periodicity of the cell

        :param sort_by_distance:
        :param exclude_out_sphere:
        :param x1:
        :param x2:
        :param radius:
        :param option:
        :return:
        """
        # Compute the vector from x1 to x2
        dv = np.array(x2) - np.array(x1)

        # If the positions are not in reduced coordinates,convert into them
        if option != 'reduced':
            dred = self.cartesian2reduced(dv)
        else:
            dred = dv

        dwrap = wrap2_pmhalf(dred)
        # log.debug('The wrap vector is: %7.3f %7.3f %7.3f' % tuple(dwrap))

        # We need to compute the distances between equivalent faces
        # For that we to compute the perpendicular distance between
        # two faces, the reciprocal lattice produces the inverse of
        # those distances
        recp_len = np.array(self.reciprocal().lengths)
        # The reciprocal (2*pi) is not necessary
        limits = np.ceil(radius * recp_len).astype(int)
        # log.debug('The limits are: %d %d %d' % tuple(limits))

        ret = {}
        # The total size is the product of the number in the 3 directions
        # that is double the limits plus 1 to include the zero
        total_size = np.prod(2 * limits + 1)
        # log.debug('The total size is: %d' % total_size)

        ret['distance'] = np.zeros(total_size)
        ret['image'] = np.zeros((total_size, 3), dtype=int)
        ret['dwrap'] = dwrap
        ret['limits'] = limits

        index = 0
        for i0 in np.arange(-limits[0], limits[0] + 1):
            for i1 in np.arange(-limits[1], limits[1] + 1):
                for i2 in np.arange(-limits[2], limits[2] + 1):
                    dtot = dwrap + np.array([i0, i1, i2])
                    norm2 = np.dot(np.dot(dtot, self.metric), dtot)
                    ret['distance'][index] = sqrt(norm2)
                    ret['image'][index] = np.array([i0, i1, i2])
                    index += 1

        # Exclude distances out of sphere
        if exclude_out_sphere:
            inside_sphere = ret['distance'] <= radius
            if sum(inside_sphere) > 0:
                ret['distance'] = ret['distance'][inside_sphere]
                ret['image'] = ret['image'][inside_sphere]

        if sort_by_distance:
            sorted_indices = np.argsort(ret['distance'])
            ret['distance'] = ret['distance'][sorted_indices]
            ret['image'] = ret['image'][sorted_indices]

        return ret
Beispiel #5
0
    def distances_in_sphere(self, x1, x2, radius, option='reduced', exclude_out_sphere=True, sort_by_distance=True):
        """
        Returns all the distances between two positions x1 and x2
        taking into account the periodicity of the cell

        :param sort_by_distance:
        :param exclude_out_sphere:
        :param x1:
        :param x2:
        :param radius:
        :param option:
        :return:
        """
        # Compute the vector from x1 to x2
        dv = np.array(x2) - np.array(x1)

        # If the positions are not in reduced coordinates,convert into them
        if option != 'reduced':
            dred = self.cartesian2reduced(dv)
        else:
            dred = dv

        dwrap = wrap2_pmhalf(dred)
        # log.debug('The wrap vector is: %7.3f %7.3f %7.3f' % tuple(dwrap))

        # We need to compute the distances between equivalent faces
        # For that we to compute the perpendicular distance between
        # two faces, the reciprocal lattice produces the inverse of
        # those distances
        recp_len = np.array(self.reciprocal().lengths)
        # The reciprocal (2*pi) is not necessary
        limits = np.ceil(radius * recp_len).astype(int)
        # log.debug('The limits are: %d %d %d' % tuple(limits))

        ret = {}
        # The total size is the product of the number in the 3 directions
        # that is double the limits plus 1 to include the zero
        total_size = np.prod(2 * limits + 1)
        # log.debug('The total size is: %d' % total_size)

        ret['distance'] = np.zeros(total_size)
        ret['image'] = np.zeros((total_size, 3), dtype=int)
        ret['dwrap'] = dwrap
        ret['limits'] = limits

        index = 0
        for i0 in np.arange(-limits[0], limits[0] + 1):
            for i1 in np.arange(-limits[1], limits[1] + 1):
                for i2 in np.arange(-limits[2], limits[2] + 1):
                    dtot = dwrap + np.array([i0, i1, i2])
                    norm2 = np.dot(np.dot(dtot, self.metric), dtot)
                    ret['distance'][index] = sqrt(norm2)
                    ret['image'][index] = np.array([i0, i1, i2])
                    index += 1

        # Exclude distances out of sphere
        if exclude_out_sphere:
            inside_sphere = ret['distance'] <= radius
            if sum(inside_sphere) > 0:
                ret['distance'] = ret['distance'][inside_sphere]
                ret['image'] = ret['image'][inside_sphere]

        if sort_by_distance:
            sorted_indices = np.argsort(ret['distance'])
            ret['distance'] = ret['distance'][sorted_indices]
            ret['image'] = ret['image'][sorted_indices]

        return ret