Esempio n. 1
0
    def makeKvecs(self, kmag2, S, orthogonal=True):
        """Make k-vectors needed for space fourier transform.

        `orthogonal` is a a keyword indicating that we will only use
        (k,0,0), (0,k,0), (0,0,k) as our vectors, instead of that in
        addition to all diagonal vectors consistent with a certain
        angle.  This is because in a cubic lattice, diagonals pointing
        in different directions (0,0,3) vs (1,2,2) do not have the
        same symmetry properties.  Default to only using orthogonal
        vectors (orthogonal=True)
        """
        if orthogonal:
            kmag = int(math.sqrt(kmag2))
            # If we didn't get an exact integer used with orthogonal,
            # is is incorrect.  We could just round it, but likely the
            # user did not want that, since most likely they are using
            # all values of integer $k^2$ instead of all values of
            # integer $k$.
            if kmag != math.sqrt(kmag2):
                raise NoKvecsException
            if len(S.physicalShape) == 1:
                kvecs = numpy.asarray([(kmag, ),
                                       ],
                                      dtype=saiga12.c_double)
            elif len(S.physicalShape) == 2:
                kvecs = numpy.asarray([(kmag, 0.  ),
                                       (0.  , kmag),
                                       ],
                                      dtype=saiga12.c_double)
            elif len(S.physicalShape) == 3:
                kvecs = numpy.asarray([(kmag, 0.  , 0.  ),
                                       (0.  , kmag, 0.  ),
                                       (0.  , 0.  , kmag),
                                       ],
                                      dtype=saiga12.c_double)
        else:
            import shelve
            cachepar = str((kmag2, len(S.physicalShape)))
            kmax = int(math.ceil(math.sqrt(kmag2)))

            useCache = False
            if _kvecCache.has_key(cachepar):  # memory cache always used
                kvecs = _kvecCache[cachepar]
            else:
                cache = shelve.open("kvecCache")
                if cache.get('version', 0) < 1:
                    for k in cache.keys(): del cache[k]
                    cache['version'] = 1
                if cache.has_key(cachepar) and useCache:

                    kvecs = cache[cachepar]
                    _kvecCache[cachepar] = kvecs
                else:
                    # kvecs is a list of all k-vectors consistent with our
                    # magnitude.
                    full = [ x for x in range(-kmax+1, kmax+1) ]
                    half = [ x for x in range(0, kmax+1) ]

                    if len(S.physicalShape) == 1:
                        kvecs = cartesianproduct(half, )
                    elif len(S.physicalShape) == 2:
                        kvecs = cartesianproduct(full, half)
                    elif len(S.physicalShape) == 3:
                        kvecs = cartesianproduct(full, full, half)
                    kvecs = numpy.asarray([ _ for _ in kvecs
                                        # the following lines limits to only
                                        # orthogonal vectors, which is handled
                                        # at the very first of this method
                                        #if numpy.max(numpy.abs(_))**2 == kmag2
                                            ],
                                          dtype=saiga12.c_double)
                    magnitudes2 = numpy.sum(kvecs * kvecs, axis=1)
                    kvecs = kvecs[magnitudes2 == kmag2]
                    if len(kvecs) == 0:
                        raise NoKvecsException

                    if useCache:
                        cache[cachepar] = kvecs
                    _kvecCache[cachepar] = kvecs   # memory cache always
                del cache
        self.kvecs = kvecs
Esempio n. 2
0
def makeKvecs(n, orthogonal, dim):
    n2 = n**2
    if orthogonal:
        if dim == 2:
            kvecs = numpy.asarray([(n , 0.  ),
                                   (0., n),
                                   ],
                                  dtype=saiga12.c_double)
            return kvecs
        elif dim == 3:
            kvecs = numpy.asarray([(n , 0., 0.),
                                   (0., n , 0.),
                                   (0., 0., n ),
                                   ],
                                  dtype=saiga12.c_double)
            return kvecs
        else:
            raise Exception("dimensions must be 2 or 3.")

    else:
        import shelve
        cachepar = str((n2, dim))
        nmax = int(math.ceil(math.sqrt(n2)))

        useCache = False
        if _kvecCache.has_key(cachepar):  # memory cache always used
            kvecs = _kvecCache[cachepar]
        else:
            cache = shelve.open("kvecCache")
            if cache.get('version', 0) < 1:
                for k in cache.keys(): del cache[k]
                cache['version'] = 1
            if cache.has_key(cachepar) and useCache:
                kvecs = cache[cachepar]
                _kvecCache[cachepar] = kvecs
            else:
                # kvecs is a list of all k-vectors consistent with our
                # magnitude.
                full = [ x for x in range(-nmax+1, nmax+1) ]
                half = [ x for x in range(0, nmax+1) ]

                if dim == 1:
                    kvecs = cartesianproduct(half, )
                elif dim == 2:
                    kvecs = cartesianproduct(full, half)
                elif dim == 3:
                    kvecs = cartesianproduct(full, full, half)
                kvecs = numpy.asarray([ _ for _ in kvecs
                                    # the following lines limits to only
                                    # orthogonal vectors, which is handled
                                    # at the very first of this method
                                    #if numpy.max(numpy.abs(_))**2 == kmag2
                                        ],
                                      dtype=saiga12.c_double)
                magnitudes2 = numpy.sum(kvecs * kvecs, axis=1)
                kvecs = kvecs[magnitudes2 == n2]
                if len(kvecs) == 0:
                    raise NoKvecsException

                if useCache:
                    cache[cachepar] = kvecs
                _kvecCache[cachepar] = kvecs   # memory cache always
            del cache
        return kvecs