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
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